diff --git a/AUTHORS b/AUTHORS index c873ef0..a5c494ca8 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -75,7 +75,7 @@ Brian Konzman, SJ <b.g.konzman@gmail.com> Brian Merrell, Novell Inc. <bgmerrell@gmail.com> Bruno Calvignac <bruno@flock.com> -Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> +Bruno de Oliveira Abinader <brunoabinader@gmail.com> Bryan Donlan <bdonlan@gmail.com> Byoungkwon Ko <gogag2@gmail.com> Byungwoo Lee <bw80.lee@samsung.com> @@ -222,6 +222,7 @@ Jincheol Jo <jincheol.jo@navercorp.com> Jingwei Liu <kingweiliu@gmail.com> Jingyi Wei <wjywbs@gmail.com> +Jinlong Zhai <jinlong.zhai@samsung.com> Jinho Bang <jinho.bang@samsung.com> Jinwoo Song <jinwoo7.song@samsung.com> Jitendra Kumar Sahoo <jitendra.ks@samsung.com>
diff --git a/DEPS b/DEPS index 48f4de84..16da657 100644 --- a/DEPS +++ b/DEPS
@@ -34,7 +34,7 @@ 'llvm_url': 'http://src.chromium.org/llvm-project', 'llvm_git': 'https://llvm.googlesource.com', 'webkit_trunk': 'http://src.chromium.org/blink/trunk', - 'webkit_revision': 'fc49b4d0de056fca013d8190c26d19bfcebbac20', # from svn revision 189364 + 'webkit_revision': '5bb4863e81c8776f7a171020fdca066906b9a2c9', # from svn revision 189770 'chromium_git': 'https://chromium.googlesource.com', 'chromiumos_git': 'https://chromium.googlesource.com/chromiumos', 'pdfium_git': 'https://pdfium.googlesource.com', @@ -42,19 +42,19 @@ 'boringssl_git': 'https://boringssl.googlesource.com', 'libvpx_revision': '5cdd30205301c293be6160f778bce981300b5a28', 'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac', - 'skia_revision': 'f16201250315bd807e06547f1c412fcdc5c8805a', + 'skia_revision': 'e6b1a60758aa16c0456ff8e1cf717c369e4e84b0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and V8 without interference from each other. 'v8_branch': 'trunk', - 'v8_revision': 'e8694f69297c3bee240490aecd29fab6c40ec3f0', + 'v8_revision': '8b488fa5699df266fd0a26a1f643e608cc14347b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling WebRTC # and V8 without interference from each other. # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. - 'swarming_revision': 'c698ea2a7781c493a8e09d0e89415a4aab8e1f62', + 'swarming_revision': 'bdad1183d6047cc6a1459a5be167ba0a7325146e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -62,15 +62,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': '451dcd05a5b34936f5be67b2472cd63aaa508401', + 'buildtools_revision': 'da0df3fdac6036e862addb1155a2d6c11b6c18d5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '615082de70c7fc18d46d0d1a03b62d0d76b1daa9', + 'pdfium_revision': '7061d1af45752617fafa85e2242dc5b2844650b5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. - 'openmax_dl_revision': 'c01d587de2dfe12458f44074d07f51857c16508e', + 'openmax_dl_revision': '81318c19369769ddaff9602936af5c699d8299b9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -94,7 +94,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'e8fbd4b6737a83a082f3de3b713a6f48cadd3e37', + 'nacl_revision': '2363d1a72c7d71d91f5bb37cfec87dee68486836', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -212,7 +212,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '4cdb373bda5977743d2bf2c89ab82e2edf571b90', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '18f533d48bdade5faf798421edad3753f8466d47', # from svn revision 8221 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'e361ce8eeec660e034d90a33f43164c7240a21e8', # from svn revision 8277 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/usrsctplib.git' + '@' + '190c8cbfcf8fd810aa09e0fab4ca62a8ce724e14', @@ -236,7 +236,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'cfe4b49b4b7e97f8cfb089d0a60767924600fce7', # from svn revision 8220 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'e898b135f11c7c119388191c63539250a72b3a28', # from svn revision 8286 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -409,7 +409,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': - Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '7678688b4405325d32fdfb45064128b9accb9a71', + Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '286cec023e90f54f391fe32bae512f9ec7b4e807', # Note that this is different from Android's freetype repo. 'src/third_party/freetype2/src': @@ -715,7 +715,7 @@ 'action': ['python', 'src/build/get_syzygy_binaries.py', '--output-dir=src/third_party/syzygy/binaries', - '--revision=f0332d538f3eb84c2a55a3d0506a4a0b58d1c09e', + '--revision=79621b5523205997ae9f689efb7f299973c87a8c', '--overwrite', ], },
diff --git a/WATCHLISTS b/WATCHLISTS index 57fc40bc..18508c0 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -287,11 +287,6 @@ 'net/base/host_cache|' \ 'net/dns/' }, - 'domui_options': { - 'filepath': 'chrome/browser/resources/options/|'\ - 'chrome/browser/resources/options.html|'\ - 'chrome/browser/ui/webui/options/', - }, 'download': { 'filepath': 'chrome/browser/download/|'\ 'content/browser/download/', @@ -433,6 +428,10 @@ 'linux_seccomp_bpf': { 'filepath': 'content/common/sandbox.*linux.cc', }, + 'md_settings': { + 'filepath': 'ui/webui/resources/cr_element|'\ + 'chrome/browser/resources/md_settings/', + }, 'media': { 'filepath': 'media/|third_party/(ffmpeg|openmax)/|webmediaplayer|'\ 'audio_message_filter|video_layer|media_internals', @@ -554,6 +553,10 @@ 'filepath': 'chrome/browser/plugin|chrome/plugin/|'\ 'chrome/common/plugin|webkit/glue/webplugin|webkit/glue/plugins/', }, + 'polymer': { + 'filepath': 'third_party/polymer/|'\ + 'ui/webui/resources/polymer_resources.grdp', + }, 'predictors': { 'filepath': 'predictors', }, @@ -579,6 +582,15 @@ 'safe_browsing': { 'filepath': 'chrome/(browser|common|renderer)/safe_browsing/', }, + 'sandbox': { + 'filepath': 'sandbox/'\ + '|content/browser/bootstrap_sandbox_mac'\ + '|content/browser/renderer_host/render_sandbox_host_linux'\ + '|content/browser/renderer_host/sandbox_ipc_linux'\ + '|content/browser/zygote_host/'\ + '|content/common/sandbox_'\ + '|content/zygote/'\ + }, 'scheduler': { 'filepath': 'cc/scheduler|'\ 'content/renderer/scheduler' @@ -924,6 +936,12 @@ 'linux_sandboxing': ['jln+watch@chromium.org'], 'linux_seccomp_bpf': ['jln+watch@chromium.org'], 'supervised_users': ['pam+watch@chromium.org'], + 'md_settings': ['jhawkins+watch-md-settings@chromium.org', + 'jlklein+watch-md-settings@chromium.org', + 'khorimoto+watch-md-settings@chromium.org', + 'michaelpg+watch-md-settings@chromium.org', + 'orenb+watch-md-settings@chromium.org', + 'stevenjb+watch-md-settings@chromium.org'], 'media': ['feature-media-reviews@chromium.org'], 'media_galleries': ['gbillock@chromium.org', 'thestig@chromium.org', 'tommycli@chromium.org', 'vandebo@chromium.org'], @@ -950,7 +968,8 @@ 'ntp': ['estade+watch@chromium.org', 'dbeam+watch-ntp@chromium.org', 'pedrosimonetti+watch@chromium.org'], 'omnibox': ['suzhe@chromium.org'], - 'options': ['dbeam+watch-options@chromium.org'], + 'options': ['dbeam+watch-options@chromium.org', + 'michaelpg+watch-options@chromium.org'], 'overview_mode': ['tdanderson+overview@chromium.org'], 'ozone': ['kalyan.kondapally@intel.com', 'ozone-reviews@chromium.org'], 'panels': ['dimich@chromium.org', 'jennb@chromium.org', @@ -963,6 +982,7 @@ 'binji+watch@chromium.org', 'teravest+watch@chromium.org', 'tzik@chromium.org'], 'plugin': ['jam@chromium.org'], + 'polymer': ['michaelpg+watch-polymer@chromium.org'], 'predictors': ['shishir+watch@chromium.org'], 'prepopulated_engines': ['vasilii+watch@chromium.org'], 'prerender': ['cbentzel+watch@chromium.org', 'tburkard+watch@chromium.org', @@ -976,6 +996,7 @@ 'erikwright+watch@chromium.org', 'robertshield+watch@chromium.org'], 'safe_browsing': ['grt+watch@chromium.org'], + 'sandbox': ['rickyz+watch@chromium.org'], 'scheduler': ['scheduler-bugs@chromium.org'], 'sessions': ['marja+watch@chromium.org'], 'service_worker': ['tzik@chromium.org',
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index aad1cc7..10f98b8 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp
@@ -30,14 +30,32 @@ }, 'includes': [ '../build/repack_action.gypi' ], }, - { - 'action_name': 'add_en_US_pak_locale', - 'variables': { - 'pak_inputs': ['<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.pak'], - 'pak_output': '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', - }, - 'includes': [ '../build/repack_action.gypi' ], - } + ], + 'conditions': [ + ['android_webview_build==0', { + 'actions': [ + { + 'action_name': 'android_webview_locales_rename_paks', + 'variables': { + 'rename_locales': 'tools/webview_locales_rename_paks.py', + }, + 'inputs': [ + '<(rename_locales)', + '<!@pymod_do_main(webview_locales_rename_paks -i -p <(PRODUCT_DIR) -s <(SHARED_INTERMEDIATE_DIR) <(locales))' + ], + 'outputs': [ + '<!@pymod_do_main(webview_locales_rename_paks -o -p <(PRODUCT_DIR) -s <(SHARED_INTERMEDIATE_DIR) <(locales))' + ], + 'action': [ + 'python', + '<(rename_locales)', + '-p', '<(PRODUCT_DIR)', + '-s', '<(SHARED_INTERMEDIATE_DIR)', + '<@(locales)', + ], + } + ], + }], ], }, {
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi index 7c9043d0..817654f 100644 --- a/android_webview/android_webview_tests.gypi +++ b/android_webview/android_webview_tests.gypi
@@ -50,7 +50,7 @@ 'destination': '<(PRODUCT_DIR)/android_webview_apk/assets', 'files': [ '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak', - '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', + '<(PRODUCT_DIR)/android_webview_assets/locales/en-US.pak', '<(java_in_dir)/assets/asset_file.html', '<(java_in_dir)/assets/asset_icon.png', '<(java_in_dir)/assets/cookie_test.html',
diff --git a/android_webview/apk/system_webview_apk_common.gypi b/android_webview/apk/system_webview_apk_common.gypi index dae95ac..a8f5b6c4 100644 --- a/android_webview/apk/system_webview_apk_common.gypi +++ b/android_webview/apk/system_webview_apk_common.gypi
@@ -23,8 +23,8 @@ 'proguard_flags_paths': ['<(DEPTH)/android_webview/apk/java/proguard.flags'], # TODO: crbug.com/405035 Find a better solution for WebView .pak files. 'additional_input_paths': [ + '<@(webview_locales_output_paks)', '<(asset_location)/webviewchromium.pak', - '<(asset_location)/en-US.pak', '<(asset_location)/webview_licenses.notice', ], 'conditions': [ @@ -45,8 +45,8 @@ { 'destination': '<(asset_location)', 'files': [ + '<@(webview_locales_input_paks)', '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak', - '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', ], 'conditions': [ ['icu_use_data_file_flag==1', { @@ -83,5 +83,8 @@ 'message': 'Generating WebView license notice', }, ], - 'includes': [ '../../build/java_apk.gypi' ], + 'includes': [ + 'system_webview_locales_paks.gypi', + '../../build/java_apk.gypi', + ], }
diff --git a/android_webview/apk/system_webview_locales_paks.gypi b/android_webview/apk/system_webview_locales_paks.gypi new file mode 100644 index 0000000..0872cd06 --- /dev/null +++ b/android_webview/apk/system_webview_locales_paks.gypi
@@ -0,0 +1,125 @@ +# Copyright (c) 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# This file defines the set of locales that should be packed inside the +# System WebView apk. +# TODO: consider unifying this list with the one in chrome_android_paks.gypi +# once Chrome includes all the locales that the WebView needs. +{ + 'variables': { + 'webview_locales_input_paks_folder': '<(PRODUCT_DIR)/android_webview_assets/locales/', + 'webview_locales_output_paks_folder': '<(asset_location)', + 'webview_locales_input_paks': [ + '<(webview_locales_input_paks_folder)/am.pak', + '<(webview_locales_input_paks_folder)/ar.pak', + '<(webview_locales_input_paks_folder)/bg.pak', + '<(webview_locales_input_paks_folder)/bn.pak', + '<(webview_locales_input_paks_folder)/ca.pak', + '<(webview_locales_input_paks_folder)/cs.pak', + '<(webview_locales_input_paks_folder)/da.pak', + '<(webview_locales_input_paks_folder)/de.pak', + '<(webview_locales_input_paks_folder)/el.pak', + '<(webview_locales_input_paks_folder)/en-GB.pak', + '<(webview_locales_input_paks_folder)/en-US.pak', + '<(webview_locales_input_paks_folder)/es.pak', + '<(webview_locales_input_paks_folder)/es-419.pak', + '<(webview_locales_input_paks_folder)/et.pak', + '<(webview_locales_input_paks_folder)/fa.pak', + '<(webview_locales_input_paks_folder)/fi.pak', + '<(webview_locales_input_paks_folder)/fil.pak', + '<(webview_locales_input_paks_folder)/fr.pak', + '<(webview_locales_input_paks_folder)/gu.pak', + '<(webview_locales_input_paks_folder)/he.pak', + '<(webview_locales_input_paks_folder)/hi.pak', + '<(webview_locales_input_paks_folder)/hr.pak', + '<(webview_locales_input_paks_folder)/hu.pak', + '<(webview_locales_input_paks_folder)/id.pak', + '<(webview_locales_input_paks_folder)/it.pak', + '<(webview_locales_input_paks_folder)/ja.pak', + '<(webview_locales_input_paks_folder)/kn.pak', + '<(webview_locales_input_paks_folder)/ko.pak', + '<(webview_locales_input_paks_folder)/lt.pak', + '<(webview_locales_input_paks_folder)/lv.pak', + '<(webview_locales_input_paks_folder)/ml.pak', + '<(webview_locales_input_paks_folder)/mr.pak', + '<(webview_locales_input_paks_folder)/ms.pak', + '<(webview_locales_input_paks_folder)/nb.pak', + '<(webview_locales_input_paks_folder)/nl.pak', + '<(webview_locales_input_paks_folder)/pl.pak', + '<(webview_locales_input_paks_folder)/pt-BR.pak', + '<(webview_locales_input_paks_folder)/pt-PT.pak', + '<(webview_locales_input_paks_folder)/ro.pak', + '<(webview_locales_input_paks_folder)/ru.pak', + '<(webview_locales_input_paks_folder)/sk.pak', + '<(webview_locales_input_paks_folder)/sl.pak', + '<(webview_locales_input_paks_folder)/sr.pak', + '<(webview_locales_input_paks_folder)/sv.pak', + '<(webview_locales_input_paks_folder)/sw.pak', + '<(webview_locales_input_paks_folder)/ta.pak', + '<(webview_locales_input_paks_folder)/te.pak', + '<(webview_locales_input_paks_folder)/th.pak', + '<(webview_locales_input_paks_folder)/tr.pak', + '<(webview_locales_input_paks_folder)/uk.pak', + '<(webview_locales_input_paks_folder)/vi.pak', + '<(webview_locales_input_paks_folder)/zh-CN.pak', + '<(webview_locales_input_paks_folder)/zh-TW.pak', + ], + 'webview_locales_output_paks': [ + '<(webview_locales_output_paks_folder)/am.pak', + '<(webview_locales_output_paks_folder)/ar.pak', + '<(webview_locales_output_paks_folder)/bg.pak', + '<(webview_locales_output_paks_folder)/bn.pak', + '<(webview_locales_output_paks_folder)/ca.pak', + '<(webview_locales_output_paks_folder)/cs.pak', + '<(webview_locales_output_paks_folder)/da.pak', + '<(webview_locales_output_paks_folder)/de.pak', + '<(webview_locales_output_paks_folder)/el.pak', + '<(webview_locales_output_paks_folder)/en-GB.pak', + '<(webview_locales_output_paks_folder)/en-US.pak', + '<(webview_locales_output_paks_folder)/es.pak', + '<(webview_locales_output_paks_folder)/es-419.pak', + '<(webview_locales_output_paks_folder)/et.pak', + '<(webview_locales_output_paks_folder)/fa.pak', + '<(webview_locales_output_paks_folder)/fi.pak', + '<(webview_locales_output_paks_folder)/fil.pak', + '<(webview_locales_output_paks_folder)/fr.pak', + '<(webview_locales_output_paks_folder)/gu.pak', + '<(webview_locales_output_paks_folder)/he.pak', + '<(webview_locales_output_paks_folder)/hi.pak', + '<(webview_locales_output_paks_folder)/hr.pak', + '<(webview_locales_output_paks_folder)/hu.pak', + '<(webview_locales_output_paks_folder)/id.pak', + '<(webview_locales_output_paks_folder)/it.pak', + '<(webview_locales_output_paks_folder)/ja.pak', + '<(webview_locales_output_paks_folder)/kn.pak', + '<(webview_locales_output_paks_folder)/ko.pak', + '<(webview_locales_output_paks_folder)/lt.pak', + '<(webview_locales_output_paks_folder)/lv.pak', + '<(webview_locales_output_paks_folder)/ml.pak', + '<(webview_locales_output_paks_folder)/mr.pak', + '<(webview_locales_output_paks_folder)/ms.pak', + '<(webview_locales_output_paks_folder)/nb.pak', + '<(webview_locales_output_paks_folder)/nl.pak', + '<(webview_locales_output_paks_folder)/pl.pak', + '<(webview_locales_output_paks_folder)/pt-BR.pak', + '<(webview_locales_output_paks_folder)/pt-PT.pak', + '<(webview_locales_output_paks_folder)/ro.pak', + '<(webview_locales_output_paks_folder)/ru.pak', + '<(webview_locales_output_paks_folder)/sk.pak', + '<(webview_locales_output_paks_folder)/sl.pak', + '<(webview_locales_output_paks_folder)/sr.pak', + '<(webview_locales_output_paks_folder)/sv.pak', + '<(webview_locales_output_paks_folder)/sw.pak', + '<(webview_locales_output_paks_folder)/ta.pak', + '<(webview_locales_output_paks_folder)/te.pak', + '<(webview_locales_output_paks_folder)/th.pak', + '<(webview_locales_output_paks_folder)/tr.pak', + '<(webview_locales_output_paks_folder)/uk.pak', + '<(webview_locales_output_paks_folder)/vi.pak', + '<(webview_locales_output_paks_folder)/zh-CN.pak', + '<(webview_locales_output_paks_folder)/zh-TW.pak', + ], + }, +} +
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 67a9f90..4030452 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h
@@ -43,8 +43,8 @@ void DidBeginMainFrame() override; void BeginMainFrame(const cc::BeginFrameArgs& args) override {} void Layout() override {} - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {}
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index e0f9013..0d647e8f 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -19,11 +19,8 @@ #include "base/threading/sequenced_worker_pool.h" #include "base/threading/worker_pool.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/cookie_store_factory.h" @@ -47,7 +44,6 @@ #include "net/url_request/url_request_interceptor.h" using content::BrowserThread; -using data_reduction_proxy::DataReductionProxySettings; namespace android_webview { @@ -271,18 +267,14 @@ request_interceptors_.swap(request_interceptors); } -data_reduction_proxy::DataReductionProxyAuthRequestHandler* -AwURLRequestContextGetter::GetDataReductionProxyAuthRequestHandler() const { - return data_reduction_proxy_auth_request_handler_.get(); -} - net::NetLog* AwURLRequestContextGetter::GetNetLog() { return net_log_.get(); } void AwURLRequestContextGetter::SetKeyOnIO(const std::string& key) { - DCHECK(data_reduction_proxy_auth_request_handler_); - data_reduction_proxy_auth_request_handler_->InitAuthentication(key); + DCHECK(AwBrowserContext::GetDefault()->GetDataReductionProxyIOData()); + AwBrowserContext::GetDefault()->GetDataReductionProxyIOData()-> + auth_request_handler()->InitAuthentication(key); } } // namespace android_webview
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h index fbaf24a3..d5e099f 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.h +++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -23,10 +23,6 @@ class URLRequestJobFactory; } -namespace data_reduction_proxy { -class DataReductionProxyAuthRequestHandler; -} - namespace android_webview { class AwNetworkDelegate; @@ -43,9 +39,6 @@ scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const override; - data_reduction_proxy::DataReductionProxyAuthRequestHandler* - GetDataReductionProxyAuthRequestHandler() const; - // NetLog is thread-safe, so clients can call this method from arbitrary // threads (UI and IO). net::NetLog* GetNetLog(); @@ -75,8 +68,6 @@ scoped_ptr<net::NetLog> net_log_; scoped_ptr<net::URLRequestContext> url_request_context_; scoped_ptr<net::ProxyConfigService> proxy_config_service_; - scoped_ptr<data_reduction_proxy::DataReductionProxyAuthRequestHandler> - data_reduction_proxy_auth_request_handler_; scoped_ptr<net::URLRequestJobFactory> job_factory_; scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index 184c86d..5779914 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc
@@ -69,7 +69,6 @@ void RequestDrawGLTracker::SetQueuedFunctorOnUi(SharedRendererState* state) { base::AutoLock lock(lock_); DCHECK(state); - DCHECK(pending_ui_ == state || pending_non_ui_ == state); pending_ui_ = state; pending_non_ui_ = NULL; }
diff --git a/android_webview/build/resources_config.mk b/android_webview/build/resources_config.mk index 4c50ff2..0b43509d 100644 --- a/android_webview/build/resources_config.mk +++ b/android_webview/build/resources_config.mk
@@ -26,6 +26,7 @@ android_webview_aapt_flags += --extra-packages org.chromium.content android_webview_aapt_flags += --extra-packages org.chromium.ui android_webview_aapt_flags += -0 pak +android_webview_aapt_flags += --ignore-assets '!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~' android_webview_system_pak_targets := \ webviewchromium_pak \
diff --git a/android_webview/common/aw_crash_handler.cc b/android_webview/common/aw_crash_handler.cc index fbd4285..7dcdc9d 100644 --- a/android_webview/common/aw_crash_handler.cc +++ b/android_webview/common/aw_crash_handler.cc
@@ -71,7 +71,7 @@ return; } - g_crash_msg = "### WebView crash. " + version; + g_crash_msg = "### WebView " + version; g_crash_msg_ptr = g_crash_msg.c_str(); // Fail if unable to store all the old handlers.
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/DrawGLFunctor.java b/android_webview/glue/java/src/com/android/webview/chromium/DrawGLFunctor.java index 34348b7..b12cb04 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/DrawGLFunctor.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/DrawGLFunctor.java
@@ -24,10 +24,13 @@ // Pointer to native side instance private CleanupReference mCleanupReference; private DestroyRunnable mDestroyRunnable; + private final long mNativeDrawGLFunctor; private WebViewDelegate mWebViewDelegate; + View mContainerView; public DrawGLFunctor(long viewContext, WebViewDelegate webViewDelegate) { - mDestroyRunnable = new DestroyRunnable(nativeCreateGLFunctor(viewContext), webViewDelegate); + mNativeDrawGLFunctor = nativeCreateGLFunctor(viewContext); + mDestroyRunnable = new DestroyRunnable(mNativeDrawGLFunctor); mCleanupReference = new CleanupReference(this, mDestroyRunnable); mWebViewDelegate = webViewDelegate; } @@ -39,11 +42,14 @@ mCleanupReference = null; mDestroyRunnable = null; mWebViewDelegate = null; + mContainerView = null; } } public void detach() { - mDestroyRunnable.detachNativeFunctor(); + if (mWebViewDelegate != null && mContainerView != null) { + mWebViewDelegate.detachDrawGlFunctor(mContainerView, mNativeDrawGLFunctor); + } } public boolean requestDrawGL(Canvas canvas, View containerView, boolean waitForCompletion) { @@ -60,7 +66,7 @@ return false; } - mDestroyRunnable.mContainerView = containerView; + mContainerView = containerView; if (canvas == null) { mWebViewDelegate.invokeDrawGlFunctor( @@ -80,29 +86,19 @@ // IMPORTANT: this class must not hold any reference back to the outer DrawGLFunctor // instance, as that will defeat GC of that object. private static final class DestroyRunnable implements Runnable { - private WebViewDelegate mWebViewDelegate; - View mContainerView; - long mNativeDrawGLFunctor; - DestroyRunnable(long nativeDrawGLFunctor, WebViewDelegate webViewDelegate) { + private long mNativeDrawGLFunctor; + DestroyRunnable(long nativeDrawGLFunctor) { mNativeDrawGLFunctor = nativeDrawGLFunctor; - mWebViewDelegate = webViewDelegate; + assert mNativeDrawGLFunctor != 0; } // Called when the outer DrawGLFunctor instance has been GC'ed, i.e this is its finalizer. @Override public void run() { - detachNativeFunctor(); + assert mNativeDrawGLFunctor != 0; nativeDestroyGLFunctor(mNativeDrawGLFunctor); mNativeDrawGLFunctor = 0; } - - void detachNativeFunctor() { - if (mNativeDrawGLFunctor != 0 && mContainerView != null && mWebViewDelegate != null) { - mWebViewDelegate.detachDrawGlFunctor(mContainerView, mNativeDrawGLFunctor); - } - mContainerView = null; - mWebViewDelegate = null; - } } private static native long nativeCreateGLFunctor(long viewContext);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 9efefb7..960580c 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -181,6 +181,15 @@ } } + /** + * Callback used when flushing the visual state, see {@link #flushVisualState}. + */ + @VisibleForTesting + public abstract static class VisualStateFlushCallback { + public abstract void onComplete(); + public abstract void onFailure(); + } + private long mNativeAwContents; private final AwBrowserContext mBrowserContext; private ViewGroup mContainerView; @@ -2030,6 +2039,21 @@ if (!isDestroyed()) nativeSetJsOnlineProperty(mNativeAwContents, networkUp); } + /** + * Flush the visual state. + * + * Flushing the visual state means queuing a callback in Blink that will be invoked when the + * contents of the DOM tree at the moment that the callback was enqueued (or later) are drawn + * into the screen. In other words, the following events need to happen before the callback is + * invoked: + * 1. The DOM tree is committed becoming the pending tree - see ThreadProxy::BeginMainFrame + * 2. The pending tree is activated becoming the active tree + * 3. A frame swap happens that draws the active tree into the screen + */ + public void flushVisualState(VisualStateFlushCallback callback) { + nativeFlushVisualState(mNativeAwContents, callback); + } + //-------------------------------------------------------------------------------------------- // Methods called from native via JNI //-------------------------------------------------------------------------------------------- @@ -2133,6 +2157,28 @@ mContentsClient.getCallbackHelper().postOnNewPicture(mPictureListenerContentProvider); } + /** + * Invokes the given {@link VisualStateFlushCallback}. + * + * @param result true if the flush request was successful and false otherwise + */ + @CalledByNative + public void flushVisualStateCallback( + final VisualStateFlushCallback callback, final boolean result) { + // Posting avoids invoking the callback inside invoking_composite_ + // (see synchronous_compositor_impl.cc and crbug/452530). + mContainerView.getHandler().post(new Runnable() { + @Override + public void run() { + if (result) { + callback.onComplete(); + } else { + callback.onFailure(); + } + } + }); + } + // Called as a result of nativeUpdateLastHitTestData. @CalledByNative private void updateHitTestData( @@ -2689,6 +2735,8 @@ private native long nativeGetAwDrawGLViewContext(long nativeAwContents); private native long nativeCapturePicture(long nativeAwContents, int width, int height); private native void nativeEnableOnNewPicture(long nativeAwContents, boolean enabled); + private native void nativeFlushVisualState( + long nativeAwContents, VisualStateFlushCallback callback); private native void nativeClearView(long nativeAwContents); private native void nativeSetExtraHeadersForUrl(long nativeAwContents, String url, String extraHeaders);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java index a5d7323..9224b2bd 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
@@ -219,7 +219,7 @@ private void assertScrollInJs(final AwContents awContents, final TestAwContentsClient contentsClient, - final int xCss, final int yCss) throws Exception { + final double xCss, final double yCss) throws Exception { poll(new Callable<Boolean>() { @Override public Boolean call() throws Exception { @@ -227,8 +227,8 @@ "window.scrollX"); String y = executeJavaScriptAndWaitForResult(awContents, contentsClient, "window.scrollY"); - return (Integer.toString(xCss).equals(x) - && Integer.toString(yCss).equals(y)); + return (Math.abs(xCss - Double.parseDouble(x)) < 0.001 + && Math.abs(yCss - Double.parseDouble(y)) < 0.001); } }); } @@ -421,8 +421,8 @@ // Make sure we can't hit these values simply as a result of scrolling. assert (maxScrollXPix % dragStepSize) != 0; assert (maxScrollYPix % dragStepSize) != 0; - final int maxScrollXCss = (int) Math.floor(maxScrollXPix / deviceDIPScale); - final int maxScrollYCss = (int) Math.floor(maxScrollYPix / deviceDIPScale); + final double maxScrollXCss = maxScrollXPix / deviceDIPScale; + final double maxScrollYCss = maxScrollYPix / deviceDIPScale; setMaxScrollOnMainSync(testContainerView, maxScrollXPix, maxScrollYPix);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java index 131eb1a..8d21a2fd 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
@@ -5,17 +5,16 @@ package org.chromium.android_webview.test; import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Color; import android.os.Build; import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; import org.chromium.android_webview.AwContents; -import org.chromium.android_webview.AwContentsClient.ShouldInterceptRequestParams; import org.chromium.android_webview.AwWebResourceResponse; import org.chromium.android_webview.test.util.AwTestTouchUtils; import org.chromium.android_webview.test.util.CommonResources; +import org.chromium.android_webview.test.util.GraphicsTestUtils; import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; @@ -252,11 +251,9 @@ pollOnUiThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { - Bitmap bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - canvas.translate(-(float) mTestContainerView.getWidth() / 2, + Bitmap bitmap = GraphicsTestUtils.drawAwContents(mAwContents, 2, 2, + -(float) mTestContainerView.getWidth() / 2, -(float) mTestContainerView.getHeight() / 2); - mAwContents.onDraw(canvas); return bitmap.getPixel(0, 0) == Color.BLUE; } });
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java index f22e1ce..d125ed77 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java
@@ -4,12 +4,12 @@ package org.chromium.android_webview.test; -import android.graphics.Bitmap; import android.graphics.Color; import android.os.Build; import android.test.suitebuilder.annotation.SmallTest; import org.chromium.android_webview.AwContents; +import org.chromium.android_webview.test.util.GraphicsTestUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; @@ -43,17 +43,11 @@ }); } - Bitmap grabViewToBitmap() { - final Bitmap result = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); - mAwContents.onDraw(new android.graphics.Canvas(result)); - return result; - } - int sampleBackgroundColorOnUiThread() throws Exception { return ThreadUtils.runOnUiThreadBlocking(new Callable<Integer>() { @Override public Integer call() throws Exception { - return grabViewToBitmap().getPixel(0, 0); + return GraphicsTestUtils.drawAwContents(mAwContents, 10, 10).getPixel(0, 0); } }); }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java new file mode 100644 index 0000000..a20ddb5 --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -0,0 +1,117 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.graphics.Bitmap; +import android.graphics.Color; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.android_webview.AwContents; +import org.chromium.android_webview.AwContents.VisualStateFlushCallback; +import org.chromium.android_webview.test.util.CommonResources; +import org.chromium.android_webview.test.util.GraphicsTestUtils; +import org.chromium.base.test.util.Feature; +import org.chromium.content.browser.test.util.CallbackHelper; +import org.chromium.content_public.browser.LoadUrlParams; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Visual state related tests. + */ +public class VisualStateTest extends AwTestBase { + + private TestAwContentsClient mContentsClient = new TestAwContentsClient(); + + @Feature({"AndroidWebView"}) + @SmallTest + public void testFlushVisualStateCallbackIsReceived() throws Throwable { + AwTestContainerView testContainer = createAwTestContainerViewOnMainSync(mContentsClient); + final AwContents awContents = testContainer.getAwContents(); + loadUrlSync( + awContents, mContentsClient.getOnPageFinishedHelper(), CommonResources.ABOUT_HTML); + final CallbackHelper ch = new CallbackHelper(); + final int chCount = ch.getCallCount(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + awContents.flushVisualState(new AwContents.VisualStateFlushCallback() { + @Override + public void onComplete() { + ch.notifyCalled(); + } + + @Override + public void onFailure() { + fail("onFailure received"); + } + }); + } + }); + ch.waitForCallback(chCount); + } + + @Feature({"AndroidWebView"}) + @SmallTest + public void testFlushVisualStateCallbackWaitsForContentsToBeOnScreen() throws Throwable { + // This test loads a page with a blue background color. It then waits for the DOM tree + // in blink to contain the contents of the blue page (which happens when the onPageFinished + // event is received). It then flushes the contents and verifies that the blue page + // background color is drawn when the flush callback is received. + final LoadUrlParams bluePageUrl = createTestPageUrl("blue"); + final CountDownLatch testFinishedSignal = new CountDownLatch(1); + + final AtomicReference<AwContents> awContentsRef = new AtomicReference<>(); + final AwTestContainerView testView = + createAwTestContainerViewOnMainSync(new TestAwContentsClient() { + @Override + public void onPageFinished(String url) { + if (bluePageUrl.getUrl().equals(url)) { + awContentsRef.get().flushVisualState(new VisualStateFlushCallback() { + @Override + public void onFailure() { + fail("onFailure received"); + } + + @Override + public void onComplete() { + Bitmap blueScreenshot = GraphicsTestUtils.drawAwContents( + awContentsRef.get(), 1, 1); + assertEquals(Color.BLUE, blueScreenshot.getPixel(0, 0)); + testFinishedSignal.countDown(); + } + }); + } + } + }); + final AwContents awContents = testView.getAwContents(); + awContentsRef.set(awContents); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + awContents.setBackgroundColor(Color.RED); + awContents.loadUrl(bluePageUrl); + + // We have just loaded the blue page, but the graphics pipeline is asynchronous + // so at this point the WebView still draws red, ie. the View background color. + // Only when the flush callback is received will we know for certain that the + // blue page contents are on screen. + Bitmap redScreenshot = GraphicsTestUtils.drawAwContents( + awContentsRef.get(), 1, 1); + assertEquals(Color.RED, redScreenshot.getPixel(0, 0)); + } + }); + + assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } + + private static final LoadUrlParams createTestPageUrl(String backgroundColor) { + return LoadUrlParams.createLoadDataParams( + "<html><body bgcolor=" + backgroundColor + "></body></html>", "text/html", false); + } +}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/GraphicsTestUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/GraphicsTestUtils.java new file mode 100644 index 0000000..95c6758 --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/GraphicsTestUtils.java
@@ -0,0 +1,52 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test.util; + +import android.graphics.Bitmap; +import android.graphics.Canvas; + +import org.chromium.android_webview.AwContents; + +/** + * Graphics-related test utils. + */ +public class GraphicsTestUtils { + /** + * Draws the supplied {@link AwContents} into the returned {@link Bitmap}. + * + * @param awContents The contents to draw + * @param width The width of the bitmap + * @param height The height of the bitmap + */ + public static Bitmap drawAwContents(AwContents awContents, int width, int height) { + return doDrawAwContents(awContents, width, height, null, null); + } + + /** + * Draws the supplied {@link AwContents} after applying a translate into the returned + * {@link Bitmap}. + * + * @param awContents The contents to draw + * @param width The width of the bitmap + * @param height The height of the bitmap + * @param dx The distance to translate in X + * @param dy The distance to translate in Y + */ + public static Bitmap drawAwContents( + AwContents awContents, int width, int height, float dx, float dy) { + return doDrawAwContents(awContents, width, height, dx, dy); + } + + private static Bitmap doDrawAwContents( + AwContents awContents, int width, int height, Float dx, Float dy) { + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + if (dx != null && dy != null) { + canvas.translate(dx, dy); + } + awContents.onDraw(canvas); + return bitmap; + } +}
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 28a715f..6c468f6 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc
@@ -1034,6 +1034,27 @@ browser_view_renderer_.EnableOnNewPicture(enabled); } +namespace { +void FlushVisualStateCallback(const JavaObjectWeakGlobalRef& java_ref, + ScopedJavaGlobalRef<jobject>* callback, + bool result) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref.get(env); + if (obj.is_null()) + return; + Java_AwContents_flushVisualStateCallback( + env, obj.obj(), callback->obj(), result); +} +} // namespace + +void AwContents::FlushVisualState(JNIEnv* env, jobject obj, jobject callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>(); + j_callback->Reset(env, callback); + web_contents_->GetMainFrame()->FlushVisualState(base::Bind( + &FlushVisualStateCallback, java_ref_, base::Owned(j_callback))); +} + void AwContents::ClearView(JNIEnv* env, jobject obj) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); browser_view_renderer_.ClearView();
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 7110ebab..077690f 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h
@@ -129,6 +129,7 @@ jlong GetAwDrawGLViewContext(JNIEnv* env, jobject obj); jlong CapturePicture(JNIEnv* env, jobject obj, int width, int height); void EnableOnNewPicture(JNIEnv* env, jobject obj, jboolean enabled); + void FlushVisualState(JNIEnv* env, jobject obj, jobject callback); void ClearView(JNIEnv* env, jobject obj); void SetExtraHeadersForUrl(JNIEnv* env, jobject obj, jstring url, jstring extra_headers);
diff --git a/android_webview/native/aw_contents_statics.cc b/android_webview/native/aw_contents_statics.cc index e09fcb8c..95c4ab8 100644 --- a/android_webview/native/aw_contents_statics.cc +++ b/android_webview/native/aw_contents_statics.cc
@@ -10,7 +10,6 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/callback.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h" #include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/url_constants.h" @@ -21,7 +20,6 @@ using base::android::ConvertJavaStringToUTF8; using base::android::ScopedJavaGlobalRef; using content::BrowserThread; -using data_reduction_proxy::DataReductionProxyAuthRequestHandler; namespace android_webview { @@ -59,8 +57,7 @@ DCHECK(browser_context->GetRequestContext()); // The following call to GetRequestContext() could possibly be the first such // call, which means AwURLRequestContextGetter::InitializeURLRequestContext - // will be called on IO thread as a result. InitializeURLRequestContext() - // will initialize DataReductionProxyAuthRequestHandler. + // will be called on IO thread as a result. AwURLRequestContextGetter* aw_url_request_context_getter = static_cast<AwURLRequestContextGetter*>( browser_context->GetRequestContext());
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java index bd490f4c..35d807a0 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -42,6 +42,9 @@ import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.WebContents; +import java.net.URI; +import java.net.URISyntaxException; + /** * This is a lightweight activity for tests that only require WebView functionality. */ @@ -195,8 +198,18 @@ return false; } - mAwTestContainerView.getAwContents().loadUrl( - new LoadUrlParams(mUrlTextView.getText().toString())); + String url = mUrlTextView.getText().toString(); + try { + URI uri = new URI(url); + if (uri.getScheme() == null) { + url = "http://" + uri.toString(); + } else { + url = uri.toString(); + } + } catch (URISyntaxException e) { + // Ignore syntax errors. + } + mAwTestContainerView.getAwContents().loadUrl(new LoadUrlParams(url)); mUrlTextView.clearFocus(); setKeyboardVisibilityForUrl(false); mAwTestContainerView.requestFocus();
diff --git a/android_webview/tools/webview_locales_rename_paks.py b/android_webview/tools/webview_locales_rename_paks.py new file mode 100755 index 0000000..4bc77e5 --- /dev/null +++ b/android_webview/tools/webview_locales_rename_paks.py
@@ -0,0 +1,98 @@ +#!/usr/bin/env python +# Copyright (c) 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Helper script to rename paks for a list of locales for the Android WebView. + +Gyp doesn't have any built-in looping capability, so this just provides a way to +loop over a list of locales when renaming pak files. Based on +chrome/tools/build/repack_locales.py +""" + +import optparse +import os +import shutil +import sys + +def calc_output(locale): + """Determine the file that will be generated for the given locale.""" + return os.path.join(PRODUCT_DIR, 'android_webview_assets', + 'locales', locale + '.pak') + +def calc_input(locale): + """Determine the file that needs processing for the given locale.""" + return os.path.join(SHARE_INT_DIR, 'content', 'app', 'strings', + 'content_strings_%s.pak' % locale) + +def list_outputs(locales): + """Returns the names of the files that will be generated for the given + locales. + + This is to provide gyp the list of output files, so build targets can + properly track what needs to be built. + """ + return list_files(locales, calc_output) + +def list_inputs(locales): + """Returns the names of the files that will be processed for the given + locales. + + This is to provide gyp the list of input files, so build targets can properly + track their prerequisites. + """ + return list_files(locales, calc_input) + +def list_files(locales, filename_func): + """Returns the names of the files generated by filename_func for a list of + locales. + + :param filename_func: function that generates a filename for a given locale + """ + files = [] + for locale in locales: + files.append(filename_func(locale)) + return " ".join(['"%s"' % x for x in files]) + +def rename_locales(locales): + """ Loop over and renames the given locales.""" + for locale in locales: + shutil.copy(calc_input(locale), calc_output(locale)) + +def DoMain(argv): + global SHARE_INT_DIR + global PRODUCT_DIR + + parser = optparse.OptionParser("usage: %prog [options] locales") + parser.add_option("-i", action="store_true", dest="inputs", default=False, + help="Print the expected input file list, then exit.") + parser.add_option("-o", action="store_true", dest="outputs", default=False, + help="Print the expected output file list, then exit.") + parser.add_option("-p", action="store", dest="product_dir", + help="Product build files output directory.") + parser.add_option("-s", action="store", dest="share_int_dir", + help="Shared intermediate build files output directory.") + options, locales = parser.parse_args(argv) + if not locales: + parser.error('Please specify at least one locale to process.\n') + + print_inputs = options.inputs + print_outputs = options.outputs + SHARE_INT_DIR = options.share_int_dir + PRODUCT_DIR = options.product_dir + + if print_inputs and print_outputs: + parser.error('Please specify only one of "-i" or "-o".\n') + + if print_inputs: + return list_inputs(locales) + + if print_outputs: + return list_outputs(locales) + + return rename_locales(locales) + +if __name__ == '__main__': + results = DoMain(sys.argv[1:]) + if results: + print results
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f1c5eb1..401f456 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -36,6 +36,7 @@ "//ui/app_list", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events:events_base", @@ -229,6 +230,7 @@ "//ui/app_list", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events:events_base", @@ -266,6 +268,7 @@ "//ui/aura", "//ui/aura:test_support", "//ui/base", + "//ui/base/ime", "//ui/base:test_support", "//ui/compositor", "//ui/compositor:test_support",
diff --git a/ash/ash.gyp b/ash/ash.gyp index 8861a16..f582504 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp
@@ -887,6 +887,7 @@ '../ui/accessibility/accessibility.gyp:accessibility', '../ui/app_list/app_list.gyp:app_list', '../ui/aura/aura.gyp:aura', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/compositor/compositor.gyp:compositor', '../ui/events/devices/events_devices.gyp:events_devices', @@ -1067,6 +1068,7 @@ '../ui/app_list/app_list.gyp:app_list', '../ui/aura/aura.gyp:aura', '../ui/aura/aura.gyp:aura_test_support', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/base/ui_base.gyp:ui_base_test_support', '../ui/compositor/compositor.gyp:compositor', @@ -1176,6 +1178,7 @@ '../third_party/icu/icu.gyp:icuuc', '../ui/app_list/app_list.gyp:app_list', '../ui/aura/aura.gyp:aura', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/compositor/compositor.gyp:compositor', '../ui/events/events.gyp:events',
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc index 270a39f1..f11743dd 100644 --- a/ash/ash_switches.cc +++ b/ash/ash_switches.cc
@@ -33,6 +33,12 @@ // WorkspaceLayoutManager. const char kAshDisableLockLayoutManager[] = "ash-disable-lock-layout-manager"; +#if defined(OS_CHROMEOS) +// Disable the support for WebContents to lock the screen orientation. +const char kAshDisableScreenOrientationLock[] = + "ash-disable-screen-orientation-lock"; +#endif + // Disable the Touch Exploration Mode. Touch Exploration Mode will no longer be // turned on automatically when spoken feedback is enabled when this flag is // set.
diff --git a/ash/ash_switches.h b/ash/ash_switches.h index 12a71dc..4edb61e 100644 --- a/ash/ash_switches.h +++ b/ash/ash_switches.h
@@ -22,6 +22,9 @@ ASH_EXPORT extern const char kAshCopyHostBackgroundAtBoot[]; ASH_EXPORT extern const char kAshDebugShortcuts[]; ASH_EXPORT extern const char kAshDisableLockLayoutManager[]; +#if defined(OS_CHROMEOS) +ASH_EXPORT extern const char kAshDisableScreenOrientationLock[]; +#endif ASH_EXPORT extern const char kAshDisableTouchExplorationMode[]; #if defined(OS_CHROMEOS) ASH_EXPORT extern const char kAshEnableFullscreenAppList[];
diff --git a/ash/content/display/screen_orientation_controller_chromeos.cc b/ash/content/display/screen_orientation_controller_chromeos.cc index a80a1b8..ea473e0 100644 --- a/ash/content/display/screen_orientation_controller_chromeos.cc +++ b/ash/content/display/screen_orientation_controller_chromeos.cc
@@ -183,8 +183,8 @@ return Shell::GetInstance() ->maximize_mode_controller() ->IsMaximizeModeWindowManagerEnabled() && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshEnableTouchViewTesting); + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshDisableScreenOrientationLock); } void ScreenOrientationController::Unlock(content::WebContents* web_contents) {
diff --git a/ash/test/virtual_keyboard_test_helper.cc b/ash/test/virtual_keyboard_test_helper.cc index c920213..5cb39db 100644 --- a/ash/test/virtual_keyboard_test_helper.cc +++ b/ash/test/virtual_keyboard_test_helper.cc
@@ -17,14 +17,13 @@ ui::DeviceHotplugEventObserver* manager = ui::DeviceDataManager::GetInstance(); std::vector<ui::TouchscreenDevice> screens; - screens.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, - "Touchscreen", gfx::Size(1024, 768), 0)); + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); manager->OnTouchscreenDevicesUpdated(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); manager->OnKeyboardDevicesUpdated(keyboards); }
diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc index 3dbc8ca..fd64107 100644 --- a/ash/touch/touch_transformer_controller_unittest.cc +++ b/ash/touch/touch_transformer_controller_unittest.cc
@@ -33,7 +33,7 @@ ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id, const gfx::Size& size) { return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - std::string(), size, 0); + size, 0); } } // namespace
diff --git a/ash/touch/touchscreen_util_unittest.cc b/ash/touch/touchscreen_util_unittest.cc index a80c357..4993093 100644 --- a/ash/touch/touchscreen_util_unittest.cc +++ b/ash/touch/touchscreen_util_unittest.cc
@@ -76,12 +76,10 @@ TEST_F(TouchscreenUtilTest, OneToOneMapping) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(800, 600), 0)); - devices.push_back( - ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(1024, 768), 0)); + devices.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); + devices.push_back(ui::TouchscreenDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1024, 768), 0)); AssociateTouchscreens(&displays_, devices); @@ -93,9 +91,8 @@ TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back( - ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(1024, 768), 0)); + devices.push_back(ui::TouchscreenDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1024, 768), 0)); AssociateTouchscreens(&displays_, devices); @@ -107,12 +104,10 @@ TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(801, 600), 0)); - devices.push_back( - ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(1023, 768), 0)); + devices.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(801, 600), 0)); + devices.push_back(ui::TouchscreenDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1023, 768), 0)); AssociateTouchscreens(&displays_, devices); @@ -124,12 +119,10 @@ TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(1022, 768), 0)); - devices.push_back( - ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(802, 600), 0)); + devices.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1022, 768), 0)); + devices.push_back(ui::TouchscreenDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(802, 600), 0)); AssociateTouchscreens(&displays_, devices); @@ -141,12 +134,10 @@ TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", - gfx::Size(1920, 1080), 0)); - devices.push_back( - ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", - gfx::Size(9999, 888), 0)); + devices.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1920, 1080), 0)); + devices.push_back(ui::TouchscreenDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(9999, 888), 0)); AssociateTouchscreens(&displays_, devices);
diff --git a/ash/virtual_keyboard_controller_unittest.cc b/ash/virtual_keyboard_controller_unittest.cc index 5c452a1..f3d169b 100644 --- a/ash/virtual_keyboard_controller_unittest.cc +++ b/ash/virtual_keyboard_controller_unittest.cc
@@ -84,8 +84,8 @@ MockEventBlocker() {} ~MockEventBlocker() override { std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); ui::DeviceHotplugEventObserver* manager = ui::DeviceDataManager::GetInstance(); manager->OnKeyboardDevicesUpdated(keyboards); @@ -157,13 +157,12 @@ // present. TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, - "Touchscreen", gfx::Size(1024, 768), 0)); + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); // Remove the internal keyboard. Virtual keyboard should now show. @@ -177,9 +176,8 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) { std::vector<ui::TouchscreenDevice> devices; // Add a touchscreen. Keyboard should deploy. - devices.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - "Touchscreen", gfx::Size(800, 600), 0)); + devices.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); UpdateTouchscreenDevices(devices); EXPECT_TRUE(keyboard::IsKeyboardEnabled()); // Remove touchscreen. Keyboard should hide. @@ -189,13 +187,12 @@ TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, - "Touchscreen", gfx::Size(1024, 768), 0)); + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_TRUE(notified()); @@ -228,12 +225,12 @@ // Tests handling multiple keyboards. Catches crbug.com/430252 TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) { std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); - keyboards.push_back(ui::KeyboardDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); - keyboards.push_back(ui::KeyboardDevice( - 3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back( + ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back( + ui::KeyboardDevice(3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); } @@ -259,13 +256,12 @@ // keyboard always enabled flag is active. TEST_F(VirtualKeyboardControllerAlwaysEnabledTest, DoesNotSuppressKeyboard) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back( - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, - "Touchscreen", gfx::Size(1024, 768), 0)); + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); UpdateKeyboardDevices(keyboards); ASSERT_TRUE(keyboard::IsKeyboardEnabled()); }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 43f92f50..44e656c2 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -342,7 +342,6 @@ "memory/ref_counted_delete_on_message_loop.h", "memory/ref_counted_memory.cc", "memory/ref_counted_memory.h", - "memory/scoped_open_process.h", "memory/scoped_policy.h", "memory/scoped_ptr.h", "memory/scoped_vector.h",
diff --git a/base/android/scoped_java_ref_unittest.cc b/base/android/scoped_java_ref_unittest.cc index 36f253c..3f4419af 100644 --- a/base/android/scoped_java_ref_unittest.cc +++ b/base/android/scoped_java_ref_unittest.cc
@@ -40,7 +40,7 @@ class ScopedJavaRefTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { g_local_refs = 0; g_global_refs = 0; JNIEnv* env = AttachCurrentThread(); @@ -55,7 +55,7 @@ hooked_functions.DeleteLocalRef = &DeleteLocalRef; } - virtual void TearDown() { + void TearDown() override { JNIEnv* env = AttachCurrentThread(); env->functions = g_previous_functions; }
diff --git a/base/android/trace_event_binding.cc b/base/android/trace_event_binding.cc index 94eb214..b8ce6d9 100644 --- a/base/android/trace_event_binding.cc +++ b/base/android/trace_event_binding.cc
@@ -57,11 +57,11 @@ class TraceEnabledObserver : public debug::TraceLog::EnabledStateObserver { public: - virtual void OnTraceLogEnabled() override { + void OnTraceLogEnabled() override { JNIEnv* env = base::android::AttachCurrentThread(); base::android::Java_TraceEvent_setEnabled(env, true); } - virtual void OnTraceLogDisabled() override { + void OnTraceLogDisabled() override { JNIEnv* env = base::android::AttachCurrentThread(); base::android::Java_TraceEvent_setEnabled(env, false); }
diff --git a/base/base.gypi b/base/base.gypi index 73c6c3b..6dd6fcfc 100644 --- a/base/base.gypi +++ b/base/base.gypi
@@ -348,7 +348,6 @@ 'memory/ref_counted_delete_on_message_loop.h', 'memory/ref_counted_memory.cc', 'memory/ref_counted_memory.h', - 'memory/scoped_open_process.h', 'memory/scoped_policy.h', 'memory/scoped_ptr.h', 'memory/scoped_vector.h',
diff --git a/base/base.isolate b/base/base.isolate index 5220887..cb85965 100644 --- a/base/base.isolate +++ b/base/base.isolate
@@ -94,5 +94,9 @@ ], }, }], + # Workaround for https://code.google.com/p/swarming/issues/detail?id=211 + ['asan==0 or lsan==0 or msan==0 or tsan==0', { + 'variables': {}, + }], ], }
diff --git a/base/base_unittests.isolate b/base/base_unittests.isolate index fca76d5..0822b24 100644 --- a/base/base_unittests.isolate +++ b/base/base_unittests.isolate
@@ -58,6 +58,13 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/base_unittests.dSYM/', + ], + }, + }], ['OS=="win" and (fastbuild==0 or fastbuild==1)', { 'variables': { 'files': [
diff --git a/base/bind.h b/base/bind.h index 7874656..51be10d 100644 --- a/base/bind.h +++ b/base/bind.h
@@ -52,13 +52,14 @@ typename internal::BindState< typename internal::FunctorTraits<Functor>::RunnableType, typename internal::FunctorTraits<Functor>::RunType, - void()>::UnboundRunType> + internal::TypeList<>>::UnboundRunType> Bind(Functor functor) { // Typedefs for how to store and run the functor. typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; typedef typename internal::FunctorTraits<Functor>::RunType RunType; - typedef internal::BindState<RunnableType, RunType, void()> BindState; + typedef internal::BindState<RunnableType, RunType, + internal::TypeList<>> BindState; return Callback<typename BindState::UnboundRunType>( new BindState(internal::MakeRunnable(functor))); @@ -69,7 +70,8 @@ typename internal::BindState< typename internal::FunctorTraits<Functor>::RunnableType, typename internal::FunctorTraits<Functor>::RunType, - void(typename internal::CallbackParamTraits<Args>::StorageType...)> + internal::TypeList< + typename internal::CallbackParamTraits<Args>::StorageType...>> ::UnboundRunType> Bind(Functor functor, const Args&... args) { // Typedefs for how to store and run the functor. @@ -101,8 +103,10 @@ !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, "a_parameter_is_refcounted_type_and_needs_scoped_refptr"); - typedef internal::BindState<RunnableType, RunType, - void(typename internal::CallbackParamTraits<Args>::StorageType...)> + typedef internal::BindState< + RunnableType, RunType, + internal::TypeList< + typename internal::CallbackParamTraits<Args>::StorageType...>> BindState; return Callback<typename BindState::UnboundRunType>(
diff --git a/base/bind_helpers.h b/base/bind_helpers.h index f3efc31..f8e89bd 100644 --- a/base/bind_helpers.h +++ b/base/bind_helpers.h
@@ -435,45 +435,46 @@ // Utility for handling different refcounting semantics in the Bind() // function. -template <bool is_method, typename T> -struct MaybeRefcount; +template <bool is_method, typename... T> +struct MaybeScopedRefPtr; -template <typename T> -struct MaybeRefcount<false, T> { - static void AddRef(const T&) {} - static void Release(const T&) {} +template <bool is_method> +struct MaybeScopedRefPtr<is_method> { + MaybeScopedRefPtr() {} }; -template <typename T, size_t n> -struct MaybeRefcount<false, T[n]> { - static void AddRef(const T*) {} - static void Release(const T*) {} +template <typename T, typename... Rest> +struct MaybeScopedRefPtr<false, T, Rest...> { + MaybeScopedRefPtr(const T&, const Rest&...) {} }; -template <typename T> -struct MaybeRefcount<true, T> { - static void AddRef(const T&) {} - static void Release(const T&) {} +template <typename T, size_t n, typename... Rest> +struct MaybeScopedRefPtr<false, T[n], Rest...> { + MaybeScopedRefPtr(const T*, const Rest&...) {} }; -template <typename T> -struct MaybeRefcount<true, T*> { - static void AddRef(T* o) { o->AddRef(); } - static void Release(T* o) { o->Release(); } +template <typename T, typename... Rest> +struct MaybeScopedRefPtr<true, T, Rest...> { + MaybeScopedRefPtr(const T& o, const Rest&...) {} +}; + +template <typename T, typename... Rest> +struct MaybeScopedRefPtr<true, T*, Rest...> { + MaybeScopedRefPtr(T* o, const Rest&...) : ref_(o) {} + scoped_refptr<T> ref_; }; // No need to additionally AddRef() and Release() since we are storing a // scoped_refptr<> inside the storage object already. -template <typename T> -struct MaybeRefcount<true, scoped_refptr<T> > { - static void AddRef(const scoped_refptr<T>& o) {} - static void Release(const scoped_refptr<T>& o) {} +template <typename T, typename... Rest> +struct MaybeScopedRefPtr<true, scoped_refptr<T>, Rest...> { + MaybeScopedRefPtr(const scoped_refptr<T>&, const Rest&...) {} }; -template <typename T> -struct MaybeRefcount<true, const T*> { - static void AddRef(const T* o) { o->AddRef(); } - static void Release(const T* o) { o->Release(); } +template <typename T, typename... Rest> +struct MaybeScopedRefPtr<true, const T*, Rest...> { + MaybeScopedRefPtr(const T* o, const Rest&...) : ref_(o) {} + scoped_refptr<const T> ref_; }; // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a @@ -481,15 +482,89 @@ // InvokeHelper that will no-op itself in the event the WeakPtr<> for // the target object is invalidated. // -// P1 should be the type of the object that will be received of the method. -template <bool IsMethod, typename P1> +// The first argument should be the type of the object that will be received by +// the method. +template <bool IsMethod, typename... Args> struct IsWeakMethod : public false_type {}; -template <typename T> -struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; +template <typename T, typename... Args> +struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {}; -template <typename T> -struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {}; +template <typename T, typename... Args> +struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...> + : public true_type {}; + + +// Packs a list of types to hold them in a single type. +template <typename... Types> +struct TypeList {}; + +// Used for DropTypeListItem implementation. +template <size_t n, typename List> +struct DropTypeListItemImpl; + +// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. +template <size_t n, typename T, typename... List> +struct DropTypeListItemImpl<n, TypeList<T, List...>> + : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; + +template <typename T, typename... List> +struct DropTypeListItemImpl<0, TypeList<T, List...>> { + typedef TypeList<T, List...> Type; +}; + +template <> +struct DropTypeListItemImpl<0, TypeList<>> { + typedef TypeList<> Type; +}; + +// A type-level function that drops |n| list item from given TypeList. +template <size_t n, typename List> +using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; + +// Used for ConcatTypeLists implementation. +template <typename List1, typename List2> +struct ConcatTypeListsImpl; + +template <typename... Types1, typename... Types2> +struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { + typedef TypeList<Types1..., Types2...> Type; +}; + +// A type-level function that concats two TypeLists. +template <typename List1, typename List2> +using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; + +template <size_t n, typename List> +struct NthTypeImpl; + +template <size_t n, typename T, typename... Types> +struct NthTypeImpl<n, TypeList<T, Types...>> + : NthTypeImpl<n - 1, TypeList<Types...>> { +}; + +template <typename T, typename... Types> +struct NthTypeImpl<0, TypeList<T, Types...>> { + typedef T Type; +}; + +// A type-level function that extracts |n|th type from a TypeList. +template <size_t n, typename List> +using NthType = typename NthTypeImpl<n, List>::Type; + +// Used for MakeFunctionType implementation. +template <typename R, typename ArgList> +struct MakeFunctionTypeImpl; + +template <typename R, typename... Args> +struct MakeFunctionTypeImpl<R, TypeList<Args...>> { + typedef R(Type)(Args...); +}; + +// A type-level function that constructs a function type that has |R| as its +// return type and has TypeLists items as its arguments. +template <typename R, typename ArgList> +using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; } // namespace internal
diff --git a/base/bind_internal.h b/base/bind_internal.h index b568c162..5fc14592 100644 --- a/base/bind_internal.h +++ b/base/bind_internal.h
@@ -1,8 +1,3 @@ -// This file was GENERATED by command: -// pump.py bind_internal.h.pump -// DO NOT EDIT BY HAND!!! - - // Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +10,7 @@ #include "base/memory/raw_scoped_refptr_mismatch_checker.h" #include "base/memory/weak_ptr.h" #include "base/template_util.h" +#include "base/tuple.h" #include "build/build_config.h" #if defined(OS_WIN) @@ -51,10 +47,6 @@ // Types: // RunnableAdapter<> -- Wraps the various "function" pointer types into an // object that adheres to the Runnable interface. -// FunctionTraits<> -- Type traits that unwrap a function signature into a -// a set of easier to use typedefs. Used mainly for -// compile time asserts. -// There are |ARITY| FunctionTraits types. // ForceVoidReturn<> -- Helper class for translating function signatures to // equivalent forms with a "void" return type. // FunctorTraits<> -- Type traits used determine the correct RunType and @@ -64,12 +56,11 @@ // type class that represents the underlying Functor. // There are |O(1)| MakeRunnable types. // InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. -// Handle the differing syntaxes needed for WeakPtr<> support, -// and for ignoring return values. This is separate from -// Invoker to avoid creating multiple version of Invoker<> -// which grows at O(n^2) with the arity. +// Handle the differing syntaxes needed for WeakPtr<> +// support, and for ignoring return values. This is separate +// from Invoker to avoid creating multiple version of +// Invoker<>. // Invoker<> -- Unwraps the curried parameters and executes the Runnable. -// There are |(ARITY^2 + ARITY)/2| Invoketypes. // BindState<> -- Stores the curried parameters, and is the main entry point // into the Bind() system, doing most of the type resolution. // There are ARITY BindState types. @@ -209,84 +200,6 @@ R (T::*method_)(Args...) const; }; -// TODO(tzik): Remove FunctionTraits after we finish removing bind.pump. -// FunctionTraits<> -// -// Breaks a function signature apart into typedefs for easier introspection. -template <typename Sig> -struct FunctionTraits; - -template <typename R> -struct FunctionTraits<R()> { - typedef R ReturnType; -}; - -template <typename R, typename A1> -struct FunctionTraits<R(A1)> { - typedef R ReturnType; - typedef A1 A1Type; -}; - -template <typename R, typename A1, typename A2> -struct FunctionTraits<R(A1, A2)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; -}; - -template <typename R, typename A1, typename A2, typename A3> -struct FunctionTraits<R(A1, A2, A3)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; - typedef A3 A3Type; -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4> -struct FunctionTraits<R(A1, A2, A3, A4)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; - typedef A3 A3Type; - typedef A4 A4Type; -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5> -struct FunctionTraits<R(A1, A2, A3, A4, A5)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; - typedef A3 A3Type; - typedef A4 A4Type; - typedef A5 A5Type; -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> -struct FunctionTraits<R(A1, A2, A3, A4, A5, A6)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; - typedef A3 A3Type; - typedef A4 A4Type; - typedef A5 A5Type; - typedef A6 A6Type; -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> -struct FunctionTraits<R(A1, A2, A3, A4, A5, A6, A7)> { - typedef R ReturnType; - typedef A1 A1Type; - typedef A2 A2Type; - typedef A3 A3Type; - typedef A4 A4Type; - typedef A5 A5Type; - typedef A6 A6Type; - typedef A7 A7Type; -}; - // ForceVoidReturn<> // @@ -310,14 +223,14 @@ }; template <typename T> -struct FunctorTraits<IgnoreResultHelper<T> > { +struct FunctorTraits<IgnoreResultHelper<T>> { typedef typename FunctorTraits<T>::RunnableType RunnableType; typedef typename ForceVoidReturn< typename RunnableType::RunType>::RunType RunType; }; template <typename T> -struct FunctorTraits<Callback<T> > { +struct FunctorTraits<Callback<T>> { typedef Callback<T> RunnableType; typedef typename Callback<T>::RunType RunType; }; @@ -339,7 +252,7 @@ } template <typename T> -const typename FunctorTraits<Callback<T> >::RunnableType& +const typename FunctorTraits<Callback<T>>::RunnableType& MakeRunnable(const Callback<T>& t) { DCHECK(!t.is_null()); return t; @@ -368,22 +281,21 @@ struct InvokeHelper; template <typename ReturnType, typename Runnable, typename... Args> -struct InvokeHelper<false, ReturnType, Runnable, - void(Args...)> { +struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { static ReturnType MakeItSo(Runnable runnable, Args... args) { return runnable.Run(CallbackForward(args)...); } }; template <typename Runnable, typename... Args> -struct InvokeHelper<false, void, Runnable, void(Args...)> { +struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { static void MakeItSo(Runnable runnable, Args... args) { runnable.Run(CallbackForward(args)...); } }; template <typename Runnable, typename BoundWeakPtr, typename... Args> -struct InvokeHelper<true, void, Runnable, void(BoundWeakPtr, Args...)> { +struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { if (!weak_ptr.get()) { return; @@ -408,1419 +320,30 @@ // Invoker<> // // See description at the top of the file. -template <int NumBound, typename Storage, typename RunType> +template <typename BoundIndices, + typename StorageType, typename Unwrappers, + typename InvokeHelperType, typename UnboundForwardRunType> struct Invoker; -// Arity 0 -> 0. -template <typename StorageType, typename R> -struct Invoker<0, StorageType, R()> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void()> - ::MakeItSo(storage->runnable_); - } -}; - -// Arity 1 -> 1. -template <typename StorageType, typename R,typename X1> -struct Invoker<0, StorageType, R(X1)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType); - - typedef R(UnboundRunType)(X1); - +template <size_t... bound_indices, + typename StorageType, + typename... Unwrappers, + typename InvokeHelperType, + typename R, + typename... UnboundForwardArgs> +struct Invoker<IndexSequence<bound_indices...>, + StorageType, TypeList<Unwrappers...>, + InvokeHelperType, R(UnboundForwardArgs...)> { static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1) { + UnboundForwardArgs... unbound_args) { StorageType* storage = static_cast<StorageType*>(base); - // Local references to make debugger stepping easier. If in a debugger, // you really want to warp ahead and step through the // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1)> - ::MakeItSo(storage->runnable_, CallbackForward(x1)); - } -}; - -// Arity 1 -> 0. -template <typename StorageType, typename R,typename X1> -struct Invoker<1, StorageType, R(X1)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1)); - } -}; - -// Arity 2 -> 2. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker<0, StorageType, R(X1, X2)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType); - - typedef R(UnboundRunType)(X1, X2); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2)); - } -}; - -// Arity 2 -> 1. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker<1, StorageType, R(X1, X2)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType); - - typedef R(UnboundRunType)(X2); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2)); - } -}; - -// Arity 2 -> 0. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker<2, StorageType, R(X1, X2)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2)); - } -}; - -// Arity 3 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker<0, StorageType, R(X1, X2, X3)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType); - - typedef R(UnboundRunType)(X1, X2, X3); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3)); - } -}; - -// Arity 3 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker<1, StorageType, R(X1, X2, X3)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType); - - typedef R(UnboundRunType)(X2, X3); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3)); - } -}; - -// Arity 3 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker<2, StorageType, R(X1, X2, X3)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X3>::ForwardType); - - typedef R(UnboundRunType)(X3); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X3>::ForwardType x3) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename CallbackParamTraits<X3>::ForwardType x3)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3)); - } -}; - -// Arity 3 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker<3, StorageType, R(X1, X2, X3)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3)); - } -}; - -// Arity 4 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker<0, StorageType, R(X1, X2, X3, X4)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType); - - typedef R(UnboundRunType)(X1, X2, X3, X4); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4)); - } -}; - -// Arity 4 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker<1, StorageType, R(X1, X2, X3, X4)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType); - - typedef R(UnboundRunType)(X2, X3, X4); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4)); - } -}; - -// Arity 4 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker<2, StorageType, R(X1, X2, X3, X4)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType); - - typedef R(UnboundRunType)(X3, X4); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4)); - } -}; - -// Arity 4 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker<3, StorageType, R(X1, X2, X3, X4)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X4>::ForwardType); - - typedef R(UnboundRunType)(X4); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X4>::ForwardType x4) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename CallbackParamTraits<X4>::ForwardType x4)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4)); - } -}; - -// Arity 4 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker<4, StorageType, R(X1, X2, X3, X4)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4)); - } -}; - -// Arity 5 -> 5. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType); - - typedef R(UnboundRunType)(X1, X2, X3, X4, X5); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 5 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType); - - typedef R(UnboundRunType)(X2, X3, X4, X5); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 5 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType); - - typedef R(UnboundRunType)(X3, X4, X5); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 5 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType); - - typedef R(UnboundRunType)(X4, X5); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 5 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X5>::ForwardType); - - typedef R(UnboundRunType)(X5); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X5>::ForwardType x5) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename CallbackParamTraits<X5>::ForwardType x5)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 5 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5)); - } -}; - -// Arity 6 -> 6. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X1, X2, X3, X4, X5, X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 5. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X2, X3, X4, X5, X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X3, X4, X5, X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X4, X5, X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X5, X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X6>::ForwardType); - - typedef R(UnboundRunType)(X6); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X6>::ForwardType x6) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType, - typename CallbackParamTraits<X6>::ForwardType x6)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 6 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - typename Bound6UnwrapTraits::ForwardType x6 = - Bound6UnwrapTraits::Unwrap(storage->p6_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType, - typename Bound6UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6)); - } -}; - -// Arity 7 -> 7. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X1>::ForwardType, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X1, X2, X3, X4, X5, X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename CallbackParamTraits<X1>::ForwardType x1, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 6. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X2>::ForwardType, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X2, X3, X4, X5, X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename CallbackParamTraits<X2>::ForwardType x2, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 5. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X3>::ForwardType, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X3, X4, X5, X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename CallbackParamTraits<X3>::ForwardType x3, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X4>::ForwardType, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X4, X5, X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename CallbackParamTraits<X4>::ForwardType x4, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X5>::ForwardType, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X5, X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename CallbackParamTraits<X5>::ForwardType x5, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X6>::ForwardType, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X6, X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType, - typename CallbackParamTraits<X6>::ForwardType x6, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*, - typename CallbackParamTraits<X7>::ForwardType); - - typedef R(UnboundRunType)(X7); - - static R Run(BindStateBase* base, - typename CallbackParamTraits<X7>::ForwardType x7) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - typename Bound6UnwrapTraits::ForwardType x6 = - Bound6UnwrapTraits::Unwrap(storage->p6_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType, - typename Bound6UnwrapTraits::ForwardType, - typename CallbackParamTraits<X7>::ForwardType x7)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); - } -}; - -// Arity 7 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6, typename X7> -struct Invoker<7, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> { - typedef R(RunType)(BindStateBase*); - - typedef R(UnboundRunType)(); - - static R Run(BindStateBase* base) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; - typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; - typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits; - typedef typename StorageType::Bound7UnwrapTraits Bound7UnwrapTraits; - - typename Bound1UnwrapTraits::ForwardType x1 = - Bound1UnwrapTraits::Unwrap(storage->p1_); - typename Bound2UnwrapTraits::ForwardType x2 = - Bound2UnwrapTraits::Unwrap(storage->p2_); - typename Bound3UnwrapTraits::ForwardType x3 = - Bound3UnwrapTraits::Unwrap(storage->p3_); - typename Bound4UnwrapTraits::ForwardType x4 = - Bound4UnwrapTraits::Unwrap(storage->p4_); - typename Bound5UnwrapTraits::ForwardType x5 = - Bound5UnwrapTraits::Unwrap(storage->p5_); - typename Bound6UnwrapTraits::ForwardType x6 = - Bound6UnwrapTraits::Unwrap(storage->p6_); - typename Bound7UnwrapTraits::ForwardType x7 = - Bound7UnwrapTraits::Unwrap(storage->p7_); - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void(typename Bound1UnwrapTraits::ForwardType, - typename Bound2UnwrapTraits::ForwardType, - typename Bound3UnwrapTraits::ForwardType, - typename Bound4UnwrapTraits::ForwardType, - typename Bound5UnwrapTraits::ForwardType, - typename Bound6UnwrapTraits::ForwardType, - typename Bound7UnwrapTraits::ForwardType)> - ::MakeItSo(storage->runnable_, CallbackForward(x1), - CallbackForward(x2), CallbackForward(x3), - CallbackForward(x4), CallbackForward(x5), - CallbackForward(x6), CallbackForward(x7)); + return InvokeHelperType::MakeItSo( + storage->runnable_, + Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., + CallbackForward(unbound_args)...); } }; @@ -1837,275 +360,52 @@ // // BoundArgsType contains the storage type for all the bound arguments by // (ab)using a function type. -template <typename Runnable, typename RunType, typename BoundArgsType> +template <typename Runnable, typename RunType, typename BoundArgList> struct BindState; -template <typename Runnable, typename RunType> -struct BindState<Runnable, RunType, void()> : public BindStateBase { - typedef Runnable RunnableType; - typedef false_type IsWeakCall; - typedef Invoker<0, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - explicit BindState(const Runnable& runnable) - : runnable_(runnable) { - } +template <typename Runnable, + typename R, typename... Args, + typename... BoundArgs> +struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> + : public BindStateBase { + private: + using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>; + using RunnableType = Runnable; + + // true_type if Runnable is a method invocation and the first bound argument + // is a WeakPtr. + using IsWeakCall = + IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; + + using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; + using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; + using UnboundForwardArgs = DropTypeListItem< + sizeof...(BoundArgs), + TypeList<typename CallbackParamTraits<Args>::ForwardType...>>; + using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; + + using InvokeHelperArgs = ConcatTypeLists< + TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, + UnboundForwardArgs>; + using InvokeHelperType = + InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; + + using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; + + public: + using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, + InvokeHelperType, UnboundForwardRunType>; + using UnboundRunType = MakeFunctionType<R, UnboundArgs>; + + BindState(const Runnable& runnable, const BoundArgs&... bound_args) + : runnable_(runnable), ref_(bound_args...), bound_args_(bound_args...) {} RunnableType runnable_; + MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; + Tuple<BoundArgs...> bound_args_; private: - ~BindState() override { } - -}; - -template <typename Runnable, typename RunType, typename P1> -struct BindState<Runnable, RunType, void(P1)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<1, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1) - : runnable_(runnable), - p1_(p1) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2> -struct BindState<Runnable, RunType, void(P1, P2)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<2, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2) - : runnable_(runnable), - p1_(p1), - p2_(p2) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2, - typename P3> -struct BindState<Runnable, RunType, void(P1, P2, P3)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<3, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - typedef UnwrapTraits<P3> Bound3UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3) - : runnable_(runnable), - p1_(p1), - p2_(p2), - p3_(p3) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - P3 p3_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2, - typename P3, typename P4> -struct BindState<Runnable, RunType, void(P1, P2, P3, - P4)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<4, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - typedef UnwrapTraits<P3> Bound3UnwrapTraits; - typedef UnwrapTraits<P4> Bound4UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, - const P4& p4) - : runnable_(runnable), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2, - typename P3, typename P4, typename P5> -struct BindState<Runnable, RunType, void(P1, P2, P3, P4, - P5)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<5, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - typedef UnwrapTraits<P3> Bound3UnwrapTraits; - typedef UnwrapTraits<P4> Bound4UnwrapTraits; - typedef UnwrapTraits<P5> Bound5UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, - const P4& p4, const P5& p5) - : runnable_(runnable), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4), - p5_(p5) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; - P5 p5_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2, - typename P3, typename P4, typename P5, typename P6> -struct BindState<Runnable, RunType, void(P1, P2, P3, P4, P5, - P6)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<6, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - typedef UnwrapTraits<P3> Bound3UnwrapTraits; - typedef UnwrapTraits<P4> Bound4UnwrapTraits; - typedef UnwrapTraits<P5> Bound5UnwrapTraits; - typedef UnwrapTraits<P6> Bound6UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, - const P4& p4, const P5& p5, const P6& p6) - : runnable_(runnable), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4), - p5_(p5), - p6_(p6) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; - P5 p5_; - P6 p6_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - -}; - -template <typename Runnable, typename RunType, typename P1, typename P2, - typename P3, typename P4, typename P5, typename P6, typename P7> -struct BindState<Runnable, RunType, void(P1, P2, P3, P4, P5, P6, - P7)> : public BindStateBase { - typedef Runnable RunnableType; - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; - typedef Invoker<7, BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - - // Convenience typedefs for bound argument types. - typedef UnwrapTraits<P1> Bound1UnwrapTraits; - typedef UnwrapTraits<P2> Bound2UnwrapTraits; - typedef UnwrapTraits<P3> Bound3UnwrapTraits; - typedef UnwrapTraits<P4> Bound4UnwrapTraits; - typedef UnwrapTraits<P5> Bound5UnwrapTraits; - typedef UnwrapTraits<P6> Bound6UnwrapTraits; - typedef UnwrapTraits<P7> Bound7UnwrapTraits; - - BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, - const P4& p4, const P5& p5, const P6& p6, const P7& p7) - : runnable_(runnable), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4), - p5_(p5), - p6_(p6), - p7_(p7) { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - } - - RunnableType runnable_; - P1 p1_; - P2 p2_; - P3 p3_; - P4 p4_; - P5 p5_; - P6 p6_; - P7 p7_; - - private: - ~BindState() override { MaybeRefcount<HasIsMethodTag<Runnable>::value, - P1>::Release(p1_); } - + ~BindState() override {} }; } // namespace internal
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump deleted file mode 100644 index 0ed3ca2..0000000 --- a/base/bind_internal.h.pump +++ /dev/null
@@ -1,516 +0,0 @@ -$$ This is a pump file for generating file templates. Pump is a python -$$ script that is part of the Google Test suite of utilities. Description -$$ can be found here: -$$ -$$ http://code.google.com/p/googletest/wiki/PumpManual -$$ - -$$ See comment for MAX_ARITY in base/bind.h.pump. -$var MAX_ARITY = 7 -$range ARITY 0..MAX_ARITY - -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIND_INTERNAL_H_ -#define BASE_BIND_INTERNAL_H_ - -#include "base/bind_helpers.h" -#include "base/callback_internal.h" -#include "base/memory/raw_scoped_refptr_mismatch_checker.h" -#include "base/memory/weak_ptr.h" -#include "base/template_util.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include "base/bind_internal_win.h" -#endif - -namespace base { -namespace internal { - -// See base/callback.h for user documentation. -// -// -// CONCEPTS: -// Runnable -- A type (really a type class) that has a single Run() method -// and a RunType typedef that corresponds to the type of Run(). -// A Runnable can declare that it should treated like a method -// call by including a typedef named IsMethod. The value of -// this typedef is NOT inspected, only the existence. When a -// Runnable declares itself a method, Bind() will enforce special -// refcounting + WeakPtr handling semantics for the first -// parameter which is expected to be an object. -// Functor -- A copyable type representing something that should be called. -// All function pointers, Callback<>, and Runnables are functors -// even if the invocation syntax differs. -// RunType -- A function type (as opposed to function _pointer_ type) for -// a Run() function. Usually just a convenience typedef. -// (Bound)ArgsType -- A function type that is being (ab)used to store the -// types of set of arguments. The "return" type is always -// void here. We use this hack so that we do not need -// a new type name for each arity of type. (eg., -// BindState1, BindState2). This makes forward -// declarations and friending much much easier. -// -// Types: -// RunnableAdapter<> -- Wraps the various "function" pointer types into an -// object that adheres to the Runnable interface. -// FunctionTraits<> -- Type traits that unwrap a function signature into a -// a set of easier to use typedefs. Used mainly for -// compile time asserts. -// There are |ARITY| FunctionTraits types. -// ForceVoidReturn<> -- Helper class for translating function signatures to -// equivalent forms with a "void" return type. -// FunctorTraits<> -- Type traits used determine the correct RunType and -// RunnableType for a Functor. This is where function -// signature adapters are applied. -// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable -// type class that represents the underlying Functor. -// There are |O(1)| MakeRunnable types. -// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. -// Handle the differing syntaxes needed for WeakPtr<> support, -// and for ignoring return values. This is separate from -// Invoker to avoid creating multiple version of Invoker<> -// which grows at O(n^2) with the arity. -// Invoker<> -- Unwraps the curried parameters and executes the Runnable. -// There are |(ARITY^2 + ARITY)/2| Invoketypes. -// BindState<> -- Stores the curried parameters, and is the main entry point -// into the Bind() system, doing most of the type resolution. -// There are ARITY BindState types. - -// HasNonConstReferenceParam selects true_type when any of the parameters in -// |Sig| is a non-const reference. -// Implementation note: This non-specialized case handles zero-arity case only. -// Non-zero-arity cases should be handled by the specialization below. -template <typename Sig> -struct HasNonConstReferenceParam : false_type {}; - -// Implementation note: Select true_type if the first parameter is a non-const -// reference. Otherwise, skip the first parameter and check rest of parameters -// recursively. -template <typename R, typename T, typename... Args> -struct HasNonConstReferenceParam<R(T, Args...)> - : SelectType<is_non_const_reference<T>::value, - true_type, - HasNonConstReferenceParam<R(Args...)>>::Type {}; - -// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw -// pointer to a RefCounted type. -// Implementation note: This non-specialized case handles zero-arity case only. -// Non-zero-arity cases should be handled by the specialization below. -template <typename... Args> -struct HasRefCountedTypeAsRawPtr : false_type {}; - -// Implementation note: Select true_type if the first parameter is a raw pointer -// to a RefCounted type. Otherwise, skip the first parameter and check rest of -// parameters recursively. -template <typename T, typename... Args> -struct HasRefCountedTypeAsRawPtr<T, Args...> - : SelectType<NeedsScopedRefptrButGetsRawPtr<T>::value, - true_type, - HasRefCountedTypeAsRawPtr<Args...>>::Type {}; - -// BindsArrayToFirstArg selects true_type when |is_method| is true and the first -// item of |Args| is an array type. -// Implementation note: This non-specialized case handles !is_method case and -// zero-arity case only. Other cases should be handled by the specialization -// below. -template <bool is_method, typename... Args> -struct BindsArrayToFirstArg : false_type {}; - -template <typename T, typename... Args> -struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; - -// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except -// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. -// Implementation note: This non-specialized case handles !is_method case and -// zero-arity case only. Other cases should be handled by the specialization -// below. -template <bool is_method, typename... Args> -struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; - -template <typename T, typename... Args> -struct HasRefCountedParamAsRawPtr<true, T, Args...> - : HasRefCountedTypeAsRawPtr<Args...> {}; - -// RunnableAdapter<> -// -// The RunnableAdapter<> templates provide a uniform interface for invoking -// a function pointer, method pointer, or const method pointer. The adapter -// exposes a Run() method with an appropriate signature. Using this wrapper -// allows for writing code that supports all three pointer types without -// undue repetition. Without it, a lot of code would need to be repeated 3 -// times. -// -// For method pointers and const method pointers the first argument to Run() -// is considered to be the received of the method. This is similar to STL's -// mem_fun(). -// -// This class also exposes a RunType typedef that is the function type of the -// Run() function. -// -// If and only if the wrapper contains a method or const method pointer, an -// IsMethod typedef is exposed. The existence of this typedef (NOT the value) -// marks that the wrapper should be considered a method wrapper. - -template <typename Functor> -class RunnableAdapter; - -// Function. -template <typename R, typename... Args> -class RunnableAdapter<R(*)(Args...)> { - public: - typedef R (RunType)(Args...); - - explicit RunnableAdapter(R(*function)(Args...)) - : function_(function) { - } - - R Run(typename CallbackParamTraits<Args>::ForwardType... args) { - return function_(CallbackForward(args)...); - } - - private: - R (*function_)(Args...); -}; - -// Method. -template <typename R, typename T, typename... Args> -class RunnableAdapter<R(T::*)(Args...)> { - public: - typedef R (RunType)(T*, Args...); - typedef true_type IsMethod; - - explicit RunnableAdapter(R(T::*method)(Args...)) - : method_(method) { - } - - R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { - return (object->*method_)(CallbackForward(args)...); - } - - private: - R (T::*method_)(Args...); -}; - -// Const Method. -template <typename R, typename T, typename... Args> -class RunnableAdapter<R(T::*)(Args...) const> { - public: - typedef R (RunType)(const T*, Args...); - typedef true_type IsMethod; - - explicit RunnableAdapter(R(T::*method)(Args...) const) - : method_(method) { - } - - R Run(const T* object, - typename CallbackParamTraits<Args>::ForwardType... args) { - return (object->*method_)(CallbackForward(args)...); - } - - private: - R (T::*method_)(Args...) const; -}; - -// TODO(tzik): Remove FunctionTraits after we finish removing bind.pump. -// FunctionTraits<> -// -// Breaks a function signature apart into typedefs for easier introspection. -template <typename Sig> -struct FunctionTraits; - -$for ARITY [[ -$range ARG 1..ARITY - -template <typename R[[]] -$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> -struct FunctionTraits<R($for ARG , [[A$(ARG)]])> { - typedef R ReturnType; -$for ARG [[ - - typedef A$(ARG) A$(ARG)Type; -]] - -}; - -]] - - -// ForceVoidReturn<> -// -// Set of templates that support forcing the function return type to void. -template <typename Sig> -struct ForceVoidReturn; - -template <typename R, typename... Args> -struct ForceVoidReturn<R(Args...)> { - typedef void(RunType)(Args...); -}; - - -// FunctorTraits<> -// -// See description at top of file. -template <typename T> -struct FunctorTraits { - typedef RunnableAdapter<T> RunnableType; - typedef typename RunnableType::RunType RunType; -}; - -template <typename T> -struct FunctorTraits<IgnoreResultHelper<T> > { - typedef typename FunctorTraits<T>::RunnableType RunnableType; - typedef typename ForceVoidReturn< - typename RunnableType::RunType>::RunType RunType; -}; - -template <typename T> -struct FunctorTraits<Callback<T> > { - typedef Callback<T> RunnableType; - typedef typename Callback<T>::RunType RunType; -}; - - -// MakeRunnable<> -// -// Converts a passed in functor to a RunnableType using type inference. - -template <typename T> -typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { - return RunnableAdapter<T>(t); -} - -template <typename T> -typename FunctorTraits<T>::RunnableType -MakeRunnable(const IgnoreResultHelper<T>& t) { - return MakeRunnable(t.functor_); -} - -template <typename T> -const typename FunctorTraits<Callback<T> >::RunnableType& -MakeRunnable(const Callback<T>& t) { - DCHECK(!t.is_null()); - return t; -} - - -// InvokeHelper<> -// -// There are 3 logical InvokeHelper<> specializations: normal, void-return, -// WeakCalls. -// -// The normal type just calls the underlying runnable. -// -// We need a InvokeHelper to handle void return types in order to support -// IgnoreResult(). Normally, if the Runnable's RunType had a void return, -// the template system would just accept "return functor.Run()" ignoring -// the fact that a void function is being used with return. This piece of -// sugar breaks though when the Runnable's RunType is not void. Thus, we -// need a partial specialization to change the syntax to drop the "return" -// from the invocation call. -// -// WeakCalls similarly need special syntax that is applied to the first -// argument to check if they should no-op themselves. -template <bool IsWeakCall, typename ReturnType, typename Runnable, - typename ArgsType> -struct InvokeHelper; - -template <typename ReturnType, typename Runnable, typename... Args> -struct InvokeHelper<false, ReturnType, Runnable, - void(Args...)> { - static ReturnType MakeItSo(Runnable runnable, Args... args) { - return runnable.Run(CallbackForward(args)...); - } -}; - -template <typename Runnable, typename... Args> -struct InvokeHelper<false, void, Runnable, void(Args...)> { - static void MakeItSo(Runnable runnable, Args... args) { - runnable.Run(CallbackForward(args)...); - } -}; - -template <typename Runnable, typename BoundWeakPtr, typename... Args> -struct InvokeHelper<true, void, Runnable, void(BoundWeakPtr, Args...)> { - static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { - if (!weak_ptr.get()) { - return; - } - runnable.Run(weak_ptr.get(), CallbackForward(args)...); - } -}; - -#if !defined(_MSC_VER) - -template <typename ReturnType, typename Runnable, typename ArgsType> -struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { - // WeakCalls are only supported for functions with a void return type. - // Otherwise, the function result would be undefined if the the WeakPtr<> - // is invalidated. - COMPILE_ASSERT(is_void<ReturnType>::value, - weak_ptrs_can_only_bind_to_methods_without_return_values); -}; - -#endif - -// Invoker<> -// -// See description at the top of the file. -template <int NumBound, typename Storage, typename RunType> -struct Invoker; - -$for ARITY [[ - -$$ Number of bound arguments. -$range BOUND 0..ARITY -$for BOUND [[ - -$var UNBOUND = ARITY - BOUND -$range ARG 1..ARITY -$range BOUND_ARG 1..BOUND -$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY - -// Arity $(ARITY) -> $(UNBOUND). -template <typename StorageType, typename R[[]] -$if ARITY > 0 [[,]][[]] -$for ARG , [[typename X$(ARG)]]> -struct Invoker<$(BOUND), StorageType, R($for ARG , [[X$(ARG)]])> { - typedef R(RunType)(BindStateBase*[[]] -$if UNBOUND != 0 [[, ]] -$for UNBOUND_ARG , [[typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType]]); - - typedef R(UnboundRunType)($for UNBOUND_ARG , [[X$(UNBOUND_ARG)]]); - - static R Run(BindStateBase* base[[]] -$if UNBOUND != 0 [[, ]][[]] -$for UNBOUND_ARG , [[ -typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG) -]][[]] -) { - StorageType* storage = static_cast<StorageType*>(base); - - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. -$for BOUND_ARG -[[ - - typedef typename StorageType::Bound$(BOUND_ARG)UnwrapTraits Bound$(BOUND_ARG)UnwrapTraits; -]] - - -$for BOUND_ARG -[[ - - typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType x$(BOUND_ARG) = - Bound$(BOUND_ARG)UnwrapTraits::Unwrap(storage->p$(BOUND_ARG)_); -]] - - return InvokeHelper<StorageType::IsWeakCall::value, R, - typename StorageType::RunnableType, - void( -$for BOUND_ARG , [[ -typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType -]] - -$if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]] - -$for UNBOUND_ARG , [[ -typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG) -]] -)> - ::MakeItSo(storage->runnable_ -$if ARITY > 0[[, ]] $for ARG , [[CallbackForward(x$(ARG))]]); - } -}; - -]] $$ for BOUND -]] $$ for ARITY - - -// BindState<> -// -// This stores all the state passed into Bind() and is also where most -// of the template resolution magic occurs. -// -// Runnable is the functor we are binding arguments to. -// RunType is type of the Run() function that the Invoker<> should use. -// Normally, this is the same as the RunType of the Runnable, but it can -// be different if an adapter like IgnoreResult() has been used. -// -// BoundArgsType contains the storage type for all the bound arguments by -// (ab)using a function type. -template <typename Runnable, typename RunType, typename BoundArgsType> -struct BindState; - -$for ARITY [[ -$range ARG 1..ARITY - -template <typename Runnable, typename RunType[[]] -$if ARITY > 0[[, ]] $for ARG , [[typename P$(ARG)]]> -struct BindState<Runnable, RunType, void($for ARG , [[P$(ARG)]])> : public BindStateBase { - typedef Runnable RunnableType; - -$if ARITY > 0 [[ - typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; -]] $else [[ - typedef false_type IsWeakCall; -]] - - typedef Invoker<$(ARITY), BindState, RunType> InvokerType; - typedef typename InvokerType::UnboundRunType UnboundRunType; - -$if ARITY > 0 [[ - - // Convenience typedefs for bound argument types. - -$for ARG [[ - typedef UnwrapTraits<P$(ARG)> Bound$(ARG)UnwrapTraits; - -]] $$ for ARG - - -]] $$ if ARITY > 0 - -$$ The extra [[ ]] is needed to massage spacing. Silly pump.py. -[[ ]]$if ARITY == 0 [[explicit ]]BindState(const Runnable& runnable -$if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]]) - : runnable_(runnable)[[]] -$if ARITY == 0 [[ - { - -]] $else [[ -, $for ARG , [[ - - p$(ARG)_(p$(ARG)) -]] { - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); - -]] - } - - RunnableType runnable_; - -$for ARG [[ - P$(ARG) p$(ARG)_; - -]] - - private: - ~BindState() override { -$if ARITY > 0 [[ - MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::Release(p1_); -]] - } - -}; - -]] $$ for ARITY - -} // namespace internal -} // namespace base - -#endif // BASE_BIND_INTERNAL_H_
diff --git a/base/bind_unittest.nc b/base/bind_unittest.nc index 33b5f5c..25963867 100644 --- a/base/bind_unittest.nc +++ b/base/bind_unittest.nc
@@ -190,7 +190,7 @@ weak_ptr_with_non_void_return_type.Run(); } -#elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no viable conversion from 'Callback<typename internal::BindState<typename internal::FunctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<void \(\*\)\(int\)>::RunType, void \(\)>::UnboundRunType>' to 'Callback<void \(\)>'"] +#elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no viable conversion from 'Callback<typename internal::BindState<typename internal::FunctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<void \(\*\)\(int\)>::RunType, internal::TypeList<> >::UnboundRunType>' to 'Callback<void \(\)>'"] // Bind result cannot be assigned to Callbacks with a mismatching type. void WontCompile() {
diff --git a/base/chromeos/memory_pressure_observer_chromeos.cc b/base/chromeos/memory_pressure_observer_chromeos.cc index 8112c761..5691eb8 100644 --- a/base/chromeos/memory_pressure_observer_chromeos.cc +++ b/base/chromeos/memory_pressure_observer_chromeos.cc
@@ -5,6 +5,7 @@ #include "base/chromeos/memory_pressure_observer_chromeos.h" #include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" #include "base/process/process_metrics.h" #include "base/time/time.h" @@ -29,6 +30,16 @@ const int kAggressiveMemoryPressureModerateThresholdPercent = 35; const int kAggressiveMemoryPressureCriticalThresholdPercent = 70; +// The possible state for memory pressure level. The values should be in line +// with values in MemoryPressureListener::MemoryPressureLevel and should be +// updated if more memory pressure levels are introduced. +enum MemoryPressureLevelUMA { + MEMORY_PRESSURE_LEVEL_NONE = 0, + MEMORY_PRESSURE_LEVEL_MODERATE, + MEMORY_PRESSURE_LEVEL_CRITICAL, + NUM_MEMORY_PRESSURE_LEVELS +}; + // Converts a |MemoryPressureThreshold| value into a used memory percentage for // the moderate pressure event. int GetModerateMemoryThresholdInPercent( @@ -92,7 +103,8 @@ void MemoryPressureObserverChromeOS::StartObserving() { timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), - Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, + Bind(&MemoryPressureObserverChromeOS:: + CheckMemoryPressureAndRecordStatistics, weak_ptr_factory_.GetWeakPtr())); } @@ -101,6 +113,28 @@ timer_.Stop(); } +void MemoryPressureObserverChromeOS::CheckMemoryPressureAndRecordStatistics() { + CheckMemoryPressure(); + + // Record UMA histogram statistics for the current memory pressure level. + MemoryPressureLevelUMA memory_pressure_level_uma(MEMORY_PRESSURE_LEVEL_NONE); + switch (current_memory_pressure_level_) { + case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: + memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_NONE; + break; + case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: + memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_MODERATE; + break; + case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: + memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_CRITICAL; + break; + } + + UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel", + memory_pressure_level_uma, + NUM_MEMORY_PRESSURE_LEVELS); +} + void MemoryPressureObserverChromeOS::CheckMemoryPressure() { MemoryPressureListener::MemoryPressureLevel old_pressure = current_memory_pressure_level_;
diff --git a/base/chromeos/memory_pressure_observer_chromeos.h b/base/chromeos/memory_pressure_observer_chromeos.h index 739b795..9af07d4 100644 --- a/base/chromeos/memory_pressure_observer_chromeos.h +++ b/base/chromeos/memory_pressure_observer_chromeos.h
@@ -76,6 +76,10 @@ // critical pressure levels. void CheckMemoryPressure(); + // The function periodically checks the memory pressure changes and records + // the UMA histogram statistics for the current memory pressure level. + void CheckMemoryPressureAndRecordStatistics(); + // Get the memory pressure in percent (virtual for testing). virtual int GetUsedMemoryInPercent();
diff --git a/base/files/file_path_watcher_win.cc b/base/files/file_path_watcher_win.cc index 73f9cfb..63e5480 100644 --- a/base/files/file_path_watcher_win.cc +++ b/base/files/file_path_watcher_win.cc
@@ -149,7 +149,8 @@ void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("FilePathWatcherImpl_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 FilePathWatcherImpl::OnObjectSignaled")); DCHECK(object == handle_); // Make sure we stay alive through the body of this function.
diff --git a/base/i18n/time_formatting.cc b/base/i18n/time_formatting.cc index 917ba43b..15b34a3 100644 --- a/base/i18n/time_formatting.cc +++ b/base/i18n/time_formatting.cc
@@ -106,6 +106,12 @@ return TimeFormat(formatter.get(), time); } +string16 TimeFormatShortDateAndTimeWithTimeZone(const Time& time) { + scoped_ptr<icu::DateFormat> formatter(icu::DateFormat::createDateTimeInstance( + icu::DateFormat::kShort, icu::DateFormat::kLong)); + return TimeFormat(formatter.get(), time); +} + string16 TimeFormatFriendlyDateAndTime(const Time& time) { scoped_ptr<icu::DateFormat> formatter( icu::DateFormat::createDateTimeInstance(icu::DateFormat::kFull));
diff --git a/base/i18n/time_formatting.h b/base/i18n/time_formatting.h index 226d1a91..2053c0b4 100644 --- a/base/i18n/time_formatting.h +++ b/base/i18n/time_formatting.h
@@ -48,6 +48,11 @@ // Returns a numeric date and time such as "12/13/52 2:44:30 PM". BASE_I18N_EXPORT string16 TimeFormatShortDateAndTime(const Time& time); +// Returns a numeric date and time with time zone such as +// "12/13/52 2:44:30 PM PST". +BASE_I18N_EXPORT string16 +TimeFormatShortDateAndTimeWithTimeZone(const Time& time); + // Formats a time in a friendly sentence format, e.g. // "Monday, March 6, 2008 2:44:30 PM". BASE_I18N_EXPORT string16 TimeFormatFriendlyDateAndTime(const Time& time);
diff --git a/base/i18n/time_formatting_unittest.cc b/base/i18n/time_formatting_unittest.cc index 0c2a6e6..4739b62a 100644 --- a/base/i18n/time_formatting_unittest.cc +++ b/base/i18n/time_formatting_unittest.cc
@@ -5,10 +5,13 @@ #include "base/i18n/time_formatting.h" #include "base/i18n/rtl.h" +#include "base/memory/scoped_ptr.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/icu/source/common/unicode/uversion.h" +#include "third_party/icu/source/i18n/unicode/calendar.h" +#include "third_party/icu/source/i18n/unicode/timezone.h" namespace base { namespace { @@ -18,6 +21,13 @@ 15, 42, 7, 0 // 15:42:07.000 }; +base::string16 GetShortTimeZone() { + scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault()); + icu::UnicodeString name; + zone->getDisplayName(true, icu::TimeZone::SHORT, name); + return base::string16(name.getBuffer(), name.length()); +} + TEST(TimeFormattingTest, TimeFormatTimeOfDayDefault12h) { // Test for a locale defaulted to 12h clock. // As an instance, we use third_party/icu/source/data/locales/en.txt. @@ -129,6 +139,8 @@ EXPECT_EQ(ASCIIToUTF16("4/30/11, 3:42:07 PM"), TimeFormatShortDateAndTime(time)); + EXPECT_EQ(ASCIIToUTF16("4/30/11, 3:42:07 PM ") + GetShortTimeZone(), + TimeFormatShortDateAndTimeWithTimeZone(time)); EXPECT_EQ(ASCIIToUTF16("Saturday, April 30, 2011 at 3:42:07 PM"), TimeFormatFriendlyDateAndTime(time)); @@ -148,6 +160,8 @@ EXPECT_EQ(ASCIIToUTF16("30/04/2011"), TimeFormatShortDateNumeric(time)); EXPECT_EQ(ASCIIToUTF16("30/04/2011 15:42:07"), TimeFormatShortDateAndTime(time)); + EXPECT_EQ(ASCIIToUTF16("30/04/2011 15:42:07 ") + GetShortTimeZone(), + TimeFormatShortDateAndTimeWithTimeZone(time)); EXPECT_EQ(ASCIIToUTF16("Saturday, 30 April 2011 15:42:07"), TimeFormatFriendlyDateAndTime(time)); EXPECT_EQ(ASCIIToUTF16("Saturday, 30 April 2011"),
diff --git a/base/json/json_string_value_serializer.cc b/base/json/json_string_value_serializer.cc index 59f030d..b626640 100644 --- a/base/json/json_string_value_serializer.cc +++ b/base/json/json_string_value_serializer.cc
@@ -10,6 +10,21 @@ using base::Value; +JSONStringValueSerializer::JSONStringValueSerializer(std::string* json_string) + : json_string_(json_string), + json_string_readonly_(*json_string), + pretty_print_(false), + allow_trailing_comma_(false) { +} + +JSONStringValueSerializer::JSONStringValueSerializer( + const base::StringPiece& json_string) + : json_string_(nullptr), + json_string_readonly_(json_string), + pretty_print_(false), + allow_trailing_comma_(false) { +} + JSONStringValueSerializer::~JSONStringValueSerializer() {} bool JSONStringValueSerializer::Serialize(const Value& root) { @@ -23,7 +38,7 @@ bool JSONStringValueSerializer::SerializeInternal(const Value& root, bool omit_binary_values) { - if (!json_string_ || initialized_with_const_string_) + if (!json_string_) return false; int options = 0; @@ -37,10 +52,7 @@ Value* JSONStringValueSerializer::Deserialize(int* error_code, std::string* error_str) { - if (!json_string_) - return NULL; - - return base::JSONReader::ReadAndReturnError(*json_string_, + return base::JSONReader::ReadAndReturnError(json_string_readonly_, allow_trailing_comma_ ? base::JSON_ALLOW_TRAILING_COMMAS : base::JSON_PARSE_RFC, error_code, error_str);
diff --git a/base/json/json_string_value_serializer.h b/base/json/json_string_value_serializer.h index 6435051..7f99bc9 100644 --- a/base/json/json_string_value_serializer.h +++ b/base/json/json_string_value_serializer.h
@@ -10,28 +10,20 @@ #include "base/base_export.h" #include "base/basictypes.h" #include "base/files/file_path.h" +#include "base/strings/string_piece.h" #include "base/values.h" class BASE_EXPORT JSONStringValueSerializer : public base::ValueSerializer { public: - // json_string is the string that will be source of the deserialization + // |json_string| is the string that will be source of the deserialization // or the destination of the serialization. The caller of the constructor - // retains ownership of the string. - explicit JSONStringValueSerializer(std::string* json_string) - : json_string_(json_string), - initialized_with_const_string_(false), - pretty_print_(false), - allow_trailing_comma_(false) { - } + // retains ownership of the string. |json_string| must not be null. + explicit JSONStringValueSerializer(std::string* json_string); - // This version allows initialization with a const string reference for - // deserialization only. - explicit JSONStringValueSerializer(const std::string& json_string) - : json_string_(&const_cast<std::string&>(json_string)), - initialized_with_const_string_(true), - pretty_print_(false), - allow_trailing_comma_(false) { - } + // This version allows initialization with a StringPiece for deserialization + // only. Retains a reference to the contents of |json_string|, so the data + // must outlive the JSONStringValueSerializer. + explicit JSONStringValueSerializer(const base::StringPiece& json_string); ~JSONStringValueSerializer() override; @@ -46,7 +38,7 @@ // Attempt to deserialize the data structure encoded in the string passed // in to the constructor into a structure of Value objects. If the return - // value is NULL, and if |error_code| is non-null, |error_code| will + // value is null, and if |error_code| is non-null, |error_code| will // contain an integer error code (a JsonParseError in this case). // If |error_message| is non-null, it will be filled in with a formatted // error message including the location of the error if appropriate. @@ -64,8 +56,12 @@ private: bool SerializeInternal(const base::Value& root, bool omit_binary_values); + // String for writing. Owned by the caller of the constructor. Will be null if + // the serializer was initialized with a const string. std::string* json_string_; - bool initialized_with_const_string_; + // String for reading. Data is owned by the caller of the constructor. If + // |json_string_| is non-null, this is a view onto |json_string_|. + base::StringPiece json_string_readonly_; bool pretty_print_; // If true, serialization will span multiple lines. // If true, deserialization will allow trailing commas. bool allow_trailing_comma_;
diff --git a/base/json/json_value_serializer_unittest.cc b/base/json/json_value_serializer_unittest.cc index e3c349c..d2a84de 100644 --- a/base/json/json_value_serializer_unittest.cc +++ b/base/json/json_value_serializer_unittest.cc
@@ -12,6 +12,7 @@ #include "base/json/json_writer.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -42,6 +43,20 @@ "\t\"compound\": { \"a\": 1, \"b\": 2, },\n" "}\n"; +// kProperJSON with a few misc characters at the begin and end. +const char kProperJSONPadded[] = + ")]}'\n" + "{\n" + " \"compound\": {\n" + " \"a\": 1,\n" + " \"b\": 2\n" + " },\n" + " \"some_String\": \"1337\",\n" + " \"some_int\": 42,\n" + " \"the_list\": [ \"val1\", \"val2\" ]\n" + "}\n" + "?!ab\n"; + const char kWinLineEnds[] = "\r\n"; const char kLinuxLineEnds[] = "\n"; @@ -74,7 +89,43 @@ // Test proper JSON [de]serialization from string is working. TEST(JSONValueSerializerTest, ReadProperJSONFromString) { // Try to deserialize it through the serializer. + JSONStringValueSerializer str_deserializer(kProperJSON); + + int error_code = 0; + std::string error_message; + scoped_ptr<Value> value( + str_deserializer.Deserialize(&error_code, &error_message)); + ASSERT_TRUE(value.get()); + ASSERT_EQ(0, error_code); + ASSERT_TRUE(error_message.empty()); + // Verify if the same JSON is still there. + CheckJSONIsStillTheSame(*value); +} + +// Test proper JSON deserialization from a string pointer is working. +TEST(JSONValueSerializerTest, ReadProperJSONFromStringPointer) { + // Try to deserialize a string pointer through the serializer. (This exercises + // a separate code path to passing a StringPiece.) std::string proper_json(kProperJSON); + JSONStringValueSerializer str_deserializer(&proper_json); + + int error_code = 0; + std::string error_message; + scoped_ptr<Value> value( + str_deserializer.Deserialize(&error_code, &error_message)); + ASSERT_TRUE(value.get()); + ASSERT_EQ(0, error_code); + ASSERT_TRUE(error_message.empty()); + // Verify if the same JSON is still there. + CheckJSONIsStillTheSame(*value); +} + +// Test proper JSON deserialization from a StringPiece substring. +TEST(JSONValueSerializerTest, ReadProperJSONFromStringPiece) { + // Create a StringPiece for the substring of kProperJSONPadded that matches + // kProperJSON. + base::StringPiece proper_json(kProperJSONPadded); + proper_json = proper_json.substr(5, proper_json.length() - 10); JSONStringValueSerializer str_deserializer(proper_json); int error_code = 0; @@ -92,8 +143,7 @@ // the proper flag for that is set. TEST(JSONValueSerializerTest, ReadJSONWithTrailingCommasFromString) { // Try to deserialize it through the serializer. - std::string proper_json(kProperJSONWithCommas); - JSONStringValueSerializer str_deserializer(proper_json); + JSONStringValueSerializer str_deserializer(kProperJSONWithCommas); int error_code = 0; std::string error_message; @@ -165,9 +215,9 @@ } TEST(JSONValueSerializerTest, Roundtrip) { - const std::string original_serialization = + static const char kOriginalSerialization[] = "{\"bool\":true,\"double\":3.14,\"int\":42,\"list\":[1,2],\"null\":null}"; - JSONStringValueSerializer serializer(original_serialization); + JSONStringValueSerializer serializer(kOriginalSerialization); scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); ASSERT_TRUE(root.get()); ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); @@ -198,7 +248,7 @@ std::string test_serialization; JSONStringValueSerializer mutable_serializer(&test_serialization); ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); - ASSERT_EQ(original_serialization, test_serialization); + ASSERT_EQ(kOriginalSerialization, test_serialization); mutable_serializer.set_pretty_print(true); ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); @@ -273,15 +323,15 @@ string16 test(WideToUTF16(L"\x7F51\x9875")); root.SetString("web", test); - std::string expected = "{\"web\":\"\xE7\xBD\x91\xE9\xA1\xB5\"}"; + static const char kExpected[] = "{\"web\":\"\xE7\xBD\x91\xE9\xA1\xB5\"}"; std::string actual; JSONStringValueSerializer serializer(&actual); ASSERT_TRUE(serializer.Serialize(root)); - ASSERT_EQ(expected, actual); + ASSERT_EQ(kExpected, actual); // escaped ascii text -> json - JSONStringValueSerializer deserializer(expected); + JSONStringValueSerializer deserializer(kExpected); scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); ASSERT_TRUE(deserial_root.get()); DictionaryValue* dict_root = @@ -297,15 +347,15 @@ string16 test(WideToUTF16(L"\x01\x02")); root.SetString("test", test); - std::string expected = "{\"test\":\"\\u0001\\u0002\"}"; + static const char kExpected[] = "{\"test\":\"\\u0001\\u0002\"}"; std::string actual; JSONStringValueSerializer serializer(&actual); ASSERT_TRUE(serializer.Serialize(root)); - ASSERT_EQ(expected, actual); + ASSERT_EQ(kExpected, actual); // escaped ascii text -> json - JSONStringValueSerializer deserializer(expected); + JSONStringValueSerializer deserializer(kExpected); scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); ASSERT_TRUE(deserial_root.get()); DictionaryValue* dict_root = @@ -315,8 +365,8 @@ ASSERT_EQ(test, test_value); // Test converting escaped regular chars - std::string escaped_chars = "{\"test\":\"\\u0067\\u006f\"}"; - JSONStringValueSerializer deserializer2(escaped_chars); + static const char kEscapedChars[] = "{\"test\":\"\\u0067\\u006f\"}"; + JSONStringValueSerializer deserializer2(kEscapedChars); deserial_root.reset(deserializer2.Deserialize(NULL, NULL)); ASSERT_TRUE(deserial_root.get()); dict_root = static_cast<DictionaryValue*>(deserial_root.get()); @@ -327,12 +377,12 @@ TEST(JSONValueSerializerTest, AllowTrailingComma) { scoped_ptr<Value> root; scoped_ptr<Value> root_expected; - std::string test_with_commas("{\"key\": [true,],}"); - std::string test_no_commas("{\"key\": [true]}"); + static const char kTestWithCommas[] = "{\"key\": [true,],}"; + static const char kTestNoCommas[] = "{\"key\": [true]}"; - JSONStringValueSerializer serializer(test_with_commas); + JSONStringValueSerializer serializer(kTestWithCommas); serializer.set_allow_trailing_comma(true); - JSONStringValueSerializer serializer_expected(test_no_commas); + JSONStringValueSerializer serializer_expected(kTestNoCommas); root.reset(serializer.Deserialize(NULL, NULL)); ASSERT_TRUE(root.get()); root_expected.reset(serializer_expected.Deserialize(NULL, NULL));
diff --git a/base/logging.h b/base/logging.h index aa243a9e..cc0a5aa 100644 --- a/base/logging.h +++ b/base/logging.h
@@ -350,7 +350,7 @@ ((verboselevel) <= ::logging::GetVlogLevel(__FILE__)) // Helper macro which avoids evaluating the arguments to a stream if -// the condition doesn't hold. +// the condition doesn't hold. Condition is evaluated once and only once. #define LAZY_STREAM(stream, condition) \ !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
diff --git a/base/memory/discardable_memory_ashmem.h b/base/memory/discardable_memory_ashmem.h index c1cc077..100655be 100644 --- a/base/memory/discardable_memory_ashmem.h +++ b/base/memory/discardable_memory_ashmem.h
@@ -25,20 +25,20 @@ DiscardableMemoryAshmemAllocator* allocator, DiscardableMemoryManager* manager); - virtual ~DiscardableMemoryAshmem(); + ~DiscardableMemoryAshmem() override; bool Initialize(); // Overridden from DiscardableMemory: - virtual DiscardableMemoryLockStatus Lock() override; - virtual void Unlock() override; - virtual void* Memory() const override; + DiscardableMemoryLockStatus Lock() override; + void Unlock() override; + void* Memory() const override; // Overridden from internal::DiscardableMemoryManagerAllocation: - virtual bool AllocateAndAcquireLock() override; - virtual void ReleaseLock() override; - virtual void Purge() override; - virtual bool IsMemoryResident() const override; + bool AllocateAndAcquireLock() override; + void ReleaseLock() override; + void Purge() override; + bool IsMemoryResident() const override; private: const size_t bytes_;
diff --git a/base/memory/scoped_open_process.h b/base/memory/scoped_open_process.h deleted file mode 100644 index 8bb19e24..0000000 --- a/base/memory/scoped_open_process.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_MEMORY_SCOPED_OPEN_PROCESS_H_ -#define BASE_MEMORY_SCOPED_OPEN_PROCESS_H_ - -#include "base/process/process_handle.h" - -namespace base { - -// A class that opens a process from its process id and closes it when the -// instance goes out of scope. -class ScopedOpenProcess { - public: - ScopedOpenProcess() : handle_(kNullProcessHandle) { - } - - // Automatically close the process. - ~ScopedOpenProcess() { - Close(); - } - - // Open a new process by pid. Closes any previously opened process (even if - // opening the new one fails). - bool Open(ProcessId pid) { - Close(); - return OpenProcessHandle(pid, &handle_); - } - - // Close the previously opened process. - void Close() { - if (handle_ == kNullProcessHandle) - return; - - CloseProcessHandle(handle_); - handle_ = kNullProcessHandle; - } - - ProcessHandle handle() const { return handle_; } - - private: - ProcessHandle handle_; - DISALLOW_COPY_AND_ASSIGN(ScopedOpenProcess); -}; -} // namespace base - -#endif // BASE_MEMORY_SCOPED_OPEN_PROCESS_H_
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc index 07de4a15..c1ce939 100644 --- a/base/message_loop/incoming_task_queue.cc +++ b/base/message_loop/incoming_task_queue.cc
@@ -17,11 +17,12 @@ namespace { -// Delays larger than this many microseconds are often bogus, and a warning -// should be emitted in debug builds to warn developers. -// http://crbug.com/450045 -const int kTaskDelayWarningThresholdInMicroseconds = - std::numeric_limits<int>::max() / 2; // A little less than 18 minutes. +#ifndef NDEBUG +// Delays larger than this are often bogus, and a warning should be emitted in +// debug builds to warn developers. http://crbug.com/450045 +const int kTaskDelayWarningThresholdInSeconds = + 14 * 24 * 60 * 60; // 14 days. +#endif // Returns true if MessagePump::ScheduleWork() must be called one // time for every task that is added to the MessageLoop incoming queue. @@ -52,9 +53,9 @@ TimeDelta delay, bool nestable) { DLOG_IF(WARNING, - delay.InMicroseconds() > kTaskDelayWarningThresholdInMicroseconds) - << "Requesting super-long task delay period of " << delay.InMicroseconds() - << " usec from here: " << from_here.ToString(); + delay.InSeconds() > kTaskDelayWarningThresholdInSeconds) + << "Requesting super-long task delay period of " << delay.InSeconds() + << " seconds from here: " << from_here.ToString(); AutoLock locked(incoming_queue_lock_); PendingTask pending_task(
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h index 9b4540f..d48050d 100644 --- a/base/message_loop/message_pump_android.h +++ b/base/message_loop/message_pump_android.h
@@ -22,12 +22,12 @@ class BASE_EXPORT MessagePumpForUI : public MessagePump { public: MessagePumpForUI(); - virtual ~MessagePumpForUI(); + ~MessagePumpForUI() override; - virtual void Run(Delegate* delegate) override; - virtual void Quit() override; - virtual void ScheduleWork() override; - virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; + void Run(Delegate* delegate) override; + void Quit() override; + void ScheduleWork() override; + void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; virtual void Start(Delegate* delegate);
diff --git a/base/process/kill_win.cc b/base/process/kill_win.cc index 0a0c99c..4d7225f 100644 --- a/base/process/kill_win.cc +++ b/base/process/kill_win.cc
@@ -73,7 +73,8 @@ void TimerExpiredTask::OnObjectSignaled(HANDLE object) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("TimerExpiredTask_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TimerExpiredTask::OnObjectSignaled")); process_.Close(); }
diff --git a/base/process/process.h b/base/process/process.h index 70aca6d..77d2bce93 100644 --- a/base/process/process.h +++ b/base/process/process.h
@@ -49,6 +49,9 @@ // Returns an object for the current process. static Process Current(); + // Returns a Process for the given |pid|. + static Process Open(ProcessId pid); + // Returns a Process for the given |pid|. On Windows the handle is opened // with more access rights and must only be used by trusted code (can read the // address space and duplicate handles).
diff --git a/base/process/process_handle.h b/base/process/process_handle.h index 976552c..c99ea15d 100644 --- a/base/process/process_handle.h +++ b/base/process/process_handle.h
@@ -40,9 +40,7 @@ // Returns the ProcessHandle of the current process. BASE_EXPORT ProcessHandle GetCurrentProcessHandle(); -// Converts a PID to a process handle. This handle must be closed by -// CloseProcessHandle when you are done with it. Returns true on success. -BASE_EXPORT bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle); + // Closes the process handle opened by OpenProcessHandle. BASE_EXPORT void CloseProcessHandle(ProcessHandle process);
diff --git a/base/process/process_handle_posix.cc b/base/process/process_handle_posix.cc index 3d92300..a661ecd8 100644 --- a/base/process/process_handle_posix.cc +++ b/base/process/process_handle_posix.cc
@@ -16,13 +16,6 @@ return GetCurrentProcId(); } -bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) { - // On Posix platforms, process handles are the same as PIDs, so we - // don't need to do anything. - *handle = pid; - return true; -} - void CloseProcessHandle(ProcessHandle process) { // See OpenProcessHandle, nothing to do. return;
diff --git a/base/process/process_handle_win.cc b/base/process/process_handle_win.cc index 468331163..30b20665 100644 --- a/base/process/process_handle_win.cc +++ b/base/process/process_handle_win.cc
@@ -20,22 +20,6 @@ return ::GetCurrentProcess(); } -bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) { - // We try to limit privileges granted to the handle. If you need this - // for test code, consider using OpenPrivilegedProcessHandle instead of - // adding more privileges here. - ProcessHandle result = OpenProcess(PROCESS_TERMINATE | - PROCESS_QUERY_INFORMATION | - SYNCHRONIZE, - FALSE, pid); - - if (result == NULL) - return false; - - *handle = result; - return true; -} - void CloseProcessHandle(ProcessHandle process) { CloseHandle(process); }
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc index e8db571..dd37236 100644 --- a/base/process/process_metrics_linux.cc +++ b/base/process/process_metrics_linux.cc
@@ -399,17 +399,36 @@ return meminfo.total - meminfo.free - meminfo.buffers - meminfo.cached; } -// Exposed for testing. int ParseProcStatCPU(const std::string& input) { - std::vector<std::string> proc_stats; - if (!internal::ParseProcStats(input, &proc_stats)) + // |input| may be empty if the process disappeared somehow. + // e.g. http://crbug.com/145811. + if (input.empty()) return -1; - if (proc_stats.size() <= internal::VM_STIME) + size_t start = input.find_last_of(')'); + if (start == input.npos) return -1; - int utime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_UTIME); - int stime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_STIME); - return utime + stime; + + // Number of spaces remaining until reaching utime's index starting after the + // last ')'. + int num_spaces_remaining = internal::VM_UTIME - 1; + + size_t i = start; + while ((i = input.find(' ', i + 1)) != input.npos) { + // Validate the assumption that there aren't any contiguous spaces + // in |input| before utime. + DCHECK_NE(input[i - 1], ' '); + if (--num_spaces_remaining == 0) { + int utime = 0; + int stime = 0; + if (sscanf(&input.data()[i], "%d %d", &utime, &stime) != 2) + return -1; + + return utime + stime; + } + } + + return -1; } const char kProcSelfExe[] = "/proc/self/exe";
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc index 69f5e83..dbfaa1a 100644 --- a/base/process/process_metrics_unittest.cc +++ b/base/process/process_metrics_unittest.cc
@@ -323,6 +323,17 @@ "3221224832 3221224344 3086339742 0 0 0 0 0 0 0 17 0 0 0"; EXPECT_EQ(0, base::ParseProcStatCPU(kSelfStat)); + + // Some weird long-running process with a weird name that I created for the + // purposes of this test. + const char kWeirdNameStat[] = "26115 (Hello) You ())) ) R 24614 26115 24614" + " 34839 26115 4218880 227 0 0 0 " + "5186 11 0 0 " + "20 0 1 0 36933953 4296704 90 18446744073709551615 4194304 4196116 " + "140735857761568 140735857761160 4195644 0 0 0 0 0 0 0 17 14 0 0 0 0 0 " + "6295056 6295616 16519168 140735857770710 140735857770737 " + "140735857770737 140735857774557 0"; + EXPECT_EQ(5186 + 11, base::ParseProcStatCPU(kWeirdNameStat)); } #endif // defined(OS_LINUX) || defined(OS_ANDROID)
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc index 5d7007c..bc2f3f8 100644 --- a/base/process/process_posix.cc +++ b/base/process/process_posix.cc
@@ -14,7 +14,6 @@ namespace base { Process::Process(ProcessHandle handle) : process_(handle) { - CHECK_NE(handle, GetCurrentProcessHandle()); } Process::Process(RValue other) @@ -32,19 +31,22 @@ // static Process Process::Current() { - Process process; - process.process_ = GetCurrentProcessHandle(); - return process.Pass(); + return Process(GetCurrentProcessHandle()); +} + +// static +Process Process::Open(ProcessId pid) { + if (pid == GetCurrentProcId()) + return Current(); + + // On POSIX process handles are the same as PIDs. + return Process(pid); } // static Process Process::OpenWithExtraPriviles(ProcessId pid) { - if (pid == GetCurrentProcId()) - return Current(); - - // On POSIX process handles are the same as PIDs, and there are no privileges - // to set. - return Process(pid); + // On POSIX there are no privileges to set. + return Open(pid); } // static
diff --git a/base/process/process_win.cc b/base/process/process_win.cc index 0107015..4e600f94 100644 --- a/base/process/process_win.cc +++ b/base/process/process_win.cc
@@ -47,10 +47,14 @@ } // static +Process Process::Open(ProcessId pid) { + return Process(::OpenProcess(kBasicProcessAccess, FALSE, pid)); +} + +// static Process Process::OpenWithExtraPriviles(ProcessId pid) { DWORD access = kBasicProcessAccess | PROCESS_DUP_HANDLE | PROCESS_VM_READ; - ProcessHandle handle = ::OpenProcess(access, FALSE, pid); - return Process(handle); + return Process(::OpenProcess(access, FALSE, pid)); } // static
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h index 602ba273..61eda20 100644 --- a/base/strings/string_util_win.h +++ b/base/strings/string_util_win.h
@@ -34,12 +34,9 @@ inline int vsnprintf(char* buffer, size_t size, const char* format, va_list arguments) { - int length = _vsprintf_p(buffer, size, format, arguments); - if (length < 0) { - if (size > 0) - buffer[0] = 0; - return _vscprintf_p(format, arguments); - } + int length = vsnprintf_s(buffer, size, size - 1, format, arguments); + if (length < 0) + return _vscprintf(format, arguments); return length; } @@ -47,12 +44,9 @@ const wchar_t* format, va_list arguments) { DCHECK(IsWprintfFormatPortable(format)); - int length = _vswprintf_p(buffer, size, format, arguments); - if (length < 0) { - if (size > 0) - buffer[0] = 0; - return _vscwprintf_p(format, arguments); - } + int length = _vsnwprintf_s(buffer, size, size - 1, format, arguments); + if (length < 0) + return _vscwprintf(format, arguments); return length; }
diff --git a/base/strings/stringprintf_unittest.cc b/base/strings/stringprintf_unittest.cc index 32174786..c49637c 100644 --- a/base/strings/stringprintf_unittest.cc +++ b/base/strings/stringprintf_unittest.cc
@@ -163,19 +163,6 @@ } #endif -// Test that the positional parameters work. -TEST(StringPrintfTest, PositionalParameters) { - std::string out; - SStringPrintf(&out, "%1$s %1$s", "test"); - EXPECT_STREQ("test test", out.c_str()); - -#if defined(OS_WIN) - std::wstring wout; - SStringPrintf(&wout, L"%1$ls %1$ls", L"test"); - EXPECT_STREQ(L"test test", wout.c_str()); -#endif -} - // Test that StringPrintf and StringAppendV do not change errno. TEST(StringPrintfTest, StringPrintfErrno) { errno = 1;
diff --git a/base/synchronization/waitable_event_watcher_win.cc b/base/synchronization/waitable_event_watcher_win.cc index f5218f1..a04a435a 100644 --- a/base/synchronization/waitable_event_watcher_win.cc +++ b/base/synchronization/waitable_event_watcher_win.cc
@@ -39,7 +39,8 @@ void WaitableEventWatcher::OnObjectSignaled(HANDLE h) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("WaitableEventWatche_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 WaitableEventWatcher::OnObjectSignaled")); WaitableEvent* event = event_; EventCallback callback = callback_;
diff --git a/base/test/test_support_android.cc b/base/test/test_support_android.cc index eeab9ee..11a0871 100644 --- a/base/test/test_support_android.cc +++ b/base/test/test_support_android.cc
@@ -72,14 +72,14 @@ // The MessagePumpForUI implementation for test purpose. class MessagePumpForUIStub : public base::MessagePumpForUI { - virtual ~MessagePumpForUIStub() {} + ~MessagePumpForUIStub() override {} - virtual void Start(base::MessagePump::Delegate* delegate) override { + void Start(base::MessagePump::Delegate* delegate) override { NOTREACHED() << "The Start() method shouldn't be called in test, using" " Run() method should be used."; } - virtual void Run(base::MessagePump::Delegate* delegate) override { + void Run(base::MessagePump::Delegate* delegate) override { // The following was based on message_pump_glib.cc, except we're using a // WaitableEvent since there are no native message loop to use. RunState state(delegate, g_state ? g_state->run_depth + 1 : 1); @@ -119,16 +119,11 @@ g_state = previous_state; } - virtual void Quit() override { - Waitable::GetInstance()->Quit(); - } + void Quit() override { Waitable::GetInstance()->Quit(); } - virtual void ScheduleWork() override { - Waitable::GetInstance()->Signal(); - } + void ScheduleWork() override { Waitable::GetInstance()->Signal(); } - virtual void ScheduleDelayedWork( - const base::TimeTicks& delayed_work_time) override { + void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) override { Waitable::GetInstance()->Signal(); } };
diff --git a/base/threading/thread_checker.h b/base/threading/thread_checker.h index 4d71f79..449247a 100644 --- a/base/threading/thread_checker.h +++ b/base/threading/thread_checker.h
@@ -30,7 +30,7 @@ // right version for your build configuration. class ThreadCheckerDoNothing { public: - bool CalledOnValidThread() const { + bool CalledOnValidThread() const WARN_UNUSED_RESULT { return true; }
diff --git a/base/threading/thread_checker_impl.h b/base/threading/thread_checker_impl.h index 879ac3a..c92e143 100644 --- a/base/threading/thread_checker_impl.h +++ b/base/threading/thread_checker_impl.h
@@ -6,6 +6,7 @@ #define BASE_THREADING_THREAD_CHECKER_IMPL_H_ #include "base/base_export.h" +#include "base/compiler_specific.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" @@ -22,7 +23,7 @@ ThreadCheckerImpl(); ~ThreadCheckerImpl(); - bool CalledOnValidThread() const; + bool CalledOnValidThread() const WARN_UNUSED_RESULT; // Changes the thread that is checked for in CalledOnValidThread. This may // be useful when an object may be created on one thread and then used
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index 7f73071d..c8583d73 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -141,7 +141,7 @@ // means, if the category for the event is disabled, the conversion will not // happen. // -// class MyData : public base::debug::ConvertableToTraceFormat { +// class MyData : public base::trace_event::ConvertableToTraceFormat { // public: // MyData() {} // virtual void AppendAsTraceFormat(std::string* out) const override { @@ -596,6 +596,15 @@ category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ arg1_name, arg1_val) +// Similar to TRACE_EVENT_ASYNC_STEP_INTOx but with a custom |at| timestamp +// provided. +#define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, \ + id, step, timestamp) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ + TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id, \ + static_cast<int>(base::PlatformThread::CurrentId()), \ + timestamp, TRACE_EVENT_FLAG_NONE, "step", step) + // Records a single ASYNC_STEP_PAST event for |step| immediately. If the // category is not enabled, then this does nothing. The |name| and |id| must // match the ASYNC_BEGIN event above. The |step| param identifies this step @@ -795,8 +804,8 @@ #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \ UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \ - (base::debug::TraceLog::ENABLED_FOR_RECORDING | \ - base::debug::TraceLog::ENABLED_FOR_EVENT_CALLBACK)) + (base::trace_event::TraceLog::ENABLED_FOR_RECORDING | \ + base::trace_event::TraceLog::ENABLED_FOR_EVENT_CALLBACK)) // Macro to efficiently determine if a given category group is enabled. #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \ @@ -839,16 +848,16 @@ // const unsigned char* // TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group) #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \ - base::debug::TraceLog::GetCategoryGroupEnabled + base::trace_event::TraceLog::GetCategoryGroupEnabled // Get the number of times traces have been recorded. This is used to implement // the TRACE_EVENT_IS_NEW_TRACE facility. // unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED() #define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \ - base::debug::TraceLog::GetInstance()->GetNumTracesRecorded + base::trace_event::TraceLog::GetInstance()->GetNumTracesRecorded // Add a trace event to the platform tracing system. -// base::debug::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT( +// base::trace_event::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT( // char phase, // const unsigned char* category_group_enabled, // const char* name, @@ -859,10 +868,11 @@ // const unsigned long long* arg_values, // unsigned char flags) #define TRACE_EVENT_API_ADD_TRACE_EVENT \ - base::debug::TraceLog::GetInstance()->AddTraceEvent + base::trace_event::TraceLog::GetInstance()->AddTraceEvent // Add a trace event to the platform tracing system. -// base::debug::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( +// base::trace_event::TraceEventHandle +// TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( // char phase, // const unsigned char* category_group_enabled, // const char* name, @@ -875,15 +885,16 @@ // const unsigned long long* arg_values, // unsigned char flags) #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \ - base::debug::TraceLog::GetInstance()->AddTraceEventWithThreadIdAndTimestamp + base::trace_event::TraceLog::GetInstance() \ + ->AddTraceEventWithThreadIdAndTimestamp // Set the duration field of a COMPLETE trace event. // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( // const unsigned char* category_group_enabled, // const char* name, -// base::debug::TraceEventHandle id) +// base::trace_event::TraceEventHandle id) #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \ - base::debug::TraceLog::GetInstance()->UpdateTraceEventDuration + base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDuration // Defines atomic operations used internally by the tracing system. #define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord @@ -956,11 +967,12 @@ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ - base::debug::TraceEventHandle h = trace_event_internal::AddTraceEvent( \ - TRACE_EVENT_PHASE_COMPLETE, \ - INTERNAL_TRACE_EVENT_UID(category_group_enabled), \ - name, trace_event_internal::kNoEventId, \ - TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ + base::trace_event::TraceEventHandle h = \ + trace_event_internal::AddTraceEvent( \ + TRACE_EVENT_PHASE_COMPLETE, \ + INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ + trace_event_internal::kNoEventId, TRACE_EVENT_FLAG_NONE, \ + ##__VA_ARGS__); \ INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \ INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \ } @@ -1253,7 +1265,7 @@ // pointers to the internal c_str and pass through to the tracing API, // the arg_values must live throughout these procedures. -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1263,7 +1275,8 @@ const base::TimeTicks& timestamp, unsigned char flags, const char* arg1_name, - const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val) { + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>& + arg1_val) { const int num_args = 1; unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE }; return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( @@ -1272,7 +1285,7 @@ } template<class ARG1_TYPE> -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1284,7 +1297,8 @@ const char* arg1_name, const ARG1_TYPE& arg1_val, const char* arg2_name, - const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg2_val) { + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>& + arg2_val) { const int num_args = 2; const char* arg_names[2] = { arg1_name, arg2_name }; @@ -1293,7 +1307,8 @@ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); arg_types[1] = TRACE_VALUE_TYPE_CONVERTABLE; - scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2]; + scoped_refptr<base::trace_event::ConvertableToTraceFormat> + convertable_values[2]; convertable_values[1] = arg2_val; return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( @@ -1302,7 +1317,7 @@ } template<class ARG2_TYPE> -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1312,7 +1327,7 @@ const base::TimeTicks& timestamp, unsigned char flags, const char* arg1_name, - const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val, + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>& arg1_val, const char* arg2_name, const ARG2_TYPE& arg2_val) { const int num_args = 2; @@ -1324,7 +1339,8 @@ arg_values[0] = 0; SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]); - scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2]; + scoped_refptr<base::trace_event::ConvertableToTraceFormat> + convertable_values[2]; convertable_values[0] = arg1_val; return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( @@ -1332,7 +1348,7 @@ num_args, arg_names, arg_types, arg_values, convertable_values, flags); } -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1342,22 +1358,23 @@ const base::TimeTicks& timestamp, unsigned char flags, const char* arg1_name, - const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val, + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>& arg1_val, const char* arg2_name, - const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg2_val) { + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>& + arg2_val) { const int num_args = 2; const char* arg_names[2] = { arg1_name, arg2_name }; unsigned char arg_types[2] = { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE }; - scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2] = - { arg1_val, arg2_val }; + scoped_refptr<base::trace_event::ConvertableToTraceFormat> + convertable_values[2] = {arg1_val, arg2_val}; return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( phase, category_group_enabled, name, id, thread_id, timestamp, num_args, arg_names, arg_types, NULL, convertable_values, flags); } -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1371,7 +1388,7 @@ kZeroNumArgs, NULL, NULL, NULL, NULL, flags); } -static inline base::debug::TraceEventHandle AddTraceEvent( +static inline base::trace_event::TraceEventHandle AddTraceEvent( char phase, const unsigned char* category_group_enabled, const char* name, @@ -1384,7 +1401,7 @@ } template<class ARG1_TYPE> -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1405,7 +1422,7 @@ } template<class ARG1_TYPE> -static inline base::debug::TraceEventHandle AddTraceEvent( +static inline base::trace_event::TraceEventHandle AddTraceEvent( char phase, const unsigned char* category_group_enabled, const char* name, @@ -1421,7 +1438,7 @@ } template<class ARG1_TYPE, class ARG2_TYPE> -static inline base::debug::TraceEventHandle +static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( char phase, const unsigned char* category_group_enabled, @@ -1446,7 +1463,7 @@ } template<class ARG1_TYPE, class ARG2_TYPE> -static inline base::debug::TraceEventHandle AddTraceEvent( +static inline base::trace_event::TraceEventHandle AddTraceEvent( char phase, const unsigned char* category_group_enabled, const char* name, @@ -1478,7 +1495,7 @@ void Initialize(const unsigned char* category_group_enabled, const char* name, - base::debug::TraceEventHandle event_handle) { + base::trace_event::TraceEventHandle event_handle) { data_.category_group_enabled = category_group_enabled; data_.name = name; data_.event_handle = event_handle; @@ -1494,7 +1511,7 @@ struct Data { const unsigned char* category_group_enabled; const char* name; - base::debug::TraceEventHandle event_handle; + base::trace_event::TraceEventHandle event_handle; }; Data* p_data_; Data data_; @@ -1509,7 +1526,7 @@ private: const unsigned char* category_group_enabled_; const char* name_; - base::debug::TraceEventHandle event_handle_; + base::trace_event::TraceEventHandle event_handle_; }; // This macro generates less code then TRACE_EVENT0 but is also @@ -1555,7 +1572,7 @@ } // namespace trace_event_internal namespace base { -namespace debug { +namespace trace_event { template<typename IDType> class TraceScopedTrackableObject { public: @@ -1583,7 +1600,15 @@ DISALLOW_COPY_AND_ASSIGN(TraceScopedTrackableObject); }; -} // namespace debug -} // namespace base +} // namespace trace_event +} // namespace base + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace base { +namespace debug { +using base::trace_event::TraceScopedTrackableObject; +} // namespace debug +} // namespace base #endif /* BASE_TRACE_EVENT_TRACE_EVENT_H_ */
diff --git a/base/trace_event/trace_event_android.cc b/base/trace_event/trace_event_android.cc index 31da26d4..bcba436 100644 --- a/base/trace_event/trace_event_android.cc +++ b/base/trace_event/trace_event_android.cc
@@ -24,8 +24,8 @@ unsigned long long id, const char** arg_names, const unsigned char* arg_types, - const base::debug::TraceEvent::TraceValue* arg_values, - const scoped_refptr<base::debug::ConvertableToTraceFormat>* + const base::trace_event::TraceEvent::TraceValue* arg_values, + const scoped_refptr<base::trace_event::ConvertableToTraceFormat>* convertable_values, unsigned char flags) { std::string out = base::StringPrintf("%c|%d|%s", phase, getpid(), name); @@ -33,7 +33,8 @@ base::StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); out += '|'; - for (int i = 0; i < base::debug::kTraceMaxNumArgs && arg_names[i]; ++i) { + for (int i = 0; i < base::trace_event::kTraceMaxNumArgs && arg_names[i]; + ++i) { if (i) out += ';'; out += arg_names[i]; @@ -42,8 +43,8 @@ if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) { convertable_values[i]->AppendAsTraceFormat(&out); } else { - base::debug::TraceEvent::AppendValueAsJSON( - arg_types[i], arg_values[i], &out); + base::trace_event::TraceEvent::AppendValueAsJSON(arg_types[i], + arg_values[i], &out); } // Remove the quotes which may confuse the atrace script. ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'"); @@ -65,7 +66,7 @@ complete_event->Signal(); } -void EndChromeTracing(base::debug::TraceLog* trace_log, +void EndChromeTracing(base::trace_event::TraceLog* trace_log, base::WaitableEvent* complete_event) { trace_log->SetDisabled(); // Delete the buffered trace events as they have been sent to atrace. @@ -75,7 +76,7 @@ } // namespace namespace base { -namespace debug { +namespace trace_event { // These functions support Android systrace.py when 'webview' category is // traced. With the new adb_profile_chrome, we may have two phases: @@ -195,5 +196,5 @@ close(atrace_fd); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_argument.cc b/base/trace_event/trace_event_argument.cc index 00fcde1..91ed9e8 100644 --- a/base/trace_event/trace_event_argument.cc +++ b/base/trace_event/trace_event_argument.cc
@@ -8,7 +8,7 @@ #include "base/values.h" namespace base { -namespace debug { +namespace trace_event { TracedValue::TracedValue() : root_(new DictionaryValue()) { stack_.push_back(root_.get()); @@ -113,5 +113,5 @@ DCHECK_EQ(1u, stack_.size()) << tmp; } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_argument.h b/base/trace_event/trace_event_argument.h index 08a5b50..43a0f38 100644 --- a/base/trace_event/trace_event_argument.h +++ b/base/trace_event/trace_event_argument.h
@@ -16,7 +16,7 @@ class ListValue; class Value; -namespace debug { +namespace trace_event { class BASE_EXPORT TracedValue : public ConvertableToTraceFormat { public: @@ -53,6 +53,14 @@ DISALLOW_COPY_AND_ASSIGN(TracedValue); }; +} // namespace trace_event +} // namespace base + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace base { +namespace debug { +using base::trace_event::TracedValue; } // namespace debug } // namespace base
diff --git a/base/trace_event/trace_event_argument_unittest.cc b/base/trace_event/trace_event_argument_unittest.cc index 39cafef..c59910e 100644 --- a/base/trace_event/trace_event_argument_unittest.cc +++ b/base/trace_event/trace_event_argument_unittest.cc
@@ -6,7 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" namespace base { -namespace debug { +namespace trace_event { TEST(TraceEventArgumentTest, FlatDictionary) { scoped_refptr<TracedValue> value = new TracedValue(); @@ -49,5 +49,5 @@ json); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_impl.cc b/base/trace_event/trace_event_impl.cc index a8a0cc1..95cf06d 100644 --- a/base/trace_event/trace_event_impl.cc +++ b/base/trace_event/trace_event_impl.cc
@@ -41,8 +41,8 @@ class DeleteTraceLogForTesting { public: static void Delete() { - Singleton<base::debug::TraceLog, - LeakySingletonTraits<base::debug::TraceLog> >::OnExit(0); + Singleton<base::trace_event::TraceLog, + LeakySingletonTraits<base::trace_event::TraceLog>>::OnExit(0); } }; @@ -50,7 +50,7 @@ BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3]; namespace base { -namespace debug { +namespace trace_event { namespace { @@ -2560,7 +2560,7 @@ return delays_; } -} // namespace debug +} // namespace trace_event } // namespace base namespace trace_event_internal {
diff --git a/base/trace_event/trace_event_impl.h b/base/trace_event/trace_event_impl.h index 6d04c76..742f6b6 100644 --- a/base/trace_event/trace_event_impl.h +++ b/base/trace_event/trace_event_impl.h
@@ -27,17 +27,17 @@ // Older style trace macros with explicit id and extra data // Only these macros result in publishing data to ETW as currently implemented. #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ + base::trace_event::TraceLog::AddTraceEventEtw( \ TRACE_EVENT_PHASE_BEGIN, \ name, reinterpret_cast<const void*>(id), extra) #define TRACE_EVENT_END_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ + base::trace_event::TraceLog::AddTraceEventEtw( \ TRACE_EVENT_PHASE_END, \ name, reinterpret_cast<const void*>(id), extra) #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ + base::trace_event::TraceLog::AddTraceEventEtw( \ TRACE_EVENT_PHASE_INSTANT, \ name, reinterpret_cast<const void*>(id), extra) @@ -49,7 +49,7 @@ class WaitableEvent; class MessageLoop; -namespace debug { +namespace trace_event { // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided // class must implement this interface. @@ -807,6 +807,23 @@ DISALLOW_COPY_AND_ASSIGN(TraceLog); }; +} // namespace trace_event +} // namespace base + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace base { +namespace debug { +using base::trace_event::CategoryFilter; +using base::trace_event::ConvertableToTraceFormat; +using base::trace_event::RECORD_UNTIL_FULL; +using base::trace_event::RECORD_CONTINUOUSLY; +using base::trace_event::RECORD_AS_MUCH_AS_POSSIBLE; +using base::trace_event::TraceEventHandle; +using base::trace_event::TraceLog; +using base::trace_event::TraceLogStatus; +using base::trace_event::TraceOptions; +using base::trace_event::TraceResultBuffer; } // namespace debug } // namespace base
diff --git a/base/trace_event/trace_event_impl_constants.cc b/base/trace_event/trace_event_impl_constants.cc index c46cf49f..ffeacff3 100644 --- a/base/trace_event/trace_event_impl_constants.cc +++ b/base/trace_event/trace_event_impl_constants.cc
@@ -5,7 +5,7 @@ #include "base/trace_event/trace_event_impl.h" namespace base { -namespace debug { +namespace trace_event { // Enable everything but debug and test categories by default. const char CategoryFilter::kDefaultCategoryFilterString[] = "-*Debug,-*Test"; @@ -24,5 +24,5 @@ const TraceLog::InternalTraceOptions TraceLog::kInternalRecordAsMuchAsPossible = 1 << 4; -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_memory.cc b/base/trace_event/trace_event_memory.cc index 96b28e47..2bf6d38b 100644 --- a/base/trace_event/trace_event_memory.cc +++ b/base/trace_event/trace_event_memory.cc
@@ -15,7 +15,7 @@ #include "base/trace_event/trace_event.h" namespace base { -namespace debug { +namespace trace_event { namespace { @@ -26,13 +26,13 @@ ///////////////////////////////////////////////////////////////////////////// // Holds a memory dump until the tracing system needs to serialize it. -class MemoryDumpHolder : public base::debug::ConvertableToTraceFormat { +class MemoryDumpHolder : public base::trace_event::ConvertableToTraceFormat { public: // Takes ownership of dump, which must be a JSON string, allocated with // malloc() and NULL terminated. explicit MemoryDumpHolder(char* dump) : dump_(dump) {} - // base::debug::ConvertableToTraceFormat overrides: + // base::trace_event::ConvertableToTraceFormat overrides: void AppendAsTraceFormat(std::string* out) const override { AppendHeapProfileAsTraceFormat(dump_, out); } @@ -165,7 +165,7 @@ TraceLog::GetInstance()->RemoveEnabledStateObserver(this); } - // base::debug::TraceLog::EnabledStateChangedObserver overrides: +// base::trace_event::TraceLog::EnabledStateChangedObserver overrides: void TraceMemoryController::OnTraceLogEnabled() { // Check to see if tracing is enabled for the memory category. bool enabled; @@ -436,5 +436,5 @@ return reinterpret_cast<const char*>(address); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_memory.h b/base/trace_event/trace_event_memory.h index f16467f..8e70020 100644 --- a/base/trace_event/trace_event_memory.h +++ b/base/trace_event/trace_event_memory.h
@@ -22,7 +22,7 @@ class MessageLoopProxy; -namespace debug { +namespace trace_event { // Watches for chrome://tracing to be enabled or disabled. When tracing is // enabled, also enables tcmalloc heap profiling. This class is the preferred @@ -46,7 +46,7 @@ GetHeapProfileFunction get_heap_profile_function); virtual ~TraceMemoryController(); - // base::debug::TraceLog::EnabledStateChangedObserver overrides: + // base::trace_event::TraceLog::EnabledStateChangedObserver overrides: void OnTraceLogEnabled() override; void OnTraceLogDisabled() override; @@ -146,7 +146,7 @@ // and "error" if |address| could not be parsed. Visible for testing. BASE_EXPORT const char* StringFromHexAddress(const std::string& hex_address); -} // namespace debug +} // namespace trace_event } // namespace base // Make local variables with unique names based on the line number. Note that @@ -159,7 +159,7 @@ // It generates a unique local variable name using the macros above. #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) #define INTERNAL_TRACE_MEMORY(category, name) \ - base::debug::ScopedTraceMemory INTERNAL_TRACE_MEMORY_ID(category, name); + base::trace_event::ScopedTraceMemory INTERNAL_TRACE_MEMORY_ID(category, name); #else #define INTERNAL_TRACE_MEMORY(category, name) #endif // defined(TRACE_MEMORY_SUPPORTED)
diff --git a/base/trace_event/trace_event_memory_unittest.cc b/base/trace_event/trace_event_memory_unittest.cc index 220c0e6..4732733 100644 --- a/base/trace_event/trace_event_memory_unittest.cc +++ b/base/trace_event/trace_event_memory_unittest.cc
@@ -16,7 +16,7 @@ #endif namespace base { -namespace debug { +namespace trace_event { // Tests for the trace event memory tracking system. Exists as a class so it // can be a friend of TraceMemoryController. @@ -236,5 +236,5 @@ EXPECT_STREQ(kHello, StringFromHexAddress(hex_address.str())); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_synthetic_delay.cc b/base/trace_event/trace_event_synthetic_delay.cc index 3651611..4b957c3 100644 --- a/base/trace_event/trace_event_synthetic_delay.cc +++ b/base/trace_event/trace_event_synthetic_delay.cc
@@ -10,7 +10,7 @@ } // namespace namespace base { -namespace debug { +namespace trace_event { TraceEventSyntheticDelayClock::TraceEventSyntheticDelayClock() {} TraceEventSyntheticDelayClock::~TraceEventSyntheticDelayClock() {} @@ -200,7 +200,7 @@ TraceEventSyntheticDelayRegistry::GetInstance()->ResetAllDelays(); } -} // namespace debug +} // namespace trace_event } // namespace base namespace trace_event_internal { @@ -215,15 +215,16 @@ delay_impl_->EndParallel(end_time_); } -base::debug::TraceEventSyntheticDelay* GetOrCreateDelay( +base::trace_event::TraceEventSyntheticDelay* GetOrCreateDelay( const char* name, base::subtle::AtomicWord* impl_ptr) { - base::debug::TraceEventSyntheticDelay* delay_impl = - reinterpret_cast<base::debug::TraceEventSyntheticDelay*>( + base::trace_event::TraceEventSyntheticDelay* delay_impl = + reinterpret_cast<base::trace_event::TraceEventSyntheticDelay*>( base::subtle::Acquire_Load(impl_ptr)); if (!delay_impl) { - delay_impl = base::debug::TraceEventSyntheticDelayRegistry::GetInstance() - ->GetOrCreateDelay(name); + delay_impl = + base::trace_event::TraceEventSyntheticDelayRegistry::GetInstance() + ->GetOrCreateDelay(name); base::subtle::Release_Store( impl_ptr, reinterpret_cast<base::subtle::AtomicWord>(delay_impl)); }
diff --git a/base/trace_event/trace_event_synthetic_delay.h b/base/trace_event/trace_event_synthetic_delay.h index b52f3b0..14801be 100644 --- a/base/trace_event/trace_event_synthetic_delay.h +++ b/base/trace_event/trace_event_synthetic_delay.h
@@ -65,7 +65,7 @@ struct DefaultSingletonTraits; namespace base { -namespace debug { +namespace trace_event { // Time source for computing delay durations. Used for testing. class TRACE_EVENT_API_CLASS_EXPORT TraceEventSyntheticDelayClock { @@ -138,7 +138,7 @@ // Set the target durations of all registered synthetic delay points to zero. TRACE_EVENT_API_CLASS_EXPORT void ResetTraceEventSyntheticDelays(); -} // namespace debug +} // namespace trace_event } // namespace base namespace trace_event_internal { @@ -151,14 +151,14 @@ ~ScopedSyntheticDelay(); private: - base::debug::TraceEventSyntheticDelay* delay_impl_; + base::trace_event::TraceEventSyntheticDelay* delay_impl_; base::TimeTicks end_time_; DISALLOW_COPY_AND_ASSIGN(ScopedSyntheticDelay); }; // Helper for registering delays. Do not use directly. -TRACE_EVENT_API_CLASS_EXPORT base::debug::TraceEventSyntheticDelay* +TRACE_EVENT_API_CLASS_EXPORT base::trace_event::TraceEventSyntheticDelay* GetOrCreateDelay(const char* name, base::subtle::AtomicWord* impl_ptr); } // namespace trace_event_internal
diff --git a/base/trace_event/trace_event_synthetic_delay_unittest.cc b/base/trace_event/trace_event_synthetic_delay_unittest.cc index 84ac75cc..1dc0fc2 100644 --- a/base/trace_event/trace_event_synthetic_delay_unittest.cc +++ b/base/trace_event/trace_event_synthetic_delay_unittest.cc
@@ -7,7 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" namespace base { -namespace debug { +namespace trace_event { namespace { const int kTargetDurationMs = 100; @@ -150,5 +150,5 @@ EXPECT_LT((Now() - start_time).InMilliseconds(), kShortDurationMs); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_system_stats_monitor.cc b/base/trace_event/trace_event_system_stats_monitor.cc index 6fa01745..98f361a 100644 --- a/base/trace_event/trace_event_system_stats_monitor.cc +++ b/base/trace_event/trace_event_system_stats_monitor.cc
@@ -16,13 +16,13 @@ #include "base/trace_event/trace_event.h" namespace base { -namespace debug { +namespace trace_event { namespace { ///////////////////////////////////////////////////////////////////////////// // Holds profiled system stats until the tracing system needs to serialize it. -class SystemStatsHolder : public base::debug::ConvertableToTraceFormat { +class SystemStatsHolder : public base::trace_event::ConvertableToTraceFormat { public: SystemStatsHolder() { } @@ -30,7 +30,7 @@ // Uses the previous stats to compute rates if this is not the first profile. void GetSystemProfilingStats(); - // base::debug::ConvertableToTraceFormat overrides: + // base::trace_event::ConvertableToTraceFormat overrides: void AppendAsTraceFormat(std::string* out) const override { AppendSystemProfileAsTraceFormat(system_stats_, out); } @@ -129,5 +129,5 @@ *output += tmp; } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_system_stats_monitor.h b/base/trace_event/trace_event_system_stats_monitor.h index 08fbfea..051669a 100644 --- a/base/trace_event/trace_event_system_stats_monitor.h +++ b/base/trace_event/trace_event_system_stats_monitor.h
@@ -17,7 +17,7 @@ class SingleThreadTaskRunner; -namespace debug { +namespace trace_event { // Watches for chrome://tracing to be enabled or disabled. When tracing is // enabled, also enables system events profiling. This class is the preferred @@ -35,7 +35,7 @@ virtual ~TraceEventSystemStatsMonitor(); - // base::debug::TraceLog::EnabledStateChangedObserver overrides: + // base::trace_event::TraceLog::EnabledStateChangedObserver overrides: void OnTraceLogEnabled() override; void OnTraceLogDisabled() override; @@ -69,7 +69,7 @@ system_stats, std::string* output); -} // namespace debug +} // namespace trace_event } // namespace base #endif // BASE_TRACE_EVENT_TRACE_EVENT_SYSTEM_STATS_MONITOR_H_
diff --git a/base/trace_event/trace_event_system_stats_monitor_unittest.cc b/base/trace_event/trace_event_system_stats_monitor_unittest.cc index 143ac4ad..995f53b 100644 --- a/base/trace_event/trace_event_system_stats_monitor_unittest.cc +++ b/base/trace_event/trace_event_system_stats_monitor_unittest.cc
@@ -12,7 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" namespace base { -namespace debug { +namespace trace_event { #if !defined(OS_IOS) // Tests for the system stats monitor. @@ -62,5 +62,5 @@ } #endif // !defined(OS_IOS) -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc index 47b5ab6..a6bc0d4e 100644 --- a/base/trace_event/trace_event_unittest.cc +++ b/base/trace_event/trace_event_unittest.cc
@@ -25,7 +25,7 @@ #include "testing/gtest/include/gtest/gtest.h" namespace base { -namespace debug { +namespace trace_event { namespace { @@ -3079,6 +3079,5 @@ } } - -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_win.cc b/base/trace_event/trace_event_win.cc index d2c3dc8..ebb55c8 100644 --- a/base/trace_event/trace_event_win.cc +++ b/base/trace_event/trace_event_win.cc
@@ -9,7 +9,7 @@ #include <initguid.h> // NOLINT namespace base { -namespace debug { +namespace trace_event { using base::win::EtwEventType; using base::win::EtwMofEvent; @@ -120,5 +120,5 @@ StaticMemorySingletonTraits<TraceEventETWProvider>::Resurrect(); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/trace_event/trace_event_win.h b/base/trace_event/trace_event_win.h index e447c35d..dcb5aacc 100644 --- a/base/trace_event/trace_event_win.h +++ b/base/trace_event/trace_event_win.h
@@ -17,7 +17,7 @@ struct StaticMemorySingletonTraits; namespace base { -namespace debug { +namespace trace_event { // This EtwTraceProvider subclass implements ETW logging // for the macros above on Windows. @@ -119,6 +119,20 @@ // Optionally the stack trace, consisting of a DWORD "depth", followed // by an array of void* (machine bitness) of length "depth". +} // namespace trace_event +} // namespace base + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace base { +namespace debug { +using base::trace_event::kChromeTraceProviderName; +using base::trace_event::kTraceEventClass32; +using base::trace_event::kTraceEventClass64; +using base::trace_event::kTraceEventTypeBegin; +using base::trace_event::kTraceEventTypeEnd; +using base::trace_event::kTraceEventTypeInstant; +using base::trace_event::TraceEventETWProvider; } // namespace debug } // namespace base
diff --git a/base/trace_event/trace_event_win_unittest.cc b/base/trace_event/trace_event_win_unittest.cc index a411301..7f1004e 100644 --- a/base/trace_event/trace_event_win_unittest.cc +++ b/base/trace_event/trace_event_win_unittest.cc
@@ -20,7 +20,7 @@ #include <initguid.h> // NOLINT - must be last include. namespace base { -namespace debug { +namespace trace_event { namespace { @@ -315,5 +315,5 @@ PlayLog(); } -} // namespace debug +} // namespace trace_event } // namespace base
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc index fe209f5e..35609fcf5 100644 --- a/base/win/object_watcher.cc +++ b/base/win/object_watcher.cc
@@ -77,7 +77,11 @@ return true; } -HANDLE ObjectWatcher::GetWatchedObject() { +bool ObjectWatcher::IsWatching() const { + return object_ != NULL; +} + +HANDLE ObjectWatcher::GetWatchedObject() const { return object_; }
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h index bf7f8b3..ecd0415 100644 --- a/base/win/object_watcher.h +++ b/base/win/object_watcher.h
@@ -74,9 +74,11 @@ // bool StopWatching(); - // Returns the handle of the object being watched, or NULL if the object - // watcher is stopped. - HANDLE GetWatchedObject(); + // Returns true if currently watching an object. + bool IsWatching() const; + + // Returns the handle of the object being watched. + HANDLE GetWatchedObject() const; private: // Called on a background thread when done waiting.
diff --git a/base/win/object_watcher_unittest.cc b/base/win/object_watcher_unittest.cc index 46b98de..1a5e9e2a 100644 --- a/base/win/object_watcher_unittest.cc +++ b/base/win/object_watcher_unittest.cc
@@ -37,7 +37,7 @@ MessageLoop message_loop(message_loop_type); ObjectWatcher watcher; - EXPECT_EQ(NULL, watcher.GetWatchedObject()); + EXPECT_FALSE(watcher.IsWatching()); // A manual-reset event that is not yet signaled. HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -45,13 +45,14 @@ QuitDelegate delegate; bool ok = watcher.StartWatching(event, &delegate); EXPECT_TRUE(ok); + EXPECT_TRUE(watcher.IsWatching()); EXPECT_EQ(event, watcher.GetWatchedObject()); SetEvent(event); MessageLoop::current()->Run(); - EXPECT_EQ(NULL, watcher.GetWatchedObject()); + EXPECT_FALSE(watcher.IsWatching()); CloseHandle(event); } @@ -115,7 +116,7 @@ MessageLoop::current()->Run(); - EXPECT_EQ(NULL, watcher.GetWatchedObject()); + EXPECT_FALSE(watcher.IsWatching()); CloseHandle(event); }
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py index e1858ce..fc053d1 100755 --- a/build/android/buildbot/bb_device_steps.py +++ b/build/android/buildbot/bb_device_steps.py
@@ -340,13 +340,13 @@ unexpected_passes, unexpected_failures, unexpected_flakes = ( _ParseLayoutTestResults(full_results)) if unexpected_failures: - _PrintDashboardLink('failed', unexpected_failures, + _PrintDashboardLink('failed', unexpected_failures.keys(), max_tests=25) elif unexpected_passes: - _PrintDashboardLink('unexpected passes', unexpected_passes, + _PrintDashboardLink('unexpected passes', unexpected_passes.keys(), max_tests=10) if unexpected_flakes: - _PrintDashboardLink('unexpected flakes', unexpected_flakes, + _PrintDashboardLink('unexpected flakes', unexpected_flakes.keys(), max_tests=10) if exit_code == 0 and (unexpected_passes or unexpected_flakes):
diff --git a/build/android/finalize_apk_action.gypi b/build/android/finalize_apk_action.gypi index 5ffbffa..9934c1a 100644 --- a/build/android/finalize_apk_action.gypi +++ b/build/android/finalize_apk_action.gypi
@@ -12,7 +12,7 @@ # 'input_apk_path': 'relative/path/to/input.apk', # 'output_apk_path': 'relative/path/to/output.apk', # }, -# 'includes': [ '../../build/android/finalize_apk.gypi' ], +# 'includes': [ '../../build/android/finalize_apk_action.gypi' ], # }, # @@ -34,8 +34,8 @@ ], }, 'inputs': [ - '<(DEPTH)/build/android/gyp/util/build_utils.py', '<(DEPTH)/build/android/gyp/finalize_apk.py', + '<(DEPTH)/build/android/gyp/util/build_utils.py', '<(keystore_path)', '<(input_apk_path)', ],
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py index a5ce11e6..6b1a91c 100644 --- a/build/android/pylib/device/device_utils.py +++ b/build/android/pylib/device/device_utils.py
@@ -104,6 +104,9 @@ _MAX_ADB_COMMAND_LENGTH = 512 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') + # Property in /data/local.prop that controls Java assertions. + JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' + def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, default_retries=_DEFAULT_RETRIES): """DeviceUtils constructor. @@ -1041,7 +1044,43 @@ Raises: CommandTimeoutError on timeout. """ - return self.old_interface.SetJavaAssertsEnabled(enabled) + def find_property(lines, property_name): + for index, line in enumerate(lines): + key, value = (s.strip() for s in line.split('=', 1)) + if key == property_name: + return index, value + return None, '' + + new_value = 'all' if enabled else '' + + # First ensure the desired property is persisted. + try: + properties = self.ReadFile( + constants.DEVICE_LOCAL_PROPERTIES_PATH).splitlines() + except device_errors.CommandFailedError: + properties = [] + index, value = find_property(properties, self.JAVA_ASSERT_PROPERTY) + if new_value != value: + if new_value: + new_line = '%s=%s' % (self.JAVA_ASSERT_PROPERTY, new_value) + if index is None: + properties.append(new_line) + else: + properties[index] = new_line + else: + assert index is not None # since new_value == '' and new_value != value + properties.pop(index) + self.WriteFile(constants.DEVICE_LOCAL_PROPERTIES_PATH, + _JoinLines(properties)) + + # Next, check the current runtime value is what we need, and + # if not, set it and report that a reboot is required. + value = self.GetProp(self.JAVA_ASSERT_PROPERTY) + if new_value != value: + self.SetProp(self.JAVA_ASSERT_PROPERTY, new_value) + return True + else: + return False @property
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py index 9d41741..6071fd5 100755 --- a/build/android/pylib/device/device_utils_test.py +++ b/build/android/pylib/device/device_utils_test.py
@@ -1238,81 +1238,44 @@ self.device.Stat('/data/local/tmp/does.not.exist.txt') -class DeviceUtilsSetJavaAssertsTest(DeviceUtilsOldImplTest): - - @staticmethod - def mockNamedTemporary(name='/tmp/file/property.file', - read_contents=''): - mock_file = mock.MagicMock(spec=file) - mock_file.name = name - mock_file.__enter__.return_value = mock_file - mock_file.read.return_value = read_contents - return mock_file +class DeviceUtilsSetJavaAssertsTest(DeviceUtilsNewImplTest): def testSetJavaAsserts_enable(self): - mock_file = self.mockNamedTemporary() - with mock.patch('tempfile.NamedTemporaryFile', - return_value=mock_file), ( - mock.patch('__builtin__.open', return_value=mock_file)): - with self.assertCallsSequence( - [('adb -s 0123456789abcdef shell ls %s' % - constants.DEVICE_LOCAL_PROPERTIES_PATH, - '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH), - ('adb -s 0123456789abcdef pull %s %s' % - (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name), - '100 B/s (100 bytes in 1.000s)\r\n'), - ('adb -s 0123456789abcdef push %s %s' % - (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH), - '100 B/s (100 bytes in 1.000s)\r\n'), - ('adb -s 0123456789abcdef shell ' - 'getprop dalvik.vm.enableassertions', - '\r\n'), - ('adb -s 0123456789abcdef shell ' - 'setprop dalvik.vm.enableassertions "all"', - '')]): - self.assertTrue(self.device.SetJavaAsserts(True)) + with self.assertCalls( + (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), + 'some.example.prop=with an example value\n' + 'some.other.prop=value_ok\n'), + self.call.device.WriteFile( + constants.DEVICE_LOCAL_PROPERTIES_PATH, + 'some.example.prop=with an example value\n' + 'some.other.prop=value_ok\n' + 'dalvik.vm.enableassertions=all\n'), + (self.call.device.GetProp('dalvik.vm.enableassertions'), ''), + self.call.device.SetProp('dalvik.vm.enableassertions', 'all')): + self.assertTrue(self.device.SetJavaAsserts(True)) def testSetJavaAsserts_disable(self): - mock_file = self.mockNamedTemporary( - read_contents='dalvik.vm.enableassertions=all\n') - with mock.patch('tempfile.NamedTemporaryFile', - return_value=mock_file), ( - mock.patch('__builtin__.open', return_value=mock_file)): - with self.assertCallsSequence( - [('adb -s 0123456789abcdef shell ls %s' % - constants.DEVICE_LOCAL_PROPERTIES_PATH, - '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH), - ('adb -s 0123456789abcdef pull %s %s' % - (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name), - '100 B/s (100 bytes in 1.000s)\r\n'), - ('adb -s 0123456789abcdef push %s %s' % - (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH), - '100 B/s (100 bytes in 1.000s)\r\n'), - ('adb -s 0123456789abcdef shell ' - 'getprop dalvik.vm.enableassertions', - 'all\r\n'), - ('adb -s 0123456789abcdef shell ' - 'setprop dalvik.vm.enableassertions ""', - '')]): - self.assertTrue(self.device.SetJavaAsserts(False)) + with self.assertCalls( + (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), + 'some.example.prop=with an example value\n' + 'dalvik.vm.enableassertions=all\n' + 'some.other.prop=value_ok\n'), + self.call.device.WriteFile( + constants.DEVICE_LOCAL_PROPERTIES_PATH, + 'some.example.prop=with an example value\n' + 'some.other.prop=value_ok\n'), + (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'), + self.call.device.SetProp('dalvik.vm.enableassertions', '')): + self.assertTrue(self.device.SetJavaAsserts(False)) def testSetJavaAsserts_alreadyEnabled(self): - mock_file = self.mockNamedTemporary( - read_contents='dalvik.vm.enableassertions=all\n') - with mock.patch('tempfile.NamedTemporaryFile', - return_value=mock_file), ( - mock.patch('__builtin__.open', return_value=mock_file)): - with self.assertCallsSequence( - [('adb -s 0123456789abcdef shell ls %s' % - constants.DEVICE_LOCAL_PROPERTIES_PATH, - '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH), - ('adb -s 0123456789abcdef pull %s %s' % - (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name), - '100 B/s (100 bytes in 1.000s)\r\n'), - ('adb -s 0123456789abcdef shell ' - 'getprop dalvik.vm.enableassertions', - 'all\r\n')]): - self.assertFalse(self.device.SetJavaAsserts(True)) + with self.assertCalls( + (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), + 'some.example.prop=with an example value\n' + 'dalvik.vm.enableassertions=all\n' + 'some.other.prop=value_ok\n'), + (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')): + self.assertFalse(self.device.SetJavaAsserts(True)) class DeviceUtilsGetPropTest(DeviceUtilsNewImplTest):
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py index 91701b0..6388bdc 100644 --- a/build/android/pylib/remote/device/remote_device_test_run.py +++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -172,10 +172,10 @@ logging.info('Downloading results to %s.' % results_path) if not os.path.exists(os.path.basename(results_path)): os.makedirs(os.path.basename(results_path)) - with appurify_sanitized.SanitizeLogging(self._env.verbose_count, - logging.WARNING): - appurify_sanitized.utils.wget(self._results['results']['url'], - results_path) + with appurify_sanitized.SanitizeLogging(self._env.verbose_count, + logging.WARNING): + appurify_sanitized.utils.wget(self._results['results']['url'], + results_path) def _GetTestStatus(self, test_run_id): """Checks the state of the test, and sets self._results
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index cc7bbee6..f0972517 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -529,7 +529,7 @@ help='APK to run tests on.') group.add_argument( '--minutes', default=5, type=int, - help='Number of minutes to run uirobot test [default: %default].') + help='Number of minutes to run uirobot test [default: %(default)s].') AddCommonOptions(parser) AddDeviceOptions(parser)
diff --git a/build/common.gypi b/build/common.gypi index 948dcec..0645cf8 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -318,7 +318,7 @@ # Only used on Windows. 'win_z7%' : 0, - # Set to 1 to enable dcheck in release. + # Set to 1 to enable dcheck in Release build. 'dcheck_always_on%': 0, # Set to 1 to make a build that disables unshipped tracing events. @@ -1588,6 +1588,18 @@ 'sysroot%': '<(sysroot)', 'CXX%': '<(CXX)', }], + # Use a 64-bit linker to avoid running out of address space. The + # buildbots should have a 64-bit kernel and a 64-bit libc installed. + ['host_arch=="ia32" and target_arch=="ia32"', { + # TODO(thestig) This is a horrible way to force the desired + # configuration. Our gyp variable scoping is likely wrong and + # needs to be cleaned up. The GN configuration should be changed + # to match. + 'binutils_version%': 224, + 'linux_use_bundled_binutils%': '1', + 'linux_use_bundled_gold%': '1', + 'binutils_dir%': 'third_party/binutils/Linux_x64/Release/bin', + }], # All Chrome builds have breakpad symbols, but only process the # symbols from official builds. ['(branding=="Chrome" and buildtype=="Official")', { @@ -1596,16 +1608,6 @@ # Omit unwind support in official release builds to save space. We # can use breakpad for these builds. 'release_unwind_tables%': 0, - - 'conditions': [ - # For official builds, use a 64-bit linker to avoid running out - # of address space. The buildbots should have a 64-bit kernel - # and a 64-bit libc installed. - ['host_arch=="ia32" and target_arch=="ia32"', { - 'linux_use_bundled_gold%': '1', - 'binutils_dir%': 'third_party/binutils/Linux_x64/Release/bin', - }], - ], }], ], }], # os_posix==1 and OS!="mac" and OS!="ios" @@ -2143,7 +2145,7 @@ 'conditions': [ # TODO(dcheng): https://crbug.com/417463 -- work to enable this flag # on all platforms is currently underway. - ['OS=="linux" or OS=="mac" or OS=="ios"', { + ['OS=="android" or OS=="linux" or OS=="mac" or OS=="ios"', { 'clang_chrome_plugins_flags': [ '-Xclang', '-plugin-arg-find-bad-constructs', @@ -3541,7 +3543,7 @@ }, }], # TODO(thakis): Enable this everywhere. http://crbug.com/371125 - ['(OS=="linux" or OS=="android") and asan==0 and msan==0 and tsan==0 and ubsan==0 and ubsan_vptr==0 and use_ozone!=1', { + ['(OS=="linux" or OS=="android") and asan==0 and msan==0 and tsan==0 and ubsan==0 and ubsan_vptr==0', { 'target_defaults': { 'ldflags': [ '-Wl,-z,defs',
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index c57ba3f..5f93dd9 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn
@@ -19,6 +19,9 @@ # TODO(sebmarchand): Update this comment once this flag guarantee that # there's no build metadata in the build artifacts. dont_embed_build_metadata = false + + # Set to true to enable dcheck in Release builds. + dcheck_always_on = false } # TODO(brettw) Most of these should be removed. Instead of global feature @@ -74,6 +77,9 @@ if (dont_embed_build_metadata) { defines += [ "DONT_EMBED_BUILD_METADATA" ] } + if (dcheck_always_on) { + defines += [ "DCHECK_ALWAYS_ON=1" ] + } if (use_udev) { # TODO(brettw) should probably be "=1". defines += [ "USE_UDEV" ]
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 33449ef7..d806a17 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -80,7 +80,7 @@ # TODO(brettw) remove this flag (and therefore enable linking all targets) on # Windows when we have sufficient bot capacity. In the meantime, you can # enable linking for local compiles. - link_chrome_on_windows = false + link_chrome_on_windows = true } # =============================================================================
diff --git a/build/gyp_chromium b/build/gyp_chromium index 3d527aa..45f3206 100755 --- a/build/gyp_chromium +++ b/build/gyp_chromium
@@ -28,6 +28,7 @@ SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Add paths so that pymod_do_main(...) can import files. +sys.path.insert(1, os.path.join(chrome_src, 'android_webview', 'tools')) sys.path.insert(1, os.path.join(chrome_src, 'build', 'android', 'gyp')) sys.path.insert(1, os.path.join(chrome_src, 'tools')) sys.path.insert(1, os.path.join(chrome_src, 'tools', 'generate_shim_headers'))
diff --git a/build/java_apk.gypi b/build/java_apk.gypi index 4243554..8d55307 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi
@@ -24,9 +24,8 @@ # Optional/automatic variables: # additional_input_paths - These paths will be included in the 'inputs' list to # ensure that this target is rebuilt when one of these paths changes. -# additional_res_dirs - Additional directories containing Android resources. -# additional_res_packages - Package names of the R.java files corresponding to -# each directory in additional_res_dirs. +# additional_res_packages - Package names of R.java files generated in addition +# to the default package name defined in AndroidManifest.xml. # additional_src_dirs - Additional directories with .java files to be compiled # and included in the output of this target. # additional_bundled_libs - Additional libraries what will be stripped and
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index ae69583..a15cba12 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -111,7 +111,8 @@ "race:content::GpuWatchdogThread::CheckArmed\n" // http://crbug.com/257396 -"race:base::debug::TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n" +"race:base::trace_event::" + "TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n" // http://crbug.com/258479 "race:SamplingStateScope\n" @@ -291,10 +292,10 @@ // http://crbug.com/397022 "deadlock:" -"base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n" +"base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n" // http://crbug.com/415472 -"deadlock:base::debug::TraceLog::GetCategoryGroupEnabled\n" +"deadlock:base::trace_event::TraceLog::GetCategoryGroupEnabled\n" // http://crbug.com/425057 "deadlock:webrtc::ViEChannelManagerScoped::ViEChannelManagerScoped\n" @@ -315,6 +316,15 @@ // https://crbug.com/448203 "race:blink::RemoteFrame::detach\n" +// https://crbug.com/455638 +"deadlock:dbus::Bus::ShutdownAndBlock\n" + +// https://crbug.com/455665 +"race:mojo::common::*::tick_clock\n" + +// https://crbug.com/456095 +"race:blink::Scheduler\n" + // End of suppressions. ; // Please keep this semicolon.
diff --git a/build/secondary/third_party/libjpeg_turbo/BUILD.gn b/build/secondary/third_party/libjpeg_turbo/BUILD.gn index 82472e7..be16302 100644 --- a/build/secondary/third_party/libjpeg_turbo/BUILD.gn +++ b/build/secondary/third_party/libjpeg_turbo/BUILD.gn
@@ -84,7 +84,7 @@ } else if (is_mac) { defines += [ "MACHO" ] include_dirs = [ "mac" ] - } else if (is_linux) { + } else if (is_linux || is_android) { defines += [ "ELF" ] include_dirs = [ "linux" ] }
diff --git a/cc/base/math_util.h b/cc/base/math_util.h index d9cc43b5..ddc8955 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h
@@ -21,10 +21,16 @@ namespace base { class Value; -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace gfx { class QuadF;
diff --git a/cc/base/region.h b/cc/base/region.h index 294ea63..b84dbd5 100644 --- a/cc/base/region.h +++ b/cc/base/region.h
@@ -15,10 +15,16 @@ namespace base { class Value; -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { class SimpleEnclosedRegion;
diff --git a/cc/blink/web_content_layer_impl.cc b/cc/blink/web_content_layer_impl.cc index abe3eb30..92242230 100644 --- a/cc/blink/web_content_layer_impl.cc +++ b/cc/blink/web_content_layer_impl.cc
@@ -19,6 +19,21 @@ namespace cc_blink { +static blink::WebContentLayerClient::PaintingControlSetting +PaintingControlToWeb( + cc::ContentLayerClient::PaintingControlSetting painting_control) { + switch (painting_control) { + case cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL: + return blink::WebContentLayerClient::PaintDefaultBehavior; + case cc::ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED: + return blink::WebContentLayerClient::DisplayListConstructionDisabled; + case cc::ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED: + return blink::WebContentLayerClient::DisplayListCachingDisabled; + } + NOTREACHED(); + return blink::WebContentLayerClient::PaintDefaultBehavior; +} + WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client) : client_(client) { if (WebLayerImpl::UsingPictureLayer()) @@ -50,30 +65,22 @@ void WebContentLayerImpl::PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus graphics_context_status) { + cc::ContentLayerClient::PaintingControlSetting painting_control) { if (!client_) return; - client_->paintContents( - canvas, clip, - graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED - ? blink::WebContentLayerClient::GraphicsContextEnabled - : blink::WebContentLayerClient::GraphicsContextDisabled); + client_->paintContents(canvas, clip, PaintingControlToWeb(painting_control)); } scoped_refptr<cc::DisplayItemList> WebContentLayerImpl::PaintContentsToDisplayList( const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus graphics_context_status) { + cc::ContentLayerClient::PaintingControlSetting painting_control) { if (!client_) return cc::DisplayItemList::Create(); WebDisplayItemListImpl list; - client_->paintContents( - &list, clip, - graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED - ? blink::WebContentLayerClient::GraphicsContextEnabled - : blink::WebContentLayerClient::GraphicsContextDisabled); + client_->paintContents(&list, clip, PaintingControlToWeb(painting_control)); return list.ToDisplayItemList(); }
diff --git a/cc/blink/web_content_layer_impl.h b/cc/blink/web_content_layer_impl.h index 148f4fc7..3e7b55c5 100644 --- a/cc/blink/web_content_layer_impl.h +++ b/cc/blink/web_content_layer_impl.h
@@ -38,11 +38,10 @@ // ContentLayerClient implementation. void PaintContents(SkCanvas* canvas, const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus - graphics_context_status) override; + PaintingControlSetting painting_control) override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus graphics_context_status) override; + PaintingControlSetting painting_control) override; bool FillsBoundsCompletely() const override; scoped_ptr<WebLayerImpl> layer_;
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc index 6ce8ac5cb..bcebfec 100644 --- a/cc/blink/web_layer_impl.cc +++ b/cc/blink/web_layer_impl.cc
@@ -383,6 +383,28 @@ return result; } +static_assert(static_cast<ScrollBlocksOn>(blink::WebScrollBlocksOnNone) == + ScrollBlocksOnNone, + "ScrollBlocksOn and WebScrollBlocksOn enums must match"); +static_assert(static_cast<ScrollBlocksOn>(blink::WebScrollBlocksOnStartTouch) == + ScrollBlocksOnStartTouch, + "ScrollBlocksOn and WebScrollBlocksOn enums must match"); +static_assert(static_cast<ScrollBlocksOn>(blink::WebScrollBlocksOnWheelEvent) == + ScrollBlocksOnWheelEvent, + "ScrollBlocksOn and WebScrollBlocksOn enums must match"); +static_assert( + static_cast<ScrollBlocksOn>(blink::WebScrollBlocksOnScrollEvent) == + ScrollBlocksOnScrollEvent, + "ScrollBlocksOn and WebScrollBlocksOn enums must match"); + +void WebLayerImpl::setScrollBlocksOn(blink::WebScrollBlocksOn blocks) { + layer_->SetScrollBlocksOn(static_cast<ScrollBlocksOn>(blocks)); +} + +blink::WebScrollBlocksOn WebLayerImpl::scrollBlocksOn() const { + return static_cast<blink::WebScrollBlocksOn>(layer_->scroll_blocks_on()); +} + void WebLayerImpl::setIsContainerForFixedPositionLayers(bool enable) { layer_->SetIsContainerForFixedPositionLayers(enable); }
diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h index 111c6cf..787f6320 100644 --- a/cc/blink/web_layer_impl.h +++ b/cc/blink/web_layer_impl.h
@@ -31,10 +31,16 @@ } namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc { class Layer; @@ -123,6 +129,8 @@ virtual void setTouchEventHandlerRegion( const blink::WebVector<blink::WebRect>& region); virtual blink::WebVector<blink::WebRect> touchEventHandlerRegion() const; + virtual void setScrollBlocksOn(blink::WebScrollBlocksOn); + virtual blink::WebScrollBlocksOn scrollBlocksOn() const; virtual void setIsContainerForFixedPositionLayers(bool is_container); virtual bool isContainerForFixedPositionLayers() const; virtual void setPositionConstraint(
diff --git a/cc/debug/picture_record_benchmark.cc b/cc/debug/picture_record_benchmark.cc index d0d031d..b1b8188 100644 --- a/cc/debug/picture_record_benchmark.cc +++ b/cc/debug/picture_record_benchmark.cc
@@ -106,8 +106,9 @@ base::TimeTicks start = base::TimeTicks::Now(); - scoped_refptr<Picture> picture = Picture::Create( - rect, painter, tile_grid_size, false, Picture::RECORD_NORMALLY); + scoped_refptr<Picture> picture = + Picture::Create(rect, painter, tile_grid_size, false, + RecordingSource::RECORD_NORMALLY); base::TimeTicks end = base::TimeTicks::Now(); base::TimeDelta duration = end - start;
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc index 3a0c98b..e56a1e13 100644 --- a/cc/debug/rasterize_and_record_benchmark.cc +++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -34,10 +34,8 @@ const int kWarmupRuns = 0; const int kTimeCheckInterval = 1; -const char* kModeSuffixes[Picture::RECORDING_MODE_COUNT] = { - "", - "_sk_null_canvas", - "_painting_disabled"}; +const char* kModeSuffixes[RecordingSource::RECORDING_MODE_COUNT] = + {"", "_sk_null_canvas", "_painting_disabled", "_caching_disabled"}; } // namespace @@ -74,7 +72,7 @@ results_->SetInteger("pixels_recorded", record_results_.pixels_recorded); results_->SetInteger("picture_memory_usage", record_results_.bytes_used); - for (int i = 0; i < Picture::RECORDING_MODE_COUNT; i++) { + for (int i = 0; i < RecordingSource::RECORDING_MODE_COUNT; i++) { std::string name = base::StringPrintf("record_time%s_ms", kModeSuffixes[i]); results_->SetDouble(name, record_results_.total_best_time[i].InMillisecondsF()); @@ -132,10 +130,10 @@ gfx::Size tile_grid_size = host_->settings().default_tile_size; - for (int mode_index = 0; mode_index < Picture::RECORDING_MODE_COUNT; + for (int mode_index = 0; mode_index < RecordingSource::RECORDING_MODE_COUNT; mode_index++) { - Picture::RecordingMode mode = - static_cast<Picture::RecordingMode>(mode_index); + RecordingSource::RecordingMode mode = + static_cast<RecordingSource::RecordingMode>(mode_index); base::TimeDelta min_time = base::TimeDelta::Max(); size_t memory_used = 0; @@ -164,7 +162,7 @@ min_time = duration; } - if (mode == Picture::RECORD_NORMALLY) { + if (mode == RecordingSource::RECORD_NORMALLY) { record_results_.bytes_used += memory_used; record_results_.pixels_recorded += visible_content_rect.width() * visible_content_rect.height(); @@ -180,49 +178,62 @@ DCHECK(host_ && host_->settings().use_display_lists); - base::TimeDelta min_time = base::TimeDelta::Max(); - size_t memory_used = 0; + for (int mode_index = 0; mode_index < RecordingSource::RECORDING_MODE_COUNT; + mode_index++) { + ContentLayerClient::PaintingControlSetting painting_control = + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL; + switch (static_cast<RecordingSource::RecordingMode>(mode_index)) { + case RecordingSource::RECORD_NORMALLY: + // Already setup for normal recording. + break; + case RecordingSource::RECORD_WITH_SK_NULL_CANVAS: + // TODO(schenney): Remove this when DisplayList recording is the only + // option. For now, fall through and disable construction. + case RecordingSource::RECORD_WITH_PAINTING_DISABLED: + painting_control = + ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED; + break; + case RecordingSource::RECORD_WITH_CACHING_DISABLED: + painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED; + break; + default: + NOTREACHED(); + } + base::TimeDelta min_time = base::TimeDelta::Max(); + size_t memory_used = 0; - // TODO(schenney): What are the corresponding Picture::RecordingMode modes - // for Slimming Paint. We could disable SkPicture creation in - // DrawingDisplayItems, or we could only generate the display list and not - // do any work on it in the compositor, or something else, or all of the - // above. - scoped_refptr<DisplayItemList> display_list; - for (int i = 0; i < record_repeat_count_; ++i) { - // Run for a minimum amount of time to avoid problems with timer - // quantization when the layer is very small. - LapTimer timer(kWarmupRuns, - base::TimeDelta::FromMilliseconds(kTimeLimitMillis), - kTimeCheckInterval); + scoped_refptr<DisplayItemList> display_list; + for (int i = 0; i < record_repeat_count_; ++i) { + // Run for a minimum amount of time to avoid problems with timer + // quantization when the layer is very small. + LapTimer timer(kWarmupRuns, + base::TimeDelta::FromMilliseconds(kTimeLimitMillis), + kTimeCheckInterval); - do { - // TODO(schenney): Cached content will not be regenerated, which skews - // the results significantly in favor of Slimming Paint (or should). - // Add a flag or API call to disable caching, and maybe run the test - // twice, without and with caching. - display_list = painter->PaintContentsToDisplayList( - visible_content_rect, ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + do { + display_list = painter->PaintContentsToDisplayList(visible_content_rect, + painting_control); - if (memory_used) { - // Verify we are recording the same thing each time. - DCHECK(memory_used == display_list->PictureMemoryUsage()); - } else { - memory_used = display_list->PictureMemoryUsage(); - } + if (memory_used) { + // Verify we are recording the same thing each time. + DCHECK(memory_used == display_list->PictureMemoryUsage()); + } else { + memory_used = display_list->PictureMemoryUsage(); + } - timer.NextLap(); - } while (!timer.HasTimeLimitExpired()); - base::TimeDelta duration = - base::TimeDelta::FromMillisecondsD(timer.MsPerLap()); - if (duration < min_time) - min_time = duration; + timer.NextLap(); + } while (!timer.HasTimeLimitExpired()); + base::TimeDelta duration = + base::TimeDelta::FromMillisecondsD(timer.MsPerLap()); + if (duration < min_time) + min_time = duration; + } + + record_results_.bytes_used += memory_used; + record_results_.pixels_recorded += + visible_content_rect.width() * visible_content_rect.height(); + record_results_.total_best_time[mode_index] += min_time; } - - record_results_.bytes_used += memory_used; - record_results_.pixels_recorded += - visible_content_rect.width() * visible_content_rect.height(); - record_results_.total_best_time[Picture::RECORD_NORMALLY] += min_time; } RasterizeAndRecordBenchmark::RecordResults::RecordResults()
diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h index 5ae45fa..30dcde0 100644 --- a/cc/debug/rasterize_and_record_benchmark.h +++ b/cc/debug/rasterize_and_record_benchmark.h
@@ -51,7 +51,7 @@ int pixels_recorded; size_t bytes_used; - base::TimeDelta total_best_time[Picture::RECORDING_MODE_COUNT]; + base::TimeDelta total_best_time[RecordingSource::RECORDING_MODE_COUNT]; }; RecordResults record_results_;
diff --git a/cc/debug/rendering_stats.cc b/cc/debug/rendering_stats.cc index 9c62a3c5..2247b3a 100644 --- a/cc/debug/rendering_stats.cc +++ b/cc/debug/rendering_stats.cc
@@ -17,10 +17,13 @@ } void RenderingStats::TimeDeltaList::AddToTracedValue( + const char* name, base::debug::TracedValue* list_value) const { + list_value->BeginArray(name); for (const auto& value : values) { list_value->AppendDouble(value.InMillisecondsF()); } + list_value->EndArray(); } void RenderingStats::TimeDeltaList::Add(const TimeDeltaList& other) { @@ -48,30 +51,22 @@ record_data->SetInteger("visible_content_area", visible_content_area); record_data->SetInteger("approximated_visible_content_area", approximated_visible_content_area); - record_data->BeginArray("draw_duration_ms"); - draw_duration.AddToTracedValue(record_data.get()); - record_data->EndArray(); + draw_duration.AddToTracedValue("draw_duration_ms", record_data.get()); - record_data->BeginArray("draw_duration_estimate_ms"); - draw_duration_estimate.AddToTracedValue(record_data.get()); - record_data->EndArray(); + draw_duration_estimate.AddToTracedValue("draw_duration_estimate_ms", + record_data.get()); - record_data->BeginArray("begin_main_frame_to_commit_duration_ms"); - begin_main_frame_to_commit_duration.AddToTracedValue(record_data.get()); - record_data->EndArray(); + begin_main_frame_to_commit_duration.AddToTracedValue( + "begin_main_frame_to_commit_duration_ms", record_data.get()); - record_data->BeginArray("begin_main_frame_to_commit_duration_estimate_ms"); begin_main_frame_to_commit_duration_estimate.AddToTracedValue( - record_data.get()); - record_data->EndArray(); + "begin_main_frame_to_commit_duration_estimate_ms", record_data.get()); - record_data->BeginArray("commit_to_activate_duration_ms"); - commit_to_activate_duration.AddToTracedValue(record_data.get()); - record_data->EndArray(); + commit_to_activate_duration.AddToTracedValue("commit_to_activate_duration_ms", + record_data.get()); - record_data->BeginArray("commit_to_activate_duration_estimate_ms"); - commit_to_activate_duration_estimate.AddToTracedValue(record_data.get()); - record_data->EndArray(); + commit_to_activate_duration_estimate.AddToTracedValue( + "commit_to_activate_duration_estimate_ms", record_data.get()); return record_data; }
diff --git a/cc/debug/rendering_stats.h b/cc/debug/rendering_stats.h index 24acb93..3a72371 100644 --- a/cc/debug/rendering_stats.h +++ b/cc/debug/rendering_stats.h
@@ -24,7 +24,8 @@ ~TimeDeltaList(); void Append(base::TimeDelta value); - void AddToTracedValue(base::debug::TracedValue* list_value) const; + void AddToTracedValue(const char* name, + base::debug::TracedValue* list_value) const; void Add(const TimeDeltaList& other);
diff --git a/cc/debug/rendering_stats_unittest.cc b/cc/debug/rendering_stats_unittest.cc index a634093..c1e189ac 100644 --- a/cc/debug/rendering_stats_unittest.cc +++ b/cc/debug/rendering_stats_unittest.cc
@@ -15,9 +15,7 @@ static std::string ToString(const RenderingStats::TimeDeltaList& list) { scoped_refptr<base::debug::TracedValue> value = new base::debug::TracedValue(); - value->BeginArray("list_value"); - list.AddToTracedValue(value.get()); - value->EndArray(); + list.AddToTracedValue("list_value", value.get()); return value->ToString(); }
diff --git a/cc/debug/traced_value.h b/cc/debug/traced_value.h index c5ea30a..db0a08a 100644 --- a/cc/debug/traced_value.h +++ b/cc/debug/traced_value.h
@@ -6,10 +6,16 @@ #define CC_DEBUG_TRACED_VALUE_H_ namespace base { -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015. +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc {
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 0208627..d899a85 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -143,7 +143,10 @@ ScrollInputType type) = 0; virtual bool HaveWheelEventHandlersAt(const gfx::Point& viewport_point) = 0; - virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_point) = 0; + + // Whether the page should be given the opportunity to suppress scrolling by + // consuming touch events that started at |viewport_point|. + virtual bool DoTouchEventsBlockScrollAt(const gfx::Point& viewport_point) = 0; // Calling CreateLatencyInfoSwapPromiseMonitor() to get a scoped // LatencyInfoSwapPromiseMonitor. During the life time of the
diff --git a/cc/input/top_controls_manager.cc b/cc/input/top_controls_manager.cc index 1615d7f..615afb0 100644 --- a/cc/input/top_controls_manager.cc +++ b/cc/input/top_controls_manager.cc
@@ -39,7 +39,6 @@ : client_(client), animation_direction_(NO_ANIMATION), permitted_state_(BOTH), - top_controls_height_(0.f), current_scroll_delta_(0.f), controls_scroll_begin_offset_(0.f), top_controls_show_threshold_(top_controls_hide_threshold), @@ -51,12 +50,20 @@ TopControlsManager::~TopControlsManager() { } -float TopControlsManager::ControlsTopOffset() { - return client_->ControlsTopOffset(); +float TopControlsManager::ControlsTopOffset() const { + return ContentTopOffset() - TopControlsHeight(); } -float TopControlsManager::ContentTopOffset() { - return client_->ControlsTopOffset() + top_controls_height_; +float TopControlsManager::ContentTopOffset() const { + return TopControlsShownRatio() * TopControlsHeight(); +} + +float TopControlsManager::TopControlsShownRatio() const { + return client_->CurrentTopControlsShownRatio(); +} + +float TopControlsManager::TopControlsHeight() const { + return client_->TopControlsHeight(); } void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, @@ -72,31 +79,25 @@ return; // Don't do anything if there is no change in offset. - float final_controls_position = 0.f; - if (constraints == HIDDEN || current == HIDDEN) { - final_controls_position = -top_controls_height_; - } - if (final_controls_position == client_->ControlsTopOffset()) { - return; - } - - AnimationDirection animation_direction = SHOWING_CONTROLS; + float final_shown_ratio = 1.f; if (constraints == HIDDEN || current == HIDDEN) - animation_direction = HIDING_CONTROLS; - ResetAnimations(); + final_shown_ratio = 0.f; + if (final_shown_ratio == TopControlsShownRatio()) + return; + if (animate) { - SetupAnimation(animation_direction); + SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS); } else { - client_->SetControlsTopOffset(final_controls_position); + ResetAnimations(); + client_->SetCurrentTopControlsShownRatio(final_shown_ratio); } - client_->DidChangeTopControlsPosition(); } void TopControlsManager::ScrollBegin() { DCHECK(!pinch_gesture_active_); ResetAnimations(); current_scroll_delta_ = 0.f; - controls_scroll_begin_offset_ = client_->ControlsTopOffset(); + controls_scroll_begin_offset_ = ContentTopOffset(); } gfx::Vector2dF TopControlsManager::ScrollBy( @@ -111,19 +112,21 @@ current_scroll_delta_ += pending_delta.y(); - float old_offset = client_->ControlsTopOffset(); - SetControlsTopOffset(controls_scroll_begin_offset_ - current_scroll_delta_); + float old_offset = ContentTopOffset(); + client_->SetCurrentTopControlsShownRatio( + (controls_scroll_begin_offset_ - current_scroll_delta_) / + TopControlsHeight()); // If the controls are fully visible, treat the current position as the // new baseline even if the gesture didn't end. - if (client_->ControlsTopOffset() == 0.f) { + if (TopControlsShownRatio() == 1.f) { current_scroll_delta_ = 0.f; - controls_scroll_begin_offset_ = 0.f; + controls_scroll_begin_offset_ = ContentTopOffset(); } ResetAnimations(); - gfx::Vector2dF applied_delta(0.f, old_offset - client_->ControlsTopOffset()); + gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset()); return pending_delta - applied_delta; } @@ -146,44 +149,20 @@ ScrollBegin(); } -void TopControlsManager::SetControlsTopOffset(float controls_top_offset) { - controls_top_offset = std::max(controls_top_offset, -top_controls_height_); - controls_top_offset = std::min(controls_top_offset, 0.f); - - if (client_->ControlsTopOffset() == controls_top_offset) - return; - - client_->SetControlsTopOffset(controls_top_offset); - - client_->DidChangeTopControlsPosition(); -} - -void TopControlsManager::SetTopControlsHeight(float top_controls_height) { - DCHECK_GE(top_controls_height, 0); - - if (top_controls_height == top_controls_height_) - return; - - ResetAnimations(); - float top_controls_offset = client_->ControlsTopOffset(); - top_controls_height_ = top_controls_height; - SetControlsTopOffset(top_controls_offset); - StartAnimationIfNecessary(); -} - gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { if (!top_controls_animation_ || !client_->HaveRootScrollLayer()) return gfx::Vector2dF(); base::TimeDelta time = monotonic_time - base::TimeTicks(); - float old_offset = client_->ControlsTopOffset(); - SetControlsTopOffset(top_controls_animation_->GetValue(time)); + float old_offset = ContentTopOffset(); + client_->SetCurrentTopControlsShownRatio( + top_controls_animation_->GetValue(time)); if (IsAnimationCompleteAtTime(monotonic_time)) ResetAnimations(); - gfx::Vector2dF scroll_delta(0.f, client_->ControlsTopOffset() - old_offset); + gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset); return scroll_delta; } @@ -193,15 +172,9 @@ } void TopControlsManager::SetupAnimation(AnimationDirection direction) { - DCHECK(direction != NO_ANIMATION); - - if (direction == SHOWING_CONTROLS && client_->ControlsTopOffset() == 0) - return; - - if (direction == HIDING_CONTROLS && - client_->ControlsTopOffset() == -top_controls_height_) { - return; - } + DCHECK_NE(NO_ANIMATION, direction); + DCHECK_IMPLIES(direction == HIDING_CONTROLS, TopControlsShownRatio() > 0.f); + DCHECK_IMPLIES(direction == SHOWING_CONTROLS, TopControlsShownRatio() < 1.f); if (top_controls_animation_ && animation_direction_ == direction) return; @@ -209,42 +182,32 @@ top_controls_animation_ = KeyframedFloatAnimationCurve::Create(); base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks(); top_controls_animation_->AddKeyframe( - FloatKeyframe::Create(start_time, client_->ControlsTopOffset(), nullptr)); - float max_ending_offset = - (direction == SHOWING_CONTROLS ? 1 : -1) * top_controls_height_; + FloatKeyframe::Create(start_time, TopControlsShownRatio(), nullptr)); + float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1); top_controls_animation_->AddKeyframe(FloatKeyframe::Create( start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs), - client_->ControlsTopOffset() + max_ending_offset, + TopControlsShownRatio() + max_ending_ratio, EaseTimingFunction::Create())); animation_direction_ = direction; client_->DidChangeTopControlsPosition(); } void TopControlsManager::StartAnimationIfNecessary() { - if (client_->ControlsTopOffset() != 0 - && client_->ControlsTopOffset() != -top_controls_height_) { - AnimationDirection show_controls = NO_ANIMATION; + if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f) + return; - float top_controls_show_height = - top_controls_height_ * top_controls_hide_threshold_; - float top_controls_hide_height = - top_controls_height_ * (1.f - top_controls_show_threshold_); - if (client_->ControlsTopOffset() >= -top_controls_show_height) { - // If we're showing so much that the hide threshold won't trigger, show. - show_controls = SHOWING_CONTROLS; - } else if (client_->ControlsTopOffset() <= -top_controls_hide_height) { - // If we're showing so little that the show threshold won't trigger, hide. - show_controls = HIDING_CONTROLS; - } else { - // If we could be either showing or hiding, we determine which one to - // do based on whether or not the total scroll delta was moving up or - // down. - show_controls = current_scroll_delta_ <= 0.f ? - SHOWING_CONTROLS : HIDING_CONTROLS; - } - - if (show_controls != NO_ANIMATION) - SetupAnimation(show_controls); + if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) { + // If we're showing so much that the hide threshold won't trigger, show. + SetupAnimation(SHOWING_CONTROLS); + } else if (TopControlsShownRatio() <= top_controls_show_threshold_) { + // If we're showing so little that the show threshold won't trigger, hide. + SetupAnimation(HIDING_CONTROLS); + } else { + // If we could be either showing or hiding, we determine which one to + // do based on whether or not the total scroll delta was moving up or + // down. + SetupAnimation(current_scroll_delta_ <= 0.f ? SHOWING_CONTROLS + : HIDING_CONTROLS); } } @@ -253,11 +216,10 @@ return true; base::TimeDelta animation_time = time - base::TimeTicks(); - float new_offset = top_controls_animation_->GetValue(animation_time); + float new_ratio = top_controls_animation_->GetValue(animation_time); - if ((animation_direction_ == SHOWING_CONTROLS && new_offset >= 0) || - (animation_direction_ == HIDING_CONTROLS - && new_offset <= -top_controls_height_)) { + if ((animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) || + (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f)) { return true; } return false;
diff --git a/cc/input/top_controls_manager.h b/cc/input/top_controls_manager.h index 69408ae..06f623d 100644 --- a/cc/input/top_controls_manager.h +++ b/cc/input/top_controls_manager.h
@@ -38,8 +38,10 @@ float top_controls_hide_threshold); virtual ~TopControlsManager(); - float ControlsTopOffset(); - float ContentTopOffset(); + float ControlsTopOffset() const; + float ContentTopOffset() const; + float TopControlsShownRatio() const; + float TopControlsHeight() const; KeyframedFloatAnimationCurve* animation() { return top_controls_animation_.get(); @@ -60,9 +62,6 @@ void PinchEnd(); gfx::Vector2dF Animate(base::TimeTicks monotonic_time); - void SetControlsTopOffset(float offset); - void SetTopControlsHeight(float top_controls_height); - float top_controls_height() { return top_controls_height_; } protected: TopControlsManager(TopControlsManagerClient* client, @@ -81,7 +80,6 @@ scoped_ptr<KeyframedFloatAnimationCurve> top_controls_animation_; AnimationDirection animation_direction_; TopControlsState permitted_state_; - float top_controls_height_; float current_scroll_delta_; float controls_scroll_begin_offset_;
diff --git a/cc/input/top_controls_manager_client.h b/cc/input/top_controls_manager_client.h index 53b5978f..a0f2f5b 100644 --- a/cc/input/top_controls_manager_client.h +++ b/cc/input/top_controls_manager_client.h
@@ -11,8 +11,9 @@ class CC_EXPORT TopControlsManagerClient { public: - virtual void SetControlsTopOffset(float offset) = 0; - virtual float ControlsTopOffset() const = 0; + virtual float TopControlsHeight() const = 0; + virtual void SetCurrentTopControlsShownRatio(float ratio) = 0; + virtual float CurrentTopControlsShownRatio() const = 0; virtual void DidChangeTopControlsPosition() = 0; virtual bool HaveRootScrollLayer() const = 0;
diff --git a/cc/input/top_controls_manager_unittest.cc b/cc/input/top_controls_manager_unittest.cc index 0be40ca..80495f6e 100644 --- a/cc/input/top_controls_manager_unittest.cc +++ b/cc/input/top_controls_manager_unittest.cc
@@ -4,6 +4,8 @@ #include "cc/input/top_controls_manager.h" +#include <algorithm> + #include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/input/top_controls_manager_client.h" @@ -27,13 +29,13 @@ : host_impl_(&proxy_, &shared_bitmap_manager_), redraw_needed_(false), update_draw_properties_needed_(false), - top_controls_top_offset_(0.f), + top_controls_shown_ratio_(1.f), top_controls_height_(top_controls_height), top_controls_show_threshold_(top_controls_show_threshold), top_controls_hide_threshold_(top_controls_hide_threshold) { - active_tree_ = - LayerTreeImpl::create(&host_impl_, new SyncedProperty<ScaleGroup>, - new SyncedElasticOverscroll); + active_tree_ = LayerTreeImpl::create( + &host_impl_, new SyncedProperty<ScaleGroup>, new SyncedTopControls, + new SyncedElasticOverscroll); root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1); } @@ -46,11 +48,17 @@ bool HaveRootScrollLayer() const override { return true; } - void SetControlsTopOffset(float offset) override { - top_controls_top_offset_ = offset; + float TopControlsHeight() const override { return top_controls_height_; } + + void SetCurrentTopControlsShownRatio(float ratio) override { + ratio = std::max(ratio, 0.f); + ratio = std::min(ratio, 1.f); + top_controls_shown_ratio_ = ratio; } - float ControlsTopOffset() const override { return top_controls_top_offset_; } + float CurrentTopControlsShownRatio() const override { + return top_controls_shown_ratio_; + } LayerImpl* rootScrollLayer() { return root_scroll_layer_.get(); @@ -61,11 +69,12 @@ manager_ = TopControlsManager::Create(this, top_controls_show_threshold_, top_controls_hide_threshold_); - manager_->SetTopControlsHeight(top_controls_height_); } return manager_.get(); } + void SetTopControlsHeight(float height) { top_controls_height_ = height; } + private: FakeImplProxy proxy_; TestSharedBitmapManager shared_bitmap_manager_; @@ -76,7 +85,7 @@ bool redraw_needed_; bool update_draw_properties_needed_; - float top_controls_top_offset_; + float top_controls_shown_ratio_; float top_controls_height_; float top_controls_show_threshold_; float top_controls_hide_threshold_; @@ -90,55 +99,56 @@ // Scroll down to hide the controls entirely. manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); - EXPECT_EQ(-30.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset()); manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); - EXPECT_EQ(-60.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-60.f, manager->ControlsTopOffset()); manager->ScrollBy(gfx::Vector2dF(0.f, 100.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); // Scroll back up a bit and ensure the controls don't move until we cross // the threshold. manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); // After hitting the threshold, further scrolling up should result in the top // controls showing. manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); - EXPECT_EQ(-90.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-90.f, manager->ControlsTopOffset()); manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); - EXPECT_EQ(-40.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-40.f, manager->ControlsTopOffset()); // Reset the scroll threshold by going further up the page than the initial // threshold. manager->ScrollBy(gfx::Vector2dF(0.f, -100.f)); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); // See that scrolling down the page now will result in the controls hiding. manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); - EXPECT_EQ(-20.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-20.f, manager->ControlsTopOffset()); manager->ScrollEnd(); } -TEST(TopControlsManagerTest, PartialShownHideAnimation) { +// Flaky. See http://crbug.com/456617. +TEST(TopControlsManagerTest, DISABLED_PartialShownHideAnimation) { MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); TopControlsManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollEnd(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); - EXPECT_EQ(-85.f, manager->ControlsTopOffset()); - EXPECT_EQ(15.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -152,8 +162,8 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, PartialShownShowAnimation) { @@ -161,14 +171,14 @@ TopControlsManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollEnd(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, -70.f)); - EXPECT_EQ(-30.f, manager->ControlsTopOffset()); - EXPECT_EQ(70.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -182,8 +192,8 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); - EXPECT_EQ(100.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) { @@ -193,8 +203,8 @@ manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); - EXPECT_EQ(-20.f, manager->ControlsTopOffset()); - EXPECT_EQ(80.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-20.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(80.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -208,19 +218,21 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); - EXPECT_EQ(100.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) { +// Flaky. See http://crbug.com/456617. +TEST(TopControlsManagerTest, + DISABLED_PartialHiddenWithAmbiguousThresholdHides) { MockTopControlsManagerClient client(100.f, 0.25f, 0.25f); TopControlsManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); - EXPECT_EQ(-30.f, manager->ControlsTopOffset()); - EXPECT_EQ(70.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -234,8 +246,8 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) { @@ -243,14 +255,14 @@ TopControlsManager* manager = client.manager(); manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, -20.f)); - EXPECT_EQ(-80.f, manager->ControlsTopOffset()); - EXPECT_EQ(20.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-80.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(20.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -264,8 +276,8 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) { @@ -273,14 +285,14 @@ TopControlsManager* manager = client.manager(); manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, -30.f)); - EXPECT_EQ(-70.f, manager->ControlsTopOffset()); - EXPECT_EQ(30.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-70.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(30.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); @@ -294,8 +306,8 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); - EXPECT_EQ(100.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, PinchIgnoresScroll) { @@ -304,36 +316,37 @@ // Hide the controls. manager->ScrollBegin(); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); manager->PinchBegin(); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); // Scrolls are ignored during pinch. manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); manager->PinchEnd(); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); // Scrolls should no long be ignored. manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); - EXPECT_EQ(-85.f, manager->ControlsTopOffset()); - EXPECT_EQ(15.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset()); manager->ScrollEnd(); EXPECT_TRUE(manager->animation()); } -TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) { +// Flaky. See http://crbug.com/456617. +TEST(TopControlsManagerTest, DISABLED_PinchBeginStartsAnimationIfNecessary) { MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); TopControlsManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); manager->PinchBegin(); EXPECT_FALSE(manager->animation()); @@ -342,8 +355,8 @@ EXPECT_FALSE(manager->animation()); manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); - EXPECT_EQ(-85.f, manager->ControlsTopOffset()); - EXPECT_EQ(15.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset()); manager->PinchBegin(); EXPECT_TRUE(manager->animation()); @@ -362,8 +375,8 @@ EXPECT_FALSE(manager->animation()); manager->ScrollBy(gfx::Vector2dF(0.f, -55.f)); - EXPECT_EQ(-45.f, manager->ControlsTopOffset()); - EXPECT_EQ(55.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-45.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(55.f, manager->ContentTopOffset()); EXPECT_FALSE(manager->animation()); manager->ScrollEnd(); @@ -378,25 +391,42 @@ previous_offset = manager->ControlsTopOffset(); } EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); } TEST(TopControlsManagerTest, HeightChangeMaintainsFullyVisibleControls) { MockTopControlsManagerClient client(0.f, 0.5f, 0.5f); TopControlsManager* manager = client.manager(); - EXPECT_EQ(0.f, manager->top_controls_height()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); - manager->SetTopControlsHeight(100.f); + client.SetTopControlsHeight(100.f); EXPECT_FALSE(manager->animation()); - EXPECT_EQ(100.f, manager->top_controls_height()); - EXPECT_EQ(0, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(100.f, manager->TopControlsHeight()); + EXPECT_FLOAT_EQ(0, manager->ControlsTopOffset()); - manager->SetTopControlsHeight(50.f); + client.SetTopControlsHeight(50.f); EXPECT_FALSE(manager->animation()); - EXPECT_EQ(50.f, manager->top_controls_height()); + EXPECT_FLOAT_EQ(50.f, manager->TopControlsHeight()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); +} + +TEST(TopControlsManagerTest, GrowingHeightKeepsTopControlsHidden) { + MockTopControlsManagerClient client(0.f, 0.5f, 0.5f); + TopControlsManager* manager = client.manager(); + manager->UpdateTopControlsState(HIDDEN, HIDDEN, false); EXPECT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_EQ(0.f, manager->ContentTopOffset()); + + client.SetTopControlsHeight(50.f); + EXPECT_FALSE(manager->animation()); + EXPECT_EQ(-50.f, manager->ControlsTopOffset()); + EXPECT_EQ(0.f, manager->ContentTopOffset()); + + client.SetTopControlsHeight(100.f); + EXPECT_FALSE(manager->animation()); + EXPECT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_EQ(0.f, manager->ContentTopOffset()); } TEST(TopControlsManagerTest, ShrinkingHeightKeepsTopControlsHidden) { @@ -405,56 +435,20 @@ manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-100.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollEnd(); - manager->SetTopControlsHeight(50.f); + client.SetTopControlsHeight(50.f); EXPECT_FALSE(manager->animation()); - EXPECT_EQ(-50.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(-50.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); - manager->SetTopControlsHeight(0.f); + client.SetTopControlsHeight(0.f); EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, HiddenTopControlsReadjustOnIncreasedHeight) { - MockTopControlsManagerClient client(10.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); - - manager->ScrollBegin(); - manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); - EXPECT_EQ(-10.f, manager->ControlsTopOffset()); - EXPECT_EQ(0.f, manager->ContentTopOffset()); - manager->ScrollEnd(); - - manager->SetTopControlsHeight(15.f); - EXPECT_TRUE(manager->animation()); - base::TimeTicks time = base::TimeTicks::Now(); - float previous_offset = manager->ControlsTopOffset(); - while (manager->animation()) { - time = base::TimeDelta::FromMicroseconds(100) + time; - manager->Animate(time); - EXPECT_LT(manager->ControlsTopOffset(), previous_offset); - previous_offset = manager->ControlsTopOffset(); - } - EXPECT_FALSE(manager->animation()); - EXPECT_EQ(-15.f, manager->ControlsTopOffset()); - - manager->SetTopControlsHeight(35.f); - EXPECT_TRUE(manager->animation()); - time = base::TimeTicks::Now(); - previous_offset = manager->ControlsTopOffset(); - while (manager->animation()) { - time = base::TimeDelta::FromMicroseconds(100) + time; - manager->Animate(time); - EXPECT_GT(manager->ControlsTopOffset(), previous_offset); - previous_offset = manager->ControlsTopOffset(); - } - EXPECT_FALSE(manager->animation()); - EXPECT_EQ(0.f, manager->ControlsTopOffset()); -} } // namespace } // namespace cc
diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc index 53c7120..6af92ec 100644 --- a/cc/layers/content_layer.cc +++ b/cc/layers/content_layer.cc
@@ -26,9 +26,8 @@ void ContentLayerPainter::Paint(SkCanvas* canvas, const gfx::Rect& content_rect) { - client_->PaintContents(canvas, - content_rect, - ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + client_->PaintContents(canvas, content_rect, + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); } scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) { @@ -128,9 +127,8 @@ SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(width, height, nullptr, 0); - client_->PaintContents(canvas, - gfx::Rect(width, height), - ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + client_->PaintContents(canvas, gfx::Rect(width, height), + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); return picture; }
diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h index c8d3a7e..4f9c754e 100644 --- a/cc/layers/content_layer_client.h +++ b/cc/layers/content_layer_client.h
@@ -19,18 +19,19 @@ class CC_EXPORT ContentLayerClient { public: - enum GraphicsContextStatus { - GRAPHICS_CONTEXT_DISABLED, - GRAPHICS_CONTEXT_ENABLED + enum PaintingControlSetting { + PAINTING_BEHAVIOR_NORMAL, + DISPLAY_LIST_CONSTRUCTION_DISABLED, + DISPLAY_LIST_CACHING_DISABLED }; virtual void PaintContents(SkCanvas* canvas, const gfx::Rect& clip, - GraphicsContextStatus gc_status) = 0; + PaintingControlSetting painting_status) = 0; virtual scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) = 0; + PaintingControlSetting painting_status) = 0; // If true the layer may skip clearing the background before rasterizing, // because it will cover any uncleared data with content.
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index cdb000f..60d984b 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -69,11 +69,10 @@ HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), - typeface_(skia::AdoptRef( - SkTypeface::CreateFromName("monospace", SkTypeface::kBold))), fps_graph_(60.0, 80.0), paint_time_graph_(16.0, 48.0), - fade_step_(0) {} + fade_step_(0) { +} HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() {} @@ -173,36 +172,36 @@ return; SkISize canvas_size; - if (hud_canvas_) - canvas_size = hud_canvas_->getDeviceSize(); + if (hud_surface_) + canvas_size = hud_surface_->getCanvas()->getDeviceSize(); else canvas_size.set(0, 0); if (canvas_size.width() != content_bounds().width() || - canvas_size.height() != content_bounds().height() || !hud_canvas_) { + canvas_size.height() != content_bounds().height() || !hud_surface_) { TRACE_EVENT0("cc", "ResizeHudCanvas"); - bool opaque = false; - hud_canvas_ = make_scoped_ptr(skia::CreateBitmapCanvas( - content_bounds().width(), content_bounds().height(), opaque)); + + hud_surface_ = skia::AdoptRef(SkSurface::NewRasterN32Premul( + content_bounds().width(), content_bounds().height())); } UpdateHudContents(); { TRACE_EVENT0("cc", "DrawHudContents"); - hud_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); - hud_canvas_->save(); - hud_canvas_->scale(contents_scale_x(), contents_scale_y()); + hud_surface_->getCanvas()->clear(SkColorSetARGB(0, 0, 0, 0)); + hud_surface_->getCanvas()->save(); + hud_surface_->getCanvas()->scale(contents_scale_x(), contents_scale_y()); - DrawHudContents(hud_canvas_.get()); + DrawHudContents(hud_surface_->getCanvas()); - hud_canvas_->restore(); + hud_surface_->getCanvas()->restore(); } TRACE_EVENT0("cc", "UploadHudTexture"); SkImageInfo info; size_t row_bytes = 0; - const void* pixels = hud_canvas_->peekPixels(&info, &row_bytes); + const void* pixels = hud_surface_->getCanvas()->peekPixels(&info, &row_bytes); DCHECK(pixels); gfx::Rect content_rect(content_bounds()); DCHECK(info.colorType() == kN32_SkColorType); @@ -300,7 +299,7 @@ paint->setTextSize(size); paint->setTextAlign(align); - paint->setTypeface(typeface_.get()); + paint->setTypeface(layer_tree_impl()->settings().hud_typeface.get()); canvas->drawText(text.c_str(), text.length(), x, y, *paint); paint->setAntiAlias(anti_alias); @@ -706,7 +705,7 @@ SkPaint label_paint = CreatePaint(); label_paint.setTextSize(kFontHeight); - label_paint.setTypeface(typeface_.get()); + label_paint.setTypeface(layer_tree_impl()->settings().hud_typeface.get()); label_paint.setColor(stroke_color); const SkScalar label_text_width =
diff --git a/cc/layers/heads_up_display_layer_impl.h b/cc/layers/heads_up_display_layer_impl.h index 3e9436b..abba5dc 100644 --- a/cc/layers/heads_up_display_layer_impl.h +++ b/cc/layers/heads_up_display_layer_impl.h
@@ -126,9 +126,7 @@ void ReleaseUnmatchedSizeResources(ResourceProvider* resource_provider); ScopedPtrVector<ScopedResource> resources_; - scoped_ptr<SkCanvas> hud_canvas_; - - skia::RefPtr<SkTypeface> typeface_; + skia::RefPtr<SkSurface> hud_surface_; Graph fps_graph_; Graph paint_time_graph_;
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index cff75e7..01e67c5ed 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -71,6 +71,7 @@ force_render_surface_(false), transform_is_invertible_(true), has_render_surface_(false), + scroll_blocks_on_(ScrollBlocksOnNone), background_color_(0), opacity_(1.f), blend_mode_(SkXfermode::kSrcOver_Mode), @@ -758,6 +759,14 @@ SetNeedsCommit(); } +void Layer::SetScrollBlocksOn(ScrollBlocksOn scroll_blocks_on) { + DCHECK(IsPropertyChangeAllowed()); + if (scroll_blocks_on_ == scroll_blocks_on) + return; + scroll_blocks_on_ = scroll_blocks_on; + SetNeedsCommit(); +} + void Layer::SetDrawCheckerboardForMissingTiles(bool checkerboard) { DCHECK(IsPropertyChangeAllowed()); if (draw_checkerboard_for_missing_tiles_ == checkerboard) @@ -911,6 +920,7 @@ layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); layer->SetTouchEventHandlerRegion(touch_event_handler_region_); + layer->SetScrollBlocksOn(scroll_blocks_on_); layer->SetContentsOpaque(contents_opaque_); if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating()) layer->SetOpacity(opacity_);
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index db472c6..cf1356c 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -25,6 +25,7 @@ #include "cc/layers/layer_position_constraint.h" #include "cc/layers/paint_properties.h" #include "cc/layers/render_surface.h" +#include "cc/layers/scroll_blocks_on.h" #include "cc/output/filter_operations.h" #include "cc/trees/property_tree.h" #include "skia/ext/refptr.h" @@ -43,10 +44,16 @@ } namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc { @@ -305,6 +312,9 @@ return touch_event_handler_region_; } + void SetScrollBlocksOn(ScrollBlocksOn scroll_blocks_on); + ScrollBlocksOn scroll_blocks_on() const { return scroll_blocks_on_; } + void set_did_scroll_callback(const base::Closure& callback) { did_scroll_callback_ = callback; } @@ -667,6 +677,7 @@ bool force_render_surface_ : 1; bool transform_is_invertible_ : 1; bool has_render_surface_ : 1; + ScrollBlocksOn scroll_blocks_on_ : 3; Region non_fast_scrollable_region_; Region touch_event_handler_region_; gfx::PointF position_;
diff --git a/cc/layers/layer_client.h b/cc/layers/layer_client.h index 4b98a95..efdbe510 100644 --- a/cc/layers/layer_client.h +++ b/cc/layers/layer_client.h
@@ -11,10 +11,16 @@ #include "cc/base/cc_export.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 50501a9..eae36859 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -54,6 +54,7 @@ should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), have_scroll_event_handlers_(false), + scroll_blocks_on_(ScrollBlocksOnNone), user_scrollable_horizontal_(true), user_scrollable_vertical_(true), stacking_order_changed_(false), @@ -392,7 +393,8 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( const gfx::PointF& screen_space_point, - InputHandler::ScrollInputType type) const { + InputHandler::ScrollInputType type, + ScrollBlocksOn effective_block_mode) const { if (should_scroll_on_main_thread()) { TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); return InputHandler::ScrollOnMainThread; @@ -430,7 +432,14 @@ } } - if (type == InputHandler::Wheel && have_wheel_event_handlers()) { + if (have_scroll_event_handlers() && + effective_block_mode & ScrollBlocksOnScrollEvent) { + TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed ScrollEventHandlers"); + return InputHandler::ScrollOnMainThread; + } + + if (type == InputHandler::Wheel && have_wheel_event_handlers() && + effective_block_mode & ScrollBlocksOnWheelEvent) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); return InputHandler::ScrollOnMainThread; } @@ -487,6 +496,7 @@ layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); + layer->SetScrollBlocksOn(scroll_blocks_on_); layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); layer->SetTouchEventHandlerRegion(touch_event_handler_region_); layer->SetContentsOpaque(contents_opaque_); @@ -649,6 +659,17 @@ result->Set("TouchRegion", region.release()); } + if (scroll_blocks_on_) { + list = new base::ListValue; + if (scroll_blocks_on_ & ScrollBlocksOnStartTouch) + list->AppendString("StartTouch"); + if (scroll_blocks_on_ & ScrollBlocksOnWheelEvent) + list->AppendString("WheelEvent"); + if (scroll_blocks_on_ & ScrollBlocksOnScrollEvent) + list->AppendString("ScrollEvent"); + result->Set("ScrollBlocksOn", list); + } + list = new base::ListValue; for (size_t i = 0; i < children_.size(); ++i) list->Append(children_[i]->LayerTreeAsJson()); @@ -1088,20 +1109,7 @@ gfx::ScrollOffset LayerImpl::PullDeltaForMainThread() { RefreshFromScrollDelegate(); - - // TODO(aelias, miletus): Remove all this temporary flooring machinery when - // Blink fully supports fractional scrolls. - gfx::ScrollOffset current_offset = CurrentScrollOffset(); - gfx::Vector2dF current_delta = ScrollDelta(); - gfx::Vector2dF floored_delta(floor(current_delta.x()), - floor(current_delta.y())); - gfx::Vector2dF diff_delta = floored_delta - current_delta; - gfx::ScrollOffset tmp_offset = ScrollOffsetWithDelta(current_offset, - diff_delta); - scroll_offset_->SetCurrent(tmp_offset); - gfx::ScrollOffset delta = scroll_offset_->PullDeltaForMainThread(); - scroll_offset_->SetCurrent(current_offset); - return delta; + return scroll_offset_->PullDeltaForMainThread(); } void LayerImpl::RefreshFromScrollDelegate() { @@ -1181,6 +1189,9 @@ void LayerImpl::ReleaseResources() {} +void LayerImpl::RecreateResources() { +} + gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { if (!scroll_clip_layer_ || bounds().IsEmpty()) return gfx::ScrollOffset(); @@ -1444,6 +1455,9 @@ non_fast_scrollable_region_.AsValueInto(state); state->EndArray(); } + if (scroll_blocks_on_) { + state->SetInteger("scroll_blocks_on", scroll_blocks_on_); + } state->BeginArray("children"); for (size_t i = 0; i < children_.size(); ++i) {
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 40e295f..96f915f 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -27,6 +27,7 @@ #include "cc/layers/layer_lists.h" #include "cc/layers/layer_position_constraint.h" #include "cc/layers/render_surface_impl.h" +#include "cc/layers/scroll_blocks_on.h" #include "cc/output/filter_operations.h" #include "cc/quads/shared_quad_state.h" #include "cc/resources/resource_provider.h" @@ -41,13 +42,19 @@ #include "ui/gfx/transform.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } -class DictionaryValue; +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +class DictionaryValue; +} // namespace base namespace cc { @@ -479,6 +486,10 @@ return touch_event_handler_region_; } + void SetScrollBlocksOn(ScrollBlocksOn scroll_blocks_on) { + scroll_blocks_on_ = scroll_blocks_on; + } + ScrollBlocksOn scroll_blocks_on() const { return scroll_blocks_on_; } void SetDrawCheckerboardForMissingTiles(bool checkerboard) { draw_checkerboard_for_missing_tiles_ = checkerboard; } @@ -488,7 +499,8 @@ InputHandler::ScrollStatus TryScroll( const gfx::PointF& screen_space_point, - InputHandler::ScrollInputType type) const; + InputHandler::ScrollInputType type, + ScrollBlocksOn effective_block_mode) const; void SetDoubleSided(bool double_sided); bool double_sided() const { return double_sided_; } @@ -535,6 +547,10 @@ // that rendered this layer was lost or a rendering mode switch has occured. virtual void ReleaseResources(); + // Recreate resources that are required after they were released by a + // ReleaseResources call. + virtual void RecreateResources(); + ScrollbarAnimationController* scrollbar_animation_controller() const { return scrollbar_animation_controller_.get(); } @@ -662,6 +678,10 @@ bool should_scroll_on_main_thread_ : 1; bool have_wheel_event_handlers_ : 1; bool have_scroll_event_handlers_ : 1; + + static_assert(ScrollBlocksOnMax < (1 << 3), "ScrollBlocksOn too big"); + ScrollBlocksOn scroll_blocks_on_ : 3; + bool user_scrollable_horizontal_ : 1; bool user_scrollable_vertical_ : 1; bool stacking_order_changed_ : 1;
diff --git a/cc/layers/picture_image_layer.cc b/cc/layers/picture_image_layer.cc index 85bc582..9f35d6e 100644 --- a/cc/layers/picture_image_layer.cc +++ b/cc/layers/picture_image_layer.cc
@@ -47,7 +47,7 @@ void PictureImageLayer::PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) { + ContentLayerClient::PaintingControlSetting painting_control) { if (!bitmap_.width() || !bitmap_.height()) return; @@ -65,12 +65,12 @@ scoped_refptr<DisplayItemList> PictureImageLayer::PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) { + ContentLayerClient::PaintingControlSetting painting_control) { scoped_refptr<DisplayItemList> display_item_list = DisplayItemList::Create(); SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(gfx::RectToSkRect(clip)); - PaintContents(canvas, clip, gc_status); + PaintContents(canvas, clip, painting_control); skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); display_item_list->AppendItem(
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h index 57c7de2..8d40550b 100644 --- a/cc/layers/picture_image_layer.h +++ b/cc/layers/picture_image_layer.h
@@ -26,10 +26,10 @@ void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override; + ContentLayerClient::PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override; + ContentLayerClient::PaintingControlSetting painting_control) override; bool FillsBoundsCompletely() const override; protected:
diff --git a/cc/layers/picture_image_layer_unittest.cc b/cc/layers/picture_image_layer_unittest.cc index acf691dec..5b9375d2 100644 --- a/cc/layers/picture_image_layer_unittest.cc +++ b/cc/layers/picture_image_layer_unittest.cc
@@ -35,7 +35,7 @@ scoped_refptr<DisplayItemList> display_list = layer->PaintContentsToDisplayList( - layer_rect, ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + layer_rect, ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); unsigned char actual_pixels[4 * 200 * 200] = {0}; DrawDisplayList(actual_pixels, layer_rect, display_list);
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index 0b7d699..52288e9 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc
@@ -148,7 +148,7 @@ updated |= recording_source_->UpdateAndExpandInvalidation( client_, &recording_invalidation_, can_use_lcd_text_for_update_, layer_size, visible_layer_rect, update_source_frame_number_, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); last_updated_visible_content_rect_ = visible_content_rect(); if (updated) { @@ -192,9 +192,8 @@ SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(width, height, nullptr, 0); - client_->PaintContents(canvas, - gfx::Rect(width, height), - ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + client_->PaintContents(canvas, gfx::Rect(width, height), + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); return picture; }
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 15059ba..3a0753f5 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -602,8 +602,12 @@ void PictureLayerImpl::ReleaseResources() { // Recreate tilings with new settings, since some of those might change when // we release resources. - tilings_ = CreatePictureLayerTilingSet(); + tilings_ = nullptr; ResetRasterScale(); +} + +void PictureLayerImpl::RecreateResources() { + tilings_ = CreatePictureLayerTilingSet(); // To avoid an edge case after lost context where the tree is up to date but // the tilings have not been managed, request an update draw properties
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index fa40683..e7f4fba7 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h
@@ -62,6 +62,7 @@ void NotifyTileStateChanged(const Tile* tile) override; void DidBeginTracing() override; void ReleaseResources() override; + void RecreateResources() override; skia::RefPtr<SkPicture> GetPicture() override; // PictureLayerTilingClient overrides.
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 0a95f317..600f3e2 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -278,11 +278,14 @@ void ResetTilingsAndRasterScales() { pending_layer_->ReleaseResources(); + EXPECT_FALSE(pending_layer_->tilings()); + pending_layer_->RecreateResources(); + EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + active_layer_->ReleaseResources(); - if (pending_layer_) - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - if (active_layer_) - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + EXPECT_FALSE(active_layer_->tilings()); + active_layer_->RecreateResources(); + EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); } void AssertAllTilesRequired(PictureLayerTiling* tiling) { @@ -711,7 +714,7 @@ VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), pending_pile.get()); } -TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) { +TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { gfx::Size tile_size(400, 400); gfx::Size layer_bounds(1300, 1900); @@ -726,6 +729,8 @@ EXPECT_LT(low_res_factor, 1.f); active_layer_->ReleaseResources(); + EXPECT_FALSE(active_layer_->tilings()); + active_layer_->RecreateResources(); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); SetupDrawPropertiesAndUpdateTiles(active_layer_, @@ -796,6 +801,8 @@ EXPECT_LT(low_res_factor, 1.f); pending_layer_->ReleaseResources(); + EXPECT_FALSE(pending_layer_->tilings()); + pending_layer_->RecreateResources(); EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); SetupDrawPropertiesAndUpdateTiles(pending_layer_, @@ -1326,6 +1333,8 @@ // Drop resources and recreate them, still the same. pending_mask->ReleaseResources(); active_mask->ReleaseResources(); + pending_mask->RecreateResources(); + active_mask->RecreateResources(); SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, false); active_mask->HighResTiling()->CreateAllTilesForTesting(); EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size()); @@ -1369,6 +1378,8 @@ // Drop resources and recreate them, still the same. pending_mask->ReleaseResources(); active_mask->ReleaseResources(); + pending_mask->RecreateResources(); + active_mask->RecreateResources(); SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, false); active_mask->HighResTiling()->CreateAllTilesForTesting(); EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size()); @@ -1475,8 +1486,12 @@ // All tilings should be removed when losing output surface. active_layer_->ReleaseResources(); + EXPECT_FALSE(active_layer_->tilings()); + active_layer_->RecreateResources(); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); pending_layer_->ReleaseResources(); + EXPECT_FALSE(pending_layer_->tilings()); + pending_layer_->RecreateResources(); EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); // This should create new tilings. @@ -3744,8 +3759,12 @@ // All tilings should be removed when losing output surface. active_layer_->ReleaseResources(); + EXPECT_FALSE(active_layer_->tilings()); + active_layer_->RecreateResources(); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); pending_layer_->ReleaseResources(); + EXPECT_FALSE(pending_layer_->tilings()); + pending_layer_->RecreateResources(); EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); // This should create new tilings. @@ -4644,7 +4663,7 @@ Region invalidation(layer_rect); recording_source->UpdateAndExpandInvalidation( &client, &invalidation, false, layer_bounds, layer_rect, frame_number++, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_refptr<RasterSource> pending_raster_source = recording_source->CreateRasterSource(); @@ -4707,7 +4726,7 @@ Region invalidation1(layer_rect); recording_source->UpdateAndExpandInvalidation( &client, &invalidation1, false, layer_bounds, layer_rect, frame_number++, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_refptr<RasterSource> raster_source1 = recording_source->CreateRasterSource(); @@ -4725,7 +4744,7 @@ Region invalidation2(layer_rect); recording_source->UpdateAndExpandInvalidation( &client, &invalidation2, false, layer_bounds, layer_rect, frame_number++, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_refptr<RasterSource> raster_source2 = recording_source->CreateRasterSource();
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 9327e13..afb6096 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc
@@ -20,13 +20,12 @@ class MockContentLayerClient : public ContentLayerClient { public: - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override {} + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override {} scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); }
diff --git a/cc/layers/scroll_blocks_on.h b/cc/layers/scroll_blocks_on.h new file mode 100644 index 0000000..2447298 --- /dev/null +++ b/cc/layers/scroll_blocks_on.h
@@ -0,0 +1,25 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_LAYERS_SCROLL_BLOCKS_ON_H_ +#define CC_LAYERS_SCROLL_BLOCKS_ON_H_ + +enum ScrollBlocksOn { + ScrollBlocksOnNone = 0x0, + ScrollBlocksOnStartTouch = 0x1, + ScrollBlocksOnWheelEvent = 0x2, + ScrollBlocksOnScrollEvent = 0x4, + ScrollBlocksOnMax = ScrollBlocksOnStartTouch | ScrollBlocksOnWheelEvent | + ScrollBlocksOnScrollEvent +}; + +inline ScrollBlocksOn operator|(ScrollBlocksOn a, ScrollBlocksOn b) { + return ScrollBlocksOn(static_cast<int>(a) | static_cast<int>(b)); +} + +inline ScrollBlocksOn& operator|=(ScrollBlocksOn& a, ScrollBlocksOn b) { + return a = a | b; +} + +#endif // CC_LAYERS_SCROLL_BLOCKS_ON_H_
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 09de7d02..b24dcb1 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -107,8 +107,8 @@ // responded to on the main thread as the compositor does not yet implement // scrollbar scrolling. EXPECT_EQ(InputHandler::ScrollOnMainThread, - scrollbar_layer_impl->TryScroll(gfx::Point(0, 0), - InputHandler::Gesture)); + scrollbar_layer_impl->TryScroll( + gfx::Point(0, 0), InputHandler::Gesture, ScrollBlocksOnNone)); // Create and attach an overlay scrollbar. scrollbar.reset(new FakeScrollbar(false, false, true)); @@ -121,8 +121,8 @@ // The user shouldn't be able to drag an overlay scrollbar and the scroll // may be handled in the compositor. EXPECT_EQ(InputHandler::ScrollIgnored, - scrollbar_layer_impl->TryScroll(gfx::Point(0, 0), - InputHandler::Gesture)); + scrollbar_layer_impl->TryScroll( + gfx::Point(0, 0), InputHandler::Gesture, ScrollBlocksOnNone)); } TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) {
diff --git a/cc/output/begin_frame_args.h b/cc/output/begin_frame_args.h index 53745f9..47430ca9 100644 --- a/cc/output/begin_frame_args.h +++ b/cc/output/begin_frame_args.h
@@ -12,11 +12,18 @@ #include "cc/base/cc_export.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +} // namespace base /** * In debug builds we trace the creation origin of BeginFrameArgs objects. We
diff --git a/cc/output/filter_operation.h b/cc/output/filter_operation.h index fc14cb1..157db998 100644 --- a/cc/output/filter_operation.h +++ b/cc/output/filter_operation.h
@@ -16,11 +16,17 @@ #include "ui/gfx/geometry/point.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } -class Value; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +class Value; +} // namespace base namespace cc {
diff --git a/cc/output/filter_operations.h b/cc/output/filter_operations.h index a8c206ea..8e37933 100644 --- a/cc/output/filter_operations.h +++ b/cc/output/filter_operations.h
@@ -12,11 +12,17 @@ #include "cc/output/filter_operation.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } -class Value; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +class Value; +} // namespace base namespace cc {
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 45d98b6..15b2b40 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -2712,6 +2712,8 @@ const gfx::Rect& target_rect) { DCHECK(texture->id()); + // Explicitly release lock, otherwise we can crash when try to lock + // same texture again. current_framebuffer_lock_ = nullptr; SetStencilEnabled(false);
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc index 9a95206..71897ed4 100644 --- a/cc/output/overlay_strategy_single_on_top.cc +++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -119,6 +119,20 @@ return true; } +bool OverlayStrategySingleOnTop::IsInvisibleQuad(const DrawQuad* draw_quad) { + if (draw_quad->material == DrawQuad::SOLID_COLOR) { + const SolidColorDrawQuad* solid_quad = + SolidColorDrawQuad::MaterialCast(draw_quad); + SkColor color = solid_quad->color; + float opacity = solid_quad->opacity(); + float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity; + // Ignore transparent solid color quads. + return solid_quad->ShouldDrawWithBlending() && + alpha < std::numeric_limits<float>::epsilon(); + } + return false; +} + bool OverlayStrategySingleOnTop::Attempt( RenderPassList* render_passes_in_draw_order, OverlayCandidateList* candidate_list) { @@ -143,7 +157,7 @@ ++overlap_iter) { gfx::RectF overlap_rect = overlap_iter->rect; overlap_iter->quadTransform().TransformRect(&overlap_rect); - if (rect.Intersects(overlap_rect)) { + if (rect.Intersects(overlap_rect) && !IsInvisibleQuad(*overlap_iter)) { intersects = true; break; }
diff --git a/cc/output/overlay_strategy_single_on_top.h b/cc/output/overlay_strategy_single_on_top.h index f92e104..a3fec0a6 100644 --- a/cc/output/overlay_strategy_single_on_top.h +++ b/cc/output/overlay_strategy_single_on_top.h
@@ -29,6 +29,10 @@ bool GetCandidateQuadInfo(const DrawQuad& draw_quad, OverlayCandidate* quad_info); + // Returns true if |draw_quad| will not block quads underneath from becoming + // an overlay. + bool IsInvisibleQuad(const DrawQuad* draw_quad); + bool GetTextureQuadInfo(const TextureDrawQuad& quad, OverlayCandidate* quad_info); bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 4682679..6ee388a6 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc
@@ -156,6 +156,17 @@ mailbox, release_callback.Pass()); } +SolidColorDrawQuad* CreateSolidColorQuadAt( + const SharedQuadState* shared_quad_state, + SkColor color, + RenderPass* render_pass, + const gfx::Rect& rect) { + SolidColorDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + quad->SetNew(shared_quad_state, rect, rect, color, false); + return quad; +} + TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider, const SharedQuadState* shared_quad_state, RenderPass* render_pass, @@ -592,6 +603,94 @@ EXPECT_EQ(2U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); + shared_state->opacity = 0.f; + CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(), + kOverlayBottomRightRect); + shared_state = pass->CreateAndAppendSharedQuadState(); + shared_state->opacity = 1.f; + CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(), + kOverlayBottomRightRect); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + RenderPassList original_pass_list; + RenderPass::CopyAll(pass_list, &original_pass_list); + + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + EXPECT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateSolidColorQuadAt(pass->shared_quad_state_list.back(), + SK_ColorTRANSPARENT, pass.get(), + kOverlayBottomRightRect); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), + kOverlayBottomRightRect); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + RenderPassList original_pass_list; + RenderPass::CopyAll(pass_list, &original_pass_list); + + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + EXPECT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); + shared_state->opacity = 0.5f; + CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(), + kOverlayBottomRightRect); + shared_state = pass->CreateAndAppendSharedQuadState(); + shared_state->opacity = 1.f; + CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(), + kOverlayBottomRightRect); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + RenderPassList original_pass_list; + RenderPass::CopyAll(pass_list, &original_pass_list); + + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + EXPECT_EQ(1U, pass_list.size()); + EXPECT_EQ(0U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); + CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(), + kOverlayBottomRightRect)->opaque_rect = + kOverlayBottomRightRect; + CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(), + kOverlayBottomRightRect); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + RenderPassList original_pass_list; + RenderPass::CopyAll(pass_list, &original_pass_list); + + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + EXPECT_EQ(1U, pass_list.size()); + EXPECT_EQ(0U, candidate_list.size()); +} + TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index ceedac65..488ca09 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc
@@ -160,6 +160,11 @@ DrawingFrame* frame, const ScopedResource* texture, const gfx::Rect& target_rect) { + DCHECK(texture->id()); + + // Explicitly release lock, otherwise we can crash when try to lock + // same texture again. + current_framebuffer_lock_ = nullptr; current_framebuffer_lock_ = make_scoped_ptr( new ResourceProvider::ScopedWriteLockSoftware( resource_provider_, texture->id()));
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index 7f689a8..fa25200 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc
@@ -135,7 +135,7 @@ scoped_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(outer_rect.width(), output->info().fWidth); - EXPECT_EQ(outer_rect.width(), output->info().fHeight); + EXPECT_EQ(outer_rect.height(), output->info().fHeight); EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0)); EXPECT_EQ(SK_ColorYELLOW, @@ -233,7 +233,7 @@ scoped_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(outer_rect.width(), output->info().fWidth); - EXPECT_EQ(outer_rect.width(), output->info().fHeight); + EXPECT_EQ(outer_rect.height(), output->info().fHeight); EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0)); EXPECT_EQ(SK_ColorYELLOW, @@ -308,7 +308,7 @@ scoped_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(tile_rect.width(), output->info().fWidth); - EXPECT_EQ(tile_rect.width(), output->info().fHeight); + EXPECT_EQ(tile_rect.height(), output->info().fHeight); // Check portion of tile not in visible rect isn't drawn. const unsigned int kTransparent = SK_ColorTRANSPARENT; @@ -350,7 +350,7 @@ scoped_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth); - EXPECT_EQ(device_viewport_rect.width(), output->info().fHeight); + EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight); EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0)); EXPECT_EQ(SK_ColorGREEN, @@ -372,7 +372,7 @@ output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth); - EXPECT_EQ(device_viewport_rect.width(), output->info().fHeight); + EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight); // If we didn't clear, the borders should still be green. EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0)); @@ -417,7 +417,7 @@ scoped_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth); - EXPECT_EQ(device_viewport_rect.width(), output->info().fHeight); + EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight); EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0)); EXPECT_EQ(SK_ColorGREEN,
diff --git a/cc/quads/draw_quad.h b/cc/quads/draw_quad.h index 61ca358..d9395cd 100644 --- a/cc/quads/draw_quad.h +++ b/cc/quads/draw_quad.h
@@ -11,12 +11,18 @@ #include "cc/resources/resource_provider.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; +} class Value; class DictionaryValue; -} +} // namespace base namespace cc {
diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h index 28775883e..8a40f179 100644 --- a/cc/quads/render_pass.h +++ b/cc/quads/render_pass.h
@@ -20,11 +20,17 @@ #include "ui/gfx/transform.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } class Value; -}; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; +} +} // namespace base namespace cc {
diff --git a/cc/quads/shared_quad_state.h b/cc/quads/shared_quad_state.h index ebf7d11..0db23e1 100644 --- a/cc/quads/shared_quad_state.h +++ b/cc/quads/shared_quad_state.h
@@ -12,11 +12,17 @@ #include "ui/gfx/transform.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } class Value; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc {
diff --git a/cc/resources/bitmap_tile_task_worker_pool.h b/cc/resources/bitmap_tile_task_worker_pool.h index 404a3a5..20d57d24 100644 --- a/cc/resources/bitmap_tile_task_worker_pool.h +++ b/cc/resources/bitmap_tile_task_worker_pool.h
@@ -11,10 +11,16 @@ #include "cc/resources/tile_task_worker_pool.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc { class ResourceProvider;
diff --git a/cc/resources/display_list_recording_source.cc b/cc/resources/display_list_recording_source.cc index 7b98e50..e60e4c1 100644 --- a/cc/resources/display_list_recording_source.cc +++ b/cc/resources/display_list_recording_source.cc
@@ -45,7 +45,7 @@ const gfx::Size& layer_size, const gfx::Rect& visible_layer_rect, int frame_number, - Picture::RecordingMode recording_mode) { + RecordingMode recording_mode) { bool updated = false; if (size_ != layer_size) { @@ -81,12 +81,37 @@ if (!updated && !invalidation->Intersects(recorded_viewport_)) return false; - // TODO(ajuma): Does repeating this way really makes sense with display lists? - // With Blink caching recordings, repeated calls will not cause re-recording. - int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); + ContentLayerClient::PaintingControlSetting painting_control = + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL; + + switch (recording_mode) { + case RECORD_NORMALLY: + // Already setup for normal recording. + break; + case RECORD_WITH_SK_NULL_CANVAS: + // TODO(schenney): Remove this when DisplayList recording is the only + // option. For now, fall through and disable construction. + case RECORD_WITH_PAINTING_DISABLED: + painting_control = ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED; + break; + case RECORD_WITH_CACHING_DISABLED: + painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED; + break; + default: + NOTREACHED(); + } + + int repeat_count = 1; + if (slow_down_raster_scale_factor_for_debug_ > 1) { + repeat_count = slow_down_raster_scale_factor_for_debug_; + if (painting_control != + ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED) { + painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED; + } + } for (int i = 0; i < repeat_count; ++i) { - display_list_ = painter->PaintContentsToDisplayList( - recorded_viewport_, ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + display_list_ = painter->PaintContentsToDisplayList(recorded_viewport_, + painting_control); } display_list_->set_layer_rect(recorded_viewport_); is_suitable_for_gpu_rasterization_ =
diff --git a/cc/resources/display_list_recording_source.h b/cc/resources/display_list_recording_source.h index a2c8ea6..05e2ed7 100644 --- a/cc/resources/display_list_recording_source.h +++ b/cc/resources/display_list_recording_source.h
@@ -18,14 +18,13 @@ ~DisplayListRecordingSource() override; // RecordingSource overrides. - bool UpdateAndExpandInvalidation( - ContentLayerClient* painter, - Region* invalidation, - bool can_use_lcd_text, - const gfx::Size& layer_size, - const gfx::Rect& visible_layer_rect, - int frame_number, - Picture::RecordingMode recording_mode) override; + bool UpdateAndExpandInvalidation(ContentLayerClient* painter, + Region* invalidation, + bool can_use_lcd_text, + const gfx::Size& layer_size, + const gfx::Rect& visible_layer_rect, + int frame_number, + RecordingMode recording_mode) override; scoped_refptr<RasterSource> CreateRasterSource() const override; gfx::Size GetSize() const final; void SetEmptyBounds() override;
diff --git a/cc/resources/one_copy_tile_task_worker_pool.h b/cc/resources/one_copy_tile_task_worker_pool.h index 4568d35..85b3f32 100644 --- a/cc/resources/one_copy_tile_task_worker_pool.h +++ b/cc/resources/one_copy_tile_task_worker_pool.h
@@ -15,11 +15,18 @@ #include "cc/resources/tile_task_worker_pool.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { class ResourcePool;
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc index 003a8f175..6bbeeaa 100644 --- a/cc/resources/picture.cc +++ b/cc/resources/picture.cc
@@ -53,11 +53,12 @@ } // namespace -scoped_refptr<Picture> Picture::Create(const gfx::Rect& layer_rect, - ContentLayerClient* client, - const gfx::Size& tile_grid_size, - bool gather_pixel_refs, - RecordingMode recording_mode) { +scoped_refptr<Picture> Picture::Create( + const gfx::Rect& layer_rect, + ContentLayerClient* client, + const gfx::Size& tile_grid_size, + bool gather_pixel_refs, + RecordingSource::RecordingMode recording_mode) { scoped_refptr<Picture> picture = make_scoped_refptr(new Picture(layer_rect)); picture->Record(client, tile_grid_size, recording_mode); @@ -169,7 +170,7 @@ void Picture::Record(ContentLayerClient* painter, const gfx::Size& tile_grid_size, - RecordingMode recording_mode) { + RecordingSource::RecordingMode recording_mode) { TRACE_EVENT2("cc", "Picture::Record", "data", @@ -189,23 +190,27 @@ layer_rect_.width(), layer_rect_.height(), &factory, SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); - ContentLayerClient::GraphicsContextStatus graphics_context_status = - ContentLayerClient::GRAPHICS_CONTEXT_ENABLED; + ContentLayerClient::PaintingControlSetting painting_control = + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL; switch (recording_mode) { - case RECORD_NORMALLY: + case RecordingSource::RECORD_NORMALLY: // Already setup for normal recording. break; - case RECORD_WITH_SK_NULL_CANVAS: + case RecordingSource::RECORD_WITH_SK_NULL_CANVAS: canvas = skia::AdoptRef(SkCreateNullCanvas()); break; - case RECORD_WITH_PAINTING_DISABLED: + case RecordingSource::RECORD_WITH_PAINTING_DISABLED: // We pass a disable flag through the paint calls when perfromance // testing (the only time this case should ever arise) when we want to // prevent the Blink GraphicsContext object from consuming any compute // time. canvas = skia::AdoptRef(SkCreateNullCanvas()); - graphics_context_status = ContentLayerClient::GRAPHICS_CONTEXT_DISABLED; + painting_control = ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED; + break; + case RecordingSource::RECORD_WITH_CACHING_DISABLED: + // This mode should give the same results as RECORD_NORMALLY. + painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED; break; default: NOTREACHED(); @@ -221,7 +226,7 @@ layer_rect_.height()); canvas->clipRect(layer_skrect); - painter->PaintContents(canvas.get(), layer_rect_, graphics_context_status); + painter->PaintContents(canvas.get(), layer_rect_, painting_control); canvas->restore(); picture_ = skia::AdoptRef(recorder.endRecording());
diff --git a/cc/resources/picture.h b/cc/resources/picture.h index ec76f45..a2a4ec2b 100644 --- a/cc/resources/picture.h +++ b/cc/resources/picture.h
@@ -18,6 +18,7 @@ #include "base/trace_event/trace_event.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" +#include "cc/resources/recording_source.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/geometry/rect.h" @@ -44,18 +45,12 @@ typedef std::vector<SkPixelRef*> PixelRefs; typedef base::hash_map<PixelRefMapKey, PixelRefs> PixelRefMap; - enum RecordingMode { - RECORD_NORMALLY, - RECORD_WITH_SK_NULL_CANVAS, - RECORD_WITH_PAINTING_DISABLED, - RECORDING_MODE_COUNT, // Must be the last entry. - }; - - static scoped_refptr<Picture> Create(const gfx::Rect& layer_rect, - ContentLayerClient* client, - const gfx::Size& tile_grid_size, - bool gather_pixels_refs, - RecordingMode recording_mode); + static scoped_refptr<Picture> Create( + const gfx::Rect& layer_rect, + ContentLayerClient* client, + const gfx::Size& tile_grid_size, + bool gather_pixels_refs, + RecordingSource::RecordingMode recording_mode); static scoped_refptr<Picture> CreateFromValue(const base::Value* value); static scoped_refptr<Picture> CreateFromSkpValue(const base::Value* value); @@ -141,7 +136,7 @@ // playback on a different thread this can only be called once. void Record(ContentLayerClient* client, const gfx::Size& tile_grid_size, - RecordingMode recording_mode); + RecordingSource::RecordingMode recording_mode); // Gather pixel refs from recording. void GatherPixelRefs(const gfx::Size& tile_grid_info);
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index 15fdb43..c9672c91 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h
@@ -21,10 +21,16 @@ #include "ui/gfx/geometry/rect.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc {
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc index 779e2c0..7c36a3ff5 100644 --- a/cc/resources/picture_layer_tiling_set.cc +++ b/cc/resources/picture_layer_tiling_set.cc
@@ -116,15 +116,16 @@ } if (!tilings_.empty()) { - size_t num_high_res = std::count_if(tilings_.begin(), tilings_.end(), - [](PictureLayerTiling* tiling) { - return tiling->resolution() == HIGH_RESOLUTION; - }); - DCHECK_LE(num_high_res, 1u); + DCHECK_LE(NumHighResTilings(), 1); // When commiting from the main thread the high res tiling may get dropped, // but when cloning to the active tree, there should always be one. - if (twin_set) - DCHECK_EQ(1u, num_high_res); + if (twin_set) { + DCHECK_EQ(1, NumHighResTilings()) + << " num tilings on active: " << tilings_.size() + << " num tilings on pending: " << twin_set->tilings_.size() + << " num high res on pending: " << twin_set->NumHighResTilings() + << " are on active tree: " << (client_->GetTree() == ACTIVE_TREE); + } } #endif } @@ -214,12 +215,10 @@ } int PictureLayerTilingSet::NumHighResTilings() const { - int num_high_res = 0; - for (size_t i = 0; i < tilings_.size(); ++i) { - if (tilings_[i]->resolution() == HIGH_RESOLUTION) - num_high_res++; - } - return num_high_res; + return std::count_if(tilings_.begin(), tilings_.end(), + [](PictureLayerTiling* tiling) { + return tiling->resolution() == HIGH_RESOLUTION; + }); } PictureLayerTiling* PictureLayerTilingSet::FindTilingWithScale(
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h index 9f6eba9..3e31ed9 100644 --- a/cc/resources/picture_layer_tiling_set.h +++ b/cc/resources/picture_layer_tiling_set.h
@@ -14,10 +14,16 @@ #include "ui/gfx/geometry/size.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc {
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc index f42244cf..dcfe49ea 100644 --- a/cc/resources/picture_pile.cc +++ b/cc/resources/picture_pile.cc
@@ -181,7 +181,7 @@ const gfx::Size& layer_size, const gfx::Rect& visible_layer_rect, int frame_number, - Picture::RecordingMode recording_mode) { + RecordingSource::RecordingMode recording_mode) { bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text; can_use_lcd_text_ = can_use_lcd_text; @@ -532,7 +532,7 @@ } void PicturePile::CreatePictures(ContentLayerClient* painter, - Picture::RecordingMode recording_mode, + RecordingSource::RecordingMode recording_mode, const std::vector<gfx::Rect>& record_rects) { for (const auto& record_rect : record_rects) { gfx::Rect padded_record_rect = PadRect(record_rect);
diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h index 1e3368c..8000c422 100644 --- a/cc/resources/picture_pile.h +++ b/cc/resources/picture_pile.h
@@ -12,7 +12,7 @@ #include "base/containers/hash_tables.h" #include "base/memory/ref_counted.h" #include "cc/base/tiling_data.h" -#include "cc/resources/recording_source.h" +#include "cc/resources/picture.h" namespace cc { class PicturePileImpl; @@ -23,14 +23,13 @@ ~PicturePile() override; // RecordingSource overrides. - bool UpdateAndExpandInvalidation( - ContentLayerClient* painter, - Region* invalidation, - bool can_use_lcd_text, - const gfx::Size& layer_size, - const gfx::Rect& visible_layer_rect, - int frame_number, - Picture::RecordingMode recording_mode) override; + bool UpdateAndExpandInvalidation(ContentLayerClient* painter, + Region* invalidation, + bool can_use_lcd_text, + const gfx::Size& layer_size, + const gfx::Rect& visible_layer_rect, + int frame_number, + RecordingMode recording_mode) override; scoped_refptr<RasterSource> CreateRasterSource() const override; gfx::Size GetSize() const final; void SetEmptyBounds() override; @@ -106,7 +105,7 @@ friend class PicturePileImpl; void CreatePictures(ContentLayerClient* painter, - Picture::RecordingMode recording_mode, + RecordingMode recording_mode, const std::vector<gfx::Rect>& record_rects); void GetInvalidTileRects(const gfx::Rect& interest_rect, Region* invalidation,
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc index 4e3fe15..b834979 100644 --- a/cc/resources/picture_pile_unittest.cc +++ b/cc/resources/picture_pile_unittest.cc
@@ -44,7 +44,7 @@ frame_number_++; return pile_.UpdateAndExpandInvalidation( &client_, invalidation, false, layer_size, visible_layer_rect, - frame_number_, Picture::RECORD_NORMALLY); + frame_number_, RecordingSource::RECORD_NORMALLY); } bool UpdateWholePile() {
diff --git a/cc/resources/picture_unittest.cc b/cc/resources/picture_unittest.cc index 0c41215..1e2ba44 100644 --- a/cc/resources/picture_unittest.cc +++ b/cc/resources/picture_unittest.cc
@@ -44,7 +44,7 @@ scoped_refptr<Picture> one_rect_picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_ptr<base::Value> serialized_one_rect(one_rect_picture->AsValue()); // Reconstruct the picture. @@ -66,7 +66,7 @@ scoped_refptr<Picture> two_rect_picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_ptr<base::Value> serialized_two_rect(two_rect_picture->AsValue()); @@ -118,7 +118,7 @@ scoped_refptr<Picture> picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, true, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); // Default iterator does not have any pixel refs { @@ -213,7 +213,7 @@ scoped_refptr<Picture> picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, true, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); // Default iterator does not have any pixel refs { @@ -331,7 +331,7 @@ scoped_refptr<Picture> picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, true, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { @@ -374,7 +374,7 @@ content_layer_client.add_draw_rect(layer_rect, red_paint); scoped_refptr<Picture> one_rect_picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); scoped_ptr<base::Value> serialized_one_rect( one_rect_picture->AsValue()); @@ -406,27 +406,36 @@ scoped_refptr<Picture> picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, - Picture::RECORD_NORMALLY); + RecordingSource::RECORD_NORMALLY); EXPECT_TRUE(content_layer_client.last_canvas() != NULL); - EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED, - content_layer_client.last_context_status()); + EXPECT_EQ(ContentLayerClient::PAINTING_BEHAVIOR_NORMAL, + content_layer_client.last_painting_control()); EXPECT_TRUE(picture.get()); picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, - false, Picture::RECORD_WITH_SK_NULL_CANVAS); + false, RecordingSource::RECORD_WITH_SK_NULL_CANVAS); EXPECT_TRUE(content_layer_client.last_canvas() != NULL); - EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED, - content_layer_client.last_context_status()); + EXPECT_EQ(ContentLayerClient::PAINTING_BEHAVIOR_NORMAL, + content_layer_client.last_painting_control()); EXPECT_TRUE(picture.get()); - picture = Picture::Create(layer_rect, &content_layer_client, tile_grid_size, - false, Picture::RECORD_WITH_PAINTING_DISABLED); + picture = + Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, + RecordingSource::RECORD_WITH_PAINTING_DISABLED); EXPECT_TRUE(content_layer_client.last_canvas() != NULL); - EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_DISABLED, - content_layer_client.last_context_status()); + EXPECT_EQ(ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED, + content_layer_client.last_painting_control()); EXPECT_TRUE(picture.get()); - EXPECT_EQ(3, Picture::RECORDING_MODE_COUNT); + picture = + Picture::Create(layer_rect, &content_layer_client, tile_grid_size, false, + RecordingSource::RECORD_WITH_CACHING_DISABLED); + EXPECT_TRUE(content_layer_client.last_canvas() != NULL); + EXPECT_EQ(ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED, + content_layer_client.last_painting_control()); + EXPECT_TRUE(picture.get()); + + EXPECT_EQ(4, RecordingSource::RECORDING_MODE_COUNT); } } // namespace
diff --git a/cc/resources/pixel_buffer_tile_task_worker_pool.h b/cc/resources/pixel_buffer_tile_task_worker_pool.h index 8ee4b9c..edff89a 100644 --- a/cc/resources/pixel_buffer_tile_task_worker_pool.h +++ b/cc/resources/pixel_buffer_tile_task_worker_pool.h
@@ -16,11 +16,18 @@ #include "cc/resources/tile_task_worker_pool.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { class ResourceProvider;
diff --git a/cc/resources/recording_source.h b/cc/resources/recording_source.h index 1e45047..d96c0fa 100644 --- a/cc/resources/recording_source.h +++ b/cc/resources/recording_source.h
@@ -5,8 +5,8 @@ #ifndef CC_RESOURCES_RECORDING_SOURCE_H_ #define CC_RESOURCES_RECORDING_SOURCE_H_ +#include "base/memory/ref_counted.h" #include "cc/base/cc_export.h" -#include "cc/resources/picture.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -18,20 +18,27 @@ class CC_EXPORT RecordingSource { public: + enum RecordingMode { + RECORD_NORMALLY, + RECORD_WITH_SK_NULL_CANVAS, + RECORD_WITH_PAINTING_DISABLED, + RECORD_WITH_CACHING_DISABLED, + RECORDING_MODE_COUNT, // Must be the last entry. + }; + virtual ~RecordingSource() {} // Re-record parts of the picture that are invalid. // Invalidations are in layer space, and will be expanded to cover everything // that was either recorded/changed or that has no recording, leaving out only // pieces that we had a recording for and it was not changed. // Return true iff the pile was modified. - virtual bool UpdateAndExpandInvalidation( - ContentLayerClient* painter, - Region* invalidation, - bool can_use_lcd_text, - const gfx::Size& layer_size, - const gfx::Rect& visible_layer_rect, - int frame_number, - Picture::RecordingMode recording_mode) = 0; + virtual bool UpdateAndExpandInvalidation(ContentLayerClient* painter, + Region* invalidation, + bool can_use_lcd_text, + const gfx::Size& layer_size, + const gfx::Rect& visible_layer_rect, + int frame_number, + RecordingMode recording_mode) = 0; virtual scoped_refptr<RasterSource> CreateRasterSource() const = 0;
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h index 37ab765..0af823ed 100644 --- a/cc/resources/tile_manager.h +++ b/cc/resources/tile_manager.h
@@ -26,11 +26,18 @@ #include "cc/resources/tile_task_runner.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { class PictureLayerImpl;
diff --git a/cc/resources/zero_copy_tile_task_worker_pool.h b/cc/resources/zero_copy_tile_task_worker_pool.h index 8d3c0cf..4f3085c 100644 --- a/cc/resources/zero_copy_tile_task_worker_pool.h +++ b/cc/resources/zero_copy_tile_task_worker_pool.h
@@ -11,10 +11,16 @@ #include "cc/resources/tile_task_worker_pool.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc { class ResourceProvider;
diff --git a/cc/scheduler/delay_based_time_source.h b/cc/scheduler/delay_based_time_source.h index ea03f9d..da968a6f 100644 --- a/cc/scheduler/delay_based_time_source.h +++ b/cc/scheduler/delay_based_time_source.h
@@ -12,11 +12,17 @@ #include "cc/base/cc_export.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } -class SingleThreadTaskRunner; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +class SingleThreadTaskRunner; +} // namespace base namespace cc {
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index e06a133..ddc3f2f 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h
@@ -24,11 +24,17 @@ #include "cc/scheduler/scheduler_state_machine.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } -class SingleThreadTaskRunner; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +class SingleThreadTaskRunner; +} // namespace base namespace cc {
diff --git a/cc/scheduler/scheduler_settings.h b/cc/scheduler/scheduler_settings.h index 4ff3c7eb5..90c1a9c3 100644 --- a/cc/scheduler/scheduler_settings.h +++ b/cc/scheduler/scheduler_settings.h
@@ -11,10 +11,16 @@ #include "cc/base/cc_export.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace cc { class LayerTreeSettings;
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 5b7f6b7..fb87c84b 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -17,12 +17,19 @@ #include "cc/scheduler/scheduler_settings.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } -class Value; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +class Value; +} // namespace base namespace cc {
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc index 46d1baa..23b73f5f 100644 --- a/cc/test/fake_content_layer_client.cc +++ b/cc/test/fake_content_layer_client.cc
@@ -22,9 +22,9 @@ void FakeContentLayerClient::PaintContents( SkCanvas* canvas, const gfx::Rect& paint_rect, - ContentLayerClient::GraphicsContextStatus gc_status) { + PaintingControlSetting painting_control) { last_canvas_ = canvas; - last_context_status_ = gc_status; + last_painting_control_ = painting_control; canvas->clipRect(gfx::RectToSkRect(paint_rect)); for (RectPaintVector::const_iterator it = draw_rects_.begin(); @@ -58,7 +58,7 @@ scoped_refptr<DisplayItemList> FakeContentLayerClient::PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) { + PaintingControlSetting painting_control) { SkPictureRecorder recorder; skia::RefPtr<SkCanvas> canvas; skia::RefPtr<SkPicture> picture;
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index 1060d08..d53d34e 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h
@@ -27,13 +27,12 @@ FakeContentLayerClient(); ~FakeContentLayerClient() override; - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& rect, - ContentLayerClient::GraphicsContextStatus gc_status) override; + void PaintContents(SkCanvas* canvas, + const gfx::Rect& rect, + PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override; + PaintingControlSetting painting_control) override; bool FillsBoundsCompletely() const override; void set_fill_with_nonsolid_color(bool nonsolid) { @@ -56,8 +55,8 @@ SkCanvas* last_canvas() const { return last_canvas_; } - ContentLayerClient::GraphicsContextStatus last_context_status() const { - return last_context_status_; + PaintingControlSetting last_painting_control() const { + return last_painting_control_; } private: @@ -68,7 +67,7 @@ RectPaintVector draw_rects_; BitmapVector draw_bitmaps_; SkCanvas* last_canvas_; - ContentLayerClient::GraphicsContextStatus last_context_status_; + PaintingControlSetting last_painting_control_; }; } // namespace cc
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h index 8fcafdb7..f5f3504 100644 --- a/cc/test/fake_layer_tree_host_client.h +++ b/cc/test/fake_layer_tree_host_client.h
@@ -34,8 +34,8 @@ void DidBeginMainFrame() override {} void BeginMainFrame(const BeginFrameArgs& args) override {} void Layout() override {} - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {}
diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc index 420b5d6..bdba092 100644 --- a/cc/test/fake_picture_pile_impl.cc +++ b/cc/test/fake_picture_pile_impl.cc
@@ -120,8 +120,9 @@ gfx::Rect bounds(tiling().TileBounds(x, y)); bounds.Inset(-buffer_pixels(), -buffer_pixels()); - scoped_refptr<Picture> picture(Picture::Create( - bounds, &client_, tile_grid_size_, true, Picture::RECORD_NORMALLY)); + scoped_refptr<Picture> picture( + Picture::Create(bounds, &client_, tile_grid_size_, true, + RecordingSource::RECORD_NORMALLY)); picture_map_[std::pair<int, int>(x, y)].SetPicture(picture); EXPECT_TRUE(HasRecordingAt(x, y));
diff --git a/cc/test/layer_tree_json_parser.cc b/cc/test/layer_tree_json_parser.cc index 1514d83..efe70a0 100644 --- a/cc/test/layer_tree_json_parser.cc +++ b/cc/test/layer_tree_json_parser.cc
@@ -149,6 +149,23 @@ new_layer->SetTouchEventHandlerRegion(touch_region); } + if (dict->HasKey("ScrollBlocksOn")) { + success &= dict->GetList("ScrollBlocksOn", &list); + ScrollBlocksOn blocks; + std::string str; + for (size_t i = 0; i < list->GetSize(); i++) { + success &= list->GetString(i, &str); + if (str == "StartTouch") + blocks |= ScrollBlocksOnStartTouch; + else if (str == "WheelEvent") + blocks |= ScrollBlocksOnWheelEvent; + else if (str == "ScrollEvent") + blocks |= ScrollBlocksOnScrollEvent; + else + success = false; + } + } + success &= dict->GetList("DrawTransform", &list); double transform[16]; for (int i = 0; i < 16; ++i)
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 5f69c354..ce69079d 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -391,8 +391,8 @@ void Layout() override { test_hooks_->Layout(); } - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 4abedd7..c2b18b15 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h
@@ -65,8 +65,8 @@ virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, base::TimeTicks monotonic_time) {} virtual void ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float scale, float top_controls_delta) {}
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h index 78b8f4a3..35626993 100644 --- a/cc/test/pixel_test.h +++ b/cc/test/pixel_test.h
@@ -89,9 +89,6 @@ return static_cast<RendererType*>(renderer_.get()); } - bool UseSkiaGPUBackend() const; - bool ExpandedViewport() const; - protected: void SetUp() override; }; @@ -145,16 +142,6 @@ } template<> -inline bool RendererPixelTest<GLRenderer>::UseSkiaGPUBackend() const { - return false; -} - -template<> -inline bool RendererPixelTest<GLRenderer>::ExpandedViewport() const { - return false; -} - -template<> inline void RendererPixelTest<GLRendererWithExpandedViewport>::SetUp() { SetUpGLRenderer(false, false); ForceExpandedViewport(gfx::Size(50, 50)); @@ -162,68 +149,22 @@ } template <> -inline bool -RendererPixelTest<GLRendererWithExpandedViewport>::UseSkiaGPUBackend() const { - return false; -} - -template <> -inline bool -RendererPixelTest<GLRendererWithExpandedViewport>::ExpandedViewport() const { - return true; -} - -template <> inline void RendererPixelTest<GLRendererWithFlippedSurface>::SetUp() { SetUpGLRenderer(false, true); } template <> -inline bool RendererPixelTest<GLRendererWithFlippedSurface>::UseSkiaGPUBackend() - const { - return false; -} - -template <> -inline bool RendererPixelTest<GLRendererWithFlippedSurface>::ExpandedViewport() - const { - return true; -} - -template <> inline void RendererPixelTest<SoftwareRenderer>::SetUp() { SetUpSoftwareRenderer(); } template<> -inline bool RendererPixelTest<SoftwareRenderer>::UseSkiaGPUBackend() const { - return false; -} - -template <> -inline bool RendererPixelTest<SoftwareRenderer>::ExpandedViewport() const { - return false; -} - -template<> inline void RendererPixelTest<SoftwareRendererWithExpandedViewport>::SetUp() { SetUpSoftwareRenderer(); ForceExpandedViewport(gfx::Size(50, 50)); ForceViewportOffset(gfx::Vector2d(10, 20)); } -template <> -inline bool RendererPixelTest< - SoftwareRendererWithExpandedViewport>::UseSkiaGPUBackend() const { - return false; -} - -template <> -inline bool RendererPixelTest< - SoftwareRendererWithExpandedViewport>::ExpandedViewport() const { - return true; -} - typedef RendererPixelTest<GLRenderer> GLRendererPixelTest; typedef RendererPixelTest<SoftwareRenderer> SoftwareRendererPixelTest;
diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc index 701f004f..7e97bb8 100644 --- a/cc/test/solid_color_content_layer_client.cc +++ b/cc/test/solid_color_content_layer_client.cc
@@ -14,7 +14,7 @@ void SolidColorContentLayerClient::PaintContents( SkCanvas* canvas, const gfx::Rect& rect, - ContentLayerClient::GraphicsContextStatus gc_status) { + PaintingControlSetting painting_control) { SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setColor(color_); @@ -28,7 +28,7 @@ scoped_refptr<DisplayItemList> SolidColorContentLayerClient::PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) { + PaintingControlSetting painting_control) { NOTIMPLEMENTED(); return DisplayItemList::Create(); }
diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h index 93fca844..1ab4c4d 100644 --- a/cc/test/solid_color_content_layer_client.h +++ b/cc/test/solid_color_content_layer_client.h
@@ -16,13 +16,12 @@ explicit SolidColorContentLayerClient(SkColor color) : color_(color) {} // ContentLayerClient implementation. - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& rect, - ContentLayerClient::GraphicsContextStatus gc_status) override; + void PaintContents(SkCanvas* canvas, + const gfx::Rect& rect, + PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override; + PaintingControlSetting painting_control) override; bool FillsBoundsCompletely() const override; private:
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index cd69f92..8217ce0 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -38,7 +38,7 @@ const TransformNode* clip_transform_node = transform_tree.Node(clip_node->data.transform_id); const TransformNode* target_node = - transform_tree.Node(layer->render_target()->transform_tree_index()); + transform_tree.Node(transform_node->data.target_id); gfx::Transform clip_to_target; gfx::Transform content_to_target;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 2567122..9bac4a84 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -43,6 +43,7 @@ #include "cc/trees/thread_proxy.h" #include "cc/trees/tree_synchronizer.h" #include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" namespace { static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; @@ -118,7 +119,7 @@ debug_state_(settings.initial_debug_state), top_controls_shrink_blink_size_(false), top_controls_height_(0.f), - top_controls_content_offset_(0.f), + top_controls_shown_ratio_(0.f), device_scale_factor_(1.f), visible_(true), page_scale_factor_(1.f), @@ -334,20 +335,10 @@ sync_tree->PassSwapPromises(&swap_promise_list_); - // Track the change in top controls height to offset the top_controls_delta - // properly. This is so that the top controls offset will be maintained - // across height changes. - float top_controls_height_delta = - sync_tree->top_controls_height() - top_controls_height_; - sync_tree->set_top_controls_shrink_blink_size( top_controls_shrink_blink_size_); sync_tree->set_top_controls_height(top_controls_height_); - sync_tree->set_top_controls_content_offset(top_controls_content_offset_); - sync_tree->set_top_controls_delta(sync_tree->top_controls_delta() - - sync_tree->sent_top_controls_delta() - - top_controls_height_delta); - sync_tree->set_sent_top_controls_delta(0.f); + sync_tree->PushTopControlsFromMainThread(top_controls_shown_ratio_); host_impl->SetUseGpuRasterization(UseGpuRasterization()); host_impl->set_gpu_rasterization_status(GetGpuRasterizationStatus()); @@ -690,11 +681,11 @@ SetNeedsCommit(); } -void LayerTreeHost::SetTopControlsContentOffset(float offset) { - if (top_controls_content_offset_ == offset) +void LayerTreeHost::SetTopControlsShownRatio(float ratio) { + if (top_controls_shown_ratio_ == ratio) return; - top_controls_content_offset_ = offset; + top_controls_shown_ratio_ = ratio; SetNeedsCommit(); } @@ -1093,8 +1084,8 @@ QueueSwapPromise(swap_promise.Pass()); } - gfx::Vector2d inner_viewport_scroll_delta; - gfx::Vector2d outer_viewport_scroll_delta; + gfx::Vector2dF inner_viewport_scroll_delta; + gfx::Vector2dF outer_viewport_scroll_delta; if (root_layer_.get()) { for (size_t i = 0; i < info->scrolls.size(); ++i) { @@ -1137,10 +1128,13 @@ ApplyPageScaleDeltaFromImplSide(info->page_scale_delta); elastic_overscroll_ += info->elastic_overscroll_delta; if (!settings_.use_pinch_virtual_viewport) { + // TODO(miletus): Make sure either this code path is totally gone, + // or revisit the flooring here if the old pinch viewport code path + // is causing problems with fractional scroll offset. client_->ApplyViewportDeltas( - inner_viewport_scroll_delta + outer_viewport_scroll_delta, - info->page_scale_delta, - info->top_controls_delta); + gfx::ToFlooredVector2d(inner_viewport_scroll_delta + + outer_viewport_scroll_delta), + info->page_scale_delta, info->top_controls_delta); } else { // TODO(ccameron): pass the elastic overscroll here so that input events // may be translated appropriately.
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index f41e023..da41e4c 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -212,7 +212,7 @@ void SetViewportSize(const gfx::Size& device_viewport_size); void SetTopControlsShrinkBlinkSize(bool shrink); void SetTopControlsHeight(float height); - void SetTopControlsContentOffset(float offset); + void SetTopControlsShownRatio(float ratio); gfx::Size device_viewport_size() const { return device_viewport_size_; } @@ -416,7 +416,7 @@ gfx::Size device_viewport_size_; bool top_controls_shrink_blink_size_; float top_controls_height_; - float top_controls_content_offset_; + float top_controls_shown_ratio_; float device_scale_factor_; bool visible_;
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index a712534..574325b 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h
@@ -29,8 +29,8 @@ virtual void DidBeginMainFrame() = 0; virtual void Layout() = 0; virtual void ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) = 0;
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 0955b9a6..86666176 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -151,9 +151,7 @@ struct ScrollUpdateInfo { int layer_id; - // TODO(miletus) : Use ScrollOffset once LayerTreeHost/Blink fully supports - // franctional scroll offset. - gfx::Vector2d scroll_delta; + gfx::Vector2dF scroll_delta; }; };
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index df2b30e..de5f44a 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -56,13 +56,12 @@ public: MockContentLayerClient() {} ~MockContentLayerClient() override {} - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override {} + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override {} scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 53eb58b..eedd46f 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -116,18 +116,14 @@ gfx::ScrollOffset viewport_in_content_coordinates_; }; - void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { if (visible) { - TRACE_EVENT_ASYNC_BEGIN1("webkit", - "LayerTreeHostImpl::SetVisible", - id, - "LayerTreeHostImpl", - id); + TRACE_EVENT_ASYNC_BEGIN1("cc", "LayerTreeHostImpl::SetVisible", id, + "LayerTreeHostImpl", id); return; } - TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id); + TRACE_EVENT_ASYNC_END0("cc", "LayerTreeHostImpl::SetVisible", id); } size_t GetMaxTransferBufferUsageBytes( @@ -239,8 +235,9 @@ SetDebugState(settings.initial_debug_state); // LTHI always has an active tree. - active_tree_ = LayerTreeImpl::create(this, new SyncedProperty<ScaleGroup>(), - new SyncedElasticOverscroll); + active_tree_ = + LayerTreeImpl::create(this, new SyncedProperty<ScaleGroup>(), + new SyncedTopControls, new SyncedElasticOverscroll); TRACE_EVENT_OBJECT_CREATED_WITH_ID( TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); @@ -470,16 +467,39 @@ return layer_impl != NULL; } -bool LayerTreeHostImpl::HaveTouchEventHandlersAt( - const gfx::Point& viewport_point) { +static LayerImpl* NextScrollLayer(LayerImpl* layer) { + if (LayerImpl* scroll_parent = layer->scroll_parent()) + return scroll_parent; + return layer->parent(); +} +static ScrollBlocksOn EffectiveScrollBlocksOn(LayerImpl* layer) { + ScrollBlocksOn blocks = ScrollBlocksOnNone; + for (; layer; layer = NextScrollLayer(layer)) { + blocks |= layer->scroll_blocks_on(); + } + return blocks; +} + +bool LayerTreeHostImpl::DoTouchEventsBlockScrollAt( + const gfx::Point& viewport_point) { gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, device_scale_factor_); + // First check if scrolling at this point is required to block on any + // touch event handlers. Note that we must start at the innermost layer + // (as opposed to only the layer found to contain a touch handler region + // below) to ensure all relevant scroll-blocks-on values are applied. LayerImpl* layer_impl = - active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( - device_viewport_point); + active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); + ScrollBlocksOn blocking = EffectiveScrollBlocksOn(layer_impl); + if (!(blocking & ScrollBlocksOnStartTouch)) + return false; + // Now determine if there are actually any handlers at that point. + // TODO(rbyers): Consider also honoring touch-action (crbug.com/347272). + layer_impl = active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( + device_viewport_point); return layer_impl != NULL; } @@ -1094,8 +1114,10 @@ void LayerTreeHostImpl::ResetTreesForTesting() { if (active_tree_) active_tree_->DetachLayerTree(); - active_tree_ = LayerTreeImpl::create(this, active_tree()->page_scale_factor(), - active_tree()->elastic_overscroll()); + active_tree_ = + LayerTreeImpl::create(this, active_tree()->page_scale_factor(), + active_tree()->top_controls_shown_ratio(), + active_tree()->elastic_overscroll()); if (pending_tree_) pending_tree_->DetachLayerTree(); pending_tree_ = nullptr; @@ -1596,6 +1618,7 @@ DestroyTileManager(); CreateAndSetTileManager(); } + RecreateTreeResources(); // We have released tilings for both active and pending tree. // We would not have any content to draw until the pending tree is activated. @@ -1658,9 +1681,9 @@ active_tree_->top_controls_shrink_blink_size() ? active_tree_->top_controls_height() : 0.f; - inner_container->SetBoundsDelta( - gfx::Vector2dF(0, top_controls_layout_height - - active_tree_->total_top_controls_content_offset())); + inner_container->SetBoundsDelta(gfx::Vector2dF( + 0, + top_controls_layout_height - top_controls_manager_->ContentTopOffset())); if (!outer_container || outer_container->BoundsForScrolling().IsEmpty()) return; @@ -1748,16 +1771,9 @@ else pending_tree_ = LayerTreeImpl::create(this, active_tree()->page_scale_factor(), + active_tree()->top_controls_shown_ratio(), active_tree()->elastic_overscroll()); - // Update the delta from the active tree, which may have - // adjusted its delta prior to the pending tree being created. - DCHECK_EQ(0.f, pending_tree_->sent_top_controls_delta()); - pending_tree_->set_top_controls_delta( - active_tree_->top_controls_delta() - - active_tree_->sent_top_controls_delta()); - pending_tree_->set_top_controls_height(active_tree_->top_controls_height()); - client_->OnCanDrawStateChanged(CanDraw()); TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree:waiting", pending_tree_.get()); } @@ -1792,14 +1808,6 @@ active_tree_->SetRootLayerScrollOffsetDelegate( root_layer_scroll_offset_delegate_); - if (top_controls_manager_) { - top_controls_manager_->SetTopControlsHeight( - active_tree_->top_controls_height()); - top_controls_manager_->SetControlsTopOffset( - active_tree_->total_top_controls_content_offset() - - active_tree_->top_controls_height()); - } - UpdateViewportContainerSizes(); } else { active_tree_->ProcessUIResourceRequestQueue(); @@ -1914,6 +1922,14 @@ EvictAllUIResources(); } +void LayerTreeHostImpl::RecreateTreeResources() { + active_tree_->RecreateResources(); + if (pending_tree_) + pending_tree_->RecreateResources(); + if (recycle_tree_) + recycle_tree_->RecreateResources(); +} + void LayerTreeHostImpl::CreateAndSetRenderer() { DCHECK(!renderer_); DCHECK(output_surface_); @@ -2105,8 +2121,12 @@ resource_provider_ = nullptr; output_surface_ = nullptr; - if (!output_surface->BindToClient(this)) + if (!output_surface->BindToClient(this)) { + // Avoid recreating tree resources because we might not have enough + // information to do this yet (eg. we don't have a TileManager at this + // point). return false; + } output_surface_ = output_surface.Pass(); resource_provider_ = ResourceProvider::Create( @@ -2123,6 +2143,7 @@ if (settings_.impl_side_painting) CreateAndSetTileManager(); + RecreateTreeResources(); // Initialize vsync parameters to sane values. const base::TimeDelta display_refresh_interval = @@ -2172,6 +2193,7 @@ CreateAndSetRenderer(); EnforceZeroBudget(false); CreateAndSetTileManager(); + RecreateTreeResources(); client_->SetNeedsCommitOnImplThread(); } @@ -2191,6 +2213,7 @@ CreateAndSetRenderer(); EnforceZeroBudget(true); CreateAndSetTileManager(); + RecreateTreeResources(); client_->SetNeedsCommitOnImplThread(); } @@ -2198,6 +2221,10 @@ void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { if (device_viewport_size == device_viewport_size_) return; + TRACE_EVENT_INSTANT2("cc", "LayerTreeHostImpl::SetViewportSize", + TRACE_EVENT_SCOPE_THREAD, "width", + device_viewport_size.width(), "height", + device_viewport_size.height()); if (pending_tree_) active_tree_->SetViewportSizeInvalid(); @@ -2259,15 +2286,17 @@ SetFullRootLayerDamage(); } -void LayerTreeHostImpl::SetControlsTopOffset(float offset) { - float current_top_offset = active_tree_->top_controls_content_offset() - - active_tree_->top_controls_height(); - active_tree_->set_top_controls_delta(offset - current_top_offset); +float LayerTreeHostImpl::TopControlsHeight() const { + return active_tree_->top_controls_height(); } -float LayerTreeHostImpl::ControlsTopOffset() const { - return active_tree_->total_top_controls_content_offset() - - active_tree_->top_controls_height(); +void LayerTreeHostImpl::SetCurrentTopControlsShownRatio(float ratio) { + if (active_tree_->SetCurrentTopControlsShownRatio(ratio)) + DidChangeTopControlsPosition(); +} + +float LayerTreeHostImpl::CurrentTopControlsShownRatio() const { + return active_tree_->CurrentTopControlsShownRatio(); } void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { @@ -2275,12 +2304,6 @@ input_handler_client_ = client; } -static LayerImpl* NextScrollLayer(LayerImpl* layer) { - if (LayerImpl* scroll_parent = layer->scroll_parent()) - return scroll_parent; - return layer->parent(); -} - LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, @@ -2289,12 +2312,15 @@ bool* optional_has_ancestor_scroll_handler) const { DCHECK(scroll_on_main_thread); + ScrollBlocksOn block_mode = EffectiveScrollBlocksOn(layer_impl); + // Walk up the hierarchy and look for a scrollable layer. LayerImpl* potentially_scrolling_layer_impl = NULL; for (; layer_impl; layer_impl = NextScrollLayer(layer_impl)) { // The content layer can also block attempts to scroll outside the main // thread. - ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); + ScrollStatus status = + layer_impl->TryScroll(device_viewport_point, type, block_mode); if (status == ScrollOnMainThread) { *scroll_on_main_thread = true; return NULL; @@ -2304,7 +2330,8 @@ if (!scroll_layer_impl) continue; - status = scroll_layer_impl->TryScroll(device_viewport_point, type); + status = + scroll_layer_impl->TryScroll(device_viewport_point, type, block_mode); // If any layer wants to divert the scroll event to the main thread, abort. if (status == ScrollOnMainThread) { *scroll_on_main_thread = true; @@ -3008,7 +3035,7 @@ if (!scroll_delta.IsZero()) { LayerTreeHostCommon::ScrollUpdateInfo scroll; scroll.layer_id = layer_impl->id(); - scroll.scroll_delta = gfx::Vector2d(scroll_delta.x(), scroll_delta.y()); + scroll.scroll_delta = gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); scroll_info->scrolls.push_back(scroll); } @@ -3022,11 +3049,11 @@ CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); scroll_info->page_scale_delta = active_tree_->page_scale_factor()->PullDeltaForMainThread(); + scroll_info->top_controls_delta = + active_tree()->top_controls_shown_ratio()->PullDeltaForMainThread(); scroll_info->elastic_overscroll_delta = active_tree_->elastic_overscroll()->PullDeltaForMainThread(); scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_); - scroll_info->top_controls_delta = active_tree()->top_controls_delta(); - active_tree_->set_sent_top_controls_delta(scroll_info->top_controls_delta); return scroll_info.Pass(); }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index f9cf55c6..fcdd81e 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -168,17 +168,20 @@ bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point, InputHandler::ScrollInputType type) override; bool HaveWheelEventHandlersAt(const gfx::Point& viewport_point) override; - bool HaveTouchEventHandlersAt(const gfx::Point& viewport_port) override; + bool DoTouchEventsBlockScrollAt(const gfx::Point& viewport_port) override; scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) override; ScrollElasticityHelper* CreateScrollElasticityHelper() override; // TopControlsManagerClient implementation. - void SetControlsTopOffset(float offset) override; - float ControlsTopOffset() const override; + float TopControlsHeight() const override; + void SetCurrentTopControlsShownRatio(float offset) override; + float CurrentTopControlsShownRatio() const override; void DidChangeTopControlsPosition() override; bool HaveRootScrollLayer() const override; + void UpdateViewportContainerSizes(); + struct CC_EXPORT FrameData : public RenderPassSink { FrameData(); ~FrameData() override; @@ -530,7 +533,6 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int id); - void UpdateViewportContainerSizes(); // Virtual for testing. virtual void AnimateLayers(base::TimeTicks monotonic_time); @@ -547,6 +549,7 @@ void CreateAndSetTileManager(); void DestroyTileManager(); void ReleaseTreeResources(); + void RecreateTreeResources(); void EnforceZeroBudget(bool zero_budget); bool UsePendingTreeForSync() const;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index cb33686..23e90e1 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -197,13 +197,14 @@ static void ExpectContains(const ScrollAndScaleSet& scroll_info, int id, - const gfx::Vector2d& scroll_delta) { + const gfx::Vector2dF& scroll_delta) { int times_encountered = 0; for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { if (scroll_info.scrolls[i].layer_id != id) continue; - EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta); + EXPECT_VECTOR2DF_NEAR(scroll_delta, scroll_info.scrolls[i].scroll_delta, + 1.0e-10); times_encountered++; } @@ -573,22 +574,180 @@ ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta); } -TEST_F(LayerTreeHostImplTest, WheelEventHandlers) { +TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); DrawFrame(); LayerImpl* root = host_impl_->active_tree()->root_layer(); + // With registered event handlers, wheel scrolls don't necessarily + // have to go to the main thread. root->SetHaveWheelEventHandlers(true); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); + host_impl_->ScrollEnd(); - // With registered event handlers, wheel scrolls have to go to the main - // thread. + // But typically the scroll-blocks-on mode will require them to. + root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent | ScrollBlocksOnStartTouch); EXPECT_EQ(InputHandler::ScrollOnMainThread, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); // But gesture scrolls can still be handled. EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + + // And if the handlers go away, wheel scrolls can again be processed + // on impl (despite the scroll-blocks-on mode). + root->SetHaveWheelEventHandlers(false); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); + host_impl_->ScrollEnd(); +} + +TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { + LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + host_impl_->SetViewportSize(gfx::Size(50, 50)); + DrawFrame(); + LayerImpl* root = host_impl_->active_tree()->root_layer(); + + LayerImpl* child = 0; + { + scoped_ptr<LayerImpl> child_layer = + LayerImpl::Create(host_impl_->active_tree(), 6); + child = child_layer.get(); + child_layer->SetDrawsContent(true); + child_layer->SetPosition(gfx::PointF(0, 20)); + child_layer->SetBounds(gfx::Size(50, 50)); + child_layer->SetContentBounds(gfx::Size(50, 50)); + scroll->AddChild(child_layer.Pass()); + } + + // Touch handler regions determine whether touch events block scroll. + root->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); + EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10))); + root->SetScrollBlocksOn(ScrollBlocksOnStartTouch | ScrollBlocksOnWheelEvent); + EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10))); + + // But they don't influence the actual handling of the scroll gestures. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + + // It's the union of scroll-blocks-on mode bits across all layers in the + // scroll paret chain that matters. + EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); + root->SetScrollBlocksOn(ScrollBlocksOnNone); + EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); + child->SetScrollBlocksOn(ScrollBlocksOnStartTouch); + EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); +} + +TEST_F(LayerTreeHostImplTest, ScrollBlocksOnScrollEventHandlers) { + SetupScrollAndContentsLayers(gfx::Size(100, 100)); + host_impl_->SetViewportSize(gfx::Size(50, 50)); + DrawFrame(); + LayerImpl* root = host_impl_->active_tree()->root_layer(); + + // With registered scroll handlers, scrolls don't generally have to go + // to the main thread. + root->SetHaveScrollEventHandlers(true); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); + host_impl_->ScrollEnd(); + + // Even the default scroll blocks on mode doesn't require this. + root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent | ScrollBlocksOnStartTouch); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + + // But the page can opt in to blocking on scroll event handlers. + root->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + + // Gesture and Wheel scrolls behave identically in this regard. + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); + + // And if the handlers go away, scrolls can again be processed on impl + // (despite the scroll-blocks-on mode). + root->SetHaveScrollEventHandlers(false); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollEnd(); +} + +TEST_F(LayerTreeHostImplTest, ScrollBlocksOnLayerTopology) { + host_impl_->SetViewportSize(gfx::Size(50, 50)); + + // Create a normal scrollable root layer + LayerImpl* root_scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + LayerImpl* root_child = root_scroll->children()[0]; + LayerImpl* root = host_impl_->active_tree()->root_layer(); + DrawFrame(); + + // Create two child scrollable layers + LayerImpl* child1 = 0; + { + scoped_ptr<LayerImpl> scrollable_child_clip_1 = + LayerImpl::Create(host_impl_->active_tree(), 6); + scoped_ptr<LayerImpl> scrollable_child_1 = CreateScrollableLayer( + 7, gfx::Size(10, 10), scrollable_child_clip_1.get()); + child1 = scrollable_child_1.get(); + scrollable_child_1->SetPosition(gfx::Point(5, 5)); + scrollable_child_1->SetHaveWheelEventHandlers(true); + scrollable_child_1->SetHaveScrollEventHandlers(true); + scrollable_child_clip_1->AddChild(scrollable_child_1.Pass()); + root_child->AddChild(scrollable_child_clip_1.Pass()); + } + + LayerImpl* child2 = 0; + { + scoped_ptr<LayerImpl> scrollable_child_clip_2 = + LayerImpl::Create(host_impl_->active_tree(), 8); + scoped_ptr<LayerImpl> scrollable_child_2 = CreateScrollableLayer( + 9, gfx::Size(10, 10), scrollable_child_clip_2.get()); + child2 = scrollable_child_2.get(); + scrollable_child_2->SetPosition(gfx::Point(5, 20)); + scrollable_child_2->SetHaveWheelEventHandlers(true); + scrollable_child_2->SetHaveScrollEventHandlers(true); + scrollable_child_clip_2->AddChild(scrollable_child_2.Pass()); + root_child->AddChild(scrollable_child_clip_2.Pass()); + } + + // Scroll-blocks-on on a layer affects scrolls that hit that layer. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + child1->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture)); + + // But not those that hit only other layers. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + + // It's the union of bits set across the scroll ancestor chain that matters. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); + host_impl_->ScrollEnd(); + root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); + host_impl_->ScrollEnd(); + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); + child2->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); + EXPECT_EQ(InputHandler::ScrollOnMainThread, + host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); } TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { @@ -2302,10 +2461,7 @@ LayerTreeHostImplTest::CreateHostImpl(settings, output_surface.Pass()); if (init && settings.calculate_top_controls_position) { host_impl_->active_tree()->set_top_controls_height(top_controls_height_); - host_impl_->active_tree()->set_top_controls_delta(top_controls_height_); - host_impl_->top_controls_manager()->SetTopControlsHeight( - top_controls_height_); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); } return init; } @@ -2339,6 +2495,7 @@ host_impl_->DidChangeTopControlsPosition(); host_impl_->CreatePendingTree(); + host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); root = LayerImpl::Create(host_impl_->sync_tree(), 1); root_clip = @@ -2370,6 +2527,7 @@ const gfx::Size& scroll_layer_size) { CreateHostImpl(settings_, CreateOutputSurface()); host_impl_->sync_tree()->set_top_controls_shrink_blink_size(true); + host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); host_impl_->DidChangeTopControlsPosition(); scoped_ptr<LayerImpl> root = @@ -2448,8 +2606,8 @@ host_impl_->active_tree()->InnerViewportScrollLayer(); DCHECK(inner_viewport_scroll_layer); host_impl_->ScrollEnd(); - EXPECT_EQ(top_controls_scroll_delta, - inner_viewport_scroll_layer->FixedContainerSizeDelta()); + EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(), + inner_viewport_scroll_layer->FixedContainerSizeDelta().y()); } // In this test, the outer viewport is initially unscrollable. We test that a @@ -2480,8 +2638,7 @@ // The entire scroll delta should have been used to hide the top controls. // The viewport layers should be resized back to their full sizes. - EXPECT_EQ(0.f, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y()); EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height()); EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height()); @@ -2503,8 +2660,7 @@ // The entire scroll delta should have been used to show the top controls. // The outer viewport should be resized to accomodate and scrolled to the // bottom of the document to keep the viewport in place. - EXPECT_EQ(50.f, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height()); EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height()); EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y()); @@ -2550,8 +2706,8 @@ gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f); host_impl_->top_controls_manager()->ScrollBegin(); host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); - EXPECT_EQ(top_controls_height_ - top_controls_scroll_delta.y(), - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(top_controls_height_ - top_controls_scroll_delta.y(), + host_impl_->top_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ(top_controls_scroll_delta, outer_viewport_scroll_layer->FixedContainerSizeDelta()); host_impl_->ScrollEnd(); @@ -2588,8 +2744,7 @@ DrawFrame(); // Show top controls - EXPECT_EQ(top_controls_height_, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); LayerImpl* outer_viewport_scroll_layer = host_impl_->active_tree()->OuterViewportScrollLayer(); @@ -2623,7 +2778,7 @@ // Top controls should be hidden EXPECT_EQ(scroll_delta.y(), top_controls_height_ - - host_impl_->active_tree()->total_top_controls_content_offset()); + host_impl_->top_controls_manager()->ContentTopOffset()); } // Ensure setting the top controls position explicitly using the setters on the @@ -2633,14 +2788,18 @@ SetupTopControlsAndScrollLayer(); DrawFrame(); - host_impl_->active_tree()->set_top_controls_delta(0.f); - host_impl_->active_tree()->set_top_controls_content_offset(30.f); - EXPECT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset()); - EXPECT_EQ(-20.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); + host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( + 30.f / top_controls_height_); + host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); + EXPECT_FLOAT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(-20.f, + host_impl_->top_controls_manager()->ControlsTopOffset()); - host_impl_->active_tree()->set_top_controls_delta(-30.f); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); - EXPECT_EQ(-50.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); + EXPECT_FLOAT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(-50.f, + host_impl_->top_controls_manager()->ControlsTopOffset()); host_impl_->DidChangeTopControlsPosition(); @@ -2657,18 +2816,22 @@ SetupTopControlsAndScrollLayer(); DrawFrame(); - host_impl_->sync_tree()->set_top_controls_content_offset(15.f); - - host_impl_->active_tree()->set_top_controls_content_offset(20.f); - host_impl_->active_tree()->set_top_controls_delta(-20.f); - host_impl_->active_tree()->set_sent_top_controls_delta(-5.f); + host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( + 20.f / top_controls_height_); + host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio( + 15.f / top_controls_height_); + host_impl_->active_tree() + ->top_controls_shown_ratio() + ->PullDeltaForMainThread(); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); + host_impl_->sync_tree()->PushTopControlsFromMainThread(15.f / + top_controls_height_); host_impl_->DidChangeTopControlsPosition(); LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); - EXPECT_EQ(0.f, - host_impl_->active_tree()->total_top_controls_content_offset()); host_impl_->ActivateSyncTree(); @@ -2676,11 +2839,13 @@ EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); - EXPECT_EQ(0.f, host_impl_->active_tree()->sent_top_controls_delta()); - EXPECT_EQ(-15.f, host_impl_->active_tree()->top_controls_delta()); - EXPECT_EQ(15.f, host_impl_->active_tree()->top_controls_content_offset()); - EXPECT_EQ(0.f, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_FLOAT_EQ( + -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() * + top_controls_height_); + EXPECT_FLOAT_EQ( + 15.f, + host_impl_->active_tree()->top_controls_shown_ratio()->ActiveBase() * + top_controls_height_); } // Test that changing the top controls layout height is correctly applied to @@ -2692,11 +2857,13 @@ SetupTopControlsAndScrollLayer(); DrawFrame(); - host_impl_->sync_tree()->set_top_controls_content_offset(50.f); + host_impl_->sync_tree()->PushTopControlsFromMainThread(1.f); host_impl_->sync_tree()->set_top_controls_shrink_blink_size(true); - host_impl_->active_tree()->set_top_controls_content_offset(50.f); - host_impl_->active_tree()->set_top_controls_delta(-50.f); + host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( + 1.f); + host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); host_impl_->DidChangeTopControlsPosition(); LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); @@ -2718,9 +2885,11 @@ EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), root_clip_ptr->bounds_delta()); - host_impl_->active_tree()->set_top_controls_delta(0.f); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); host_impl_->DidChangeTopControlsPosition(); + EXPECT_EQ(1.f, host_impl_->top_controls_manager()->TopControlsShownRatio()); + EXPECT_EQ(50.f, host_impl_->top_controls_manager()->TopControlsHeight()); EXPECT_EQ(50.f, host_impl_->top_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), root_clip_ptr->bounds_delta()); EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f), @@ -2735,8 +2904,7 @@ gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); DrawFrame(); - EXPECT_EQ(top_controls_height_, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); @@ -2756,17 +2924,15 @@ host_impl_->ScrollBy(gfx::Point(), scroll_delta); // scrolling down at the max extents no longer hides the top controls - EXPECT_EQ(0.f, - top_controls_height_ - - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); // forcefully hide the top controls by 25px host_impl_->top_controls_manager()->ScrollBy(scroll_delta); host_impl_->ScrollEnd(); - EXPECT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_FLOAT_EQ(scroll_delta.y(), + top_controls_height_ - + host_impl_->top_controls_manager()->ContentTopOffset()); inner_scroll->ClampScrollToMaxScrollOffset(); outer_scroll->ClampScrollToMaxScrollOffset(); @@ -2802,8 +2968,8 @@ gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); DrawFrame(); - EXPECT_EQ(top_controls_height_, - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_FLOAT_EQ(top_controls_height_, + host_impl_->top_controls_manager()->ContentTopOffset()); gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::ScrollStarted, @@ -2811,9 +2977,9 @@ host_impl_->ScrollBy(gfx::Point(), scroll_delta); host_impl_->ScrollEnd(); - EXPECT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_FLOAT_EQ(scroll_delta.y(), + top_controls_height_ - + host_impl_->top_controls_manager()->ContentTopOffset()); // Top controls were hidden by 25px so the inner viewport should have expanded // by that much. @@ -2839,7 +3005,7 @@ DrawFrame(); EXPECT_EQ(top_controls_height_, - host_impl_->active_tree()->total_top_controls_content_offset()); + host_impl_->top_controls_manager()->ContentTopOffset()); // Send a gesture scroll that will scroll the outer viewport, make sure the // top controls get scrolled. @@ -2851,16 +3017,16 @@ host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollEnd(); - EXPECT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_FLOAT_EQ(scroll_delta.y(), + top_controls_height_ - + host_impl_->top_controls_manager()->ContentTopOffset()); scroll_delta = gfx::Vector2dF(0.f, 50.f); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); host_impl_->ScrollBy(gfx::Point(), scroll_delta); - EXPECT_EQ(0, host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset()); EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), host_impl_->CurrentlyScrollingLayer()); @@ -2877,8 +3043,8 @@ host_impl_->ScrollBy(gfx::Point(), scroll_delta); EXPECT_EQ(top_controls_height_, - host_impl_->active_tree()->total_top_controls_content_offset()); - EXPECT_EQ( + host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ( inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_), host_impl_->InnerViewportScrollLayer()->ScrollDelta().y()); @@ -2911,8 +3077,8 @@ host_impl_->top_controls_manager()->ScrollBegin(); host_impl_->top_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); - EXPECT_EQ(-scroll_increment_y, - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(-scroll_increment_y, + host_impl_->top_controls_manager()->ContentTopOffset()); // Now that top controls have moved, expect the clip to resize. EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() + scroll_increment_y), @@ -2921,8 +3087,8 @@ host_impl_->top_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); host_impl_->top_controls_manager()->ScrollEnd(); - EXPECT_EQ(-2 * scroll_increment_y, - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(-2 * scroll_increment_y, + host_impl_->top_controls_manager()->ContentTopOffset()); // Now that top controls have moved, expect the clip to resize. EXPECT_EQ(clip_size_, root_clip_ptr->bounds()); @@ -3548,9 +3714,8 @@ // The layer should have scrolled down in its local coordinates. scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - ExpectContains(*scroll_info.get(), - scroll_layer->id(), - gfx::Vector2d(0, gesture_scroll_delta.x())); + ExpectContains(*scroll_info.get(), scroll_layer->id(), + gfx::Vector2dF(0, gesture_scroll_delta.x())); // Reset and scroll down with the wheel. scroll_layer->SetScrollDelta(gfx::Vector2dF()); @@ -3611,10 +3776,9 @@ // The child layer should have scrolled down in its local coordinates an // amount proportional to the angle between it and the input scroll delta. - gfx::Vector2d expected_scroll_delta( - 0, - gesture_scroll_delta.y() * - std::cos(MathUtil::Deg2Rad(child_layer_angle))); + gfx::Vector2dF expected_scroll_delta( + 0, gesture_scroll_delta.y() * + std::cos(MathUtil::Deg2Rad(child_layer_angle))); scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); @@ -3635,17 +3799,16 @@ // The child layer should have scrolled down in its local coordinates an // amount proportional to the angle between it and the input scroll delta. - gfx::Vector2d expected_scroll_delta( - 0, - -gesture_scroll_delta.x() * - std::sin(MathUtil::Deg2Rad(child_layer_angle))); + gfx::Vector2dF expected_scroll_delta( + 0, -gesture_scroll_delta.x() * + std::sin(MathUtil::Deg2Rad(child_layer_angle))); scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); // The root scroll layer should have scrolled more, since the input scroll // delta was mostly orthogonal to the child layer's vertical scroll axis. - gfx::Vector2d expected_root_scroll_delta( + gfx::Vector2dF expected_root_scroll_delta( gesture_scroll_delta.x() * std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2), 0); @@ -7283,9 +7446,8 @@ settings.calculate_top_controls_position = true; CreateHostImpl(settings, CreateOutputSurface()); host_impl_->active_tree()->set_top_controls_height(top_controls_height_); - host_impl_->active_tree()->set_top_controls_delta(top_controls_height_); - host_impl_->top_controls_manager()->SetTopControlsHeight( - top_controls_height_); + host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); + host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); } protected: @@ -7307,23 +7469,23 @@ host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(100); host_impl_->ActivateSyncTree(); - EXPECT_EQ(100, host_impl_->top_controls_manager()->top_controls_height()); + EXPECT_EQ(100, host_impl_->top_controls_manager()->TopControlsHeight()); } TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsStayFullyVisibleOnHeightChange) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - EXPECT_EQ(0.f, host_impl_->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(0); host_impl_->ActivateSyncTree(); - EXPECT_EQ(0.f, host_impl_->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(50); host_impl_->ActivateSyncTree(); - EXPECT_EQ(0.f, host_impl_->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); } TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) {
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index 1235e15..eecc5a0 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -26,10 +26,9 @@ bool FillsBoundsCompletely() const override { return false; } - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& rect, - ContentLayerClient::GraphicsContextStatus gc_status) override { + void PaintContents(SkCanvas* canvas, + const gfx::Rect& rect, + PaintingControlSetting picture_control) override { SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(SkIntToScalar(2)); @@ -49,7 +48,7 @@ scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); } @@ -97,9 +96,8 @@ SkCanvas canvas(bitmap); canvas.scale(SkIntToScalar(4), SkIntToScalar(4)); MaskContentLayerClient client(mask_bounds); - client.PaintContents(&canvas, - gfx::Rect(mask_bounds), - ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); + client.PaintContents(&canvas, gfx::Rect(mask_bounds), + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); mask->SetBitmap(bitmap); scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index 4d60baf3..5d828c5 100644 --- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
@@ -61,10 +61,9 @@ bool FillsBoundsCompletely() const override { return false; } - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override { + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override { SkPaint paint; paint.setColor(SK_ColorBLUE); canvas->drawRect(SkRect::MakeWH(layer_rect_.width(), @@ -82,7 +81,7 @@ scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); }
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc index 0a06144..6d3c6ec 100644 --- a/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -1144,6 +1144,38 @@ base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); } +class LayerTreeHostReadbackNonFirstNonRootRenderPassPixelTest + : public LayerTreeHostReadbackPixelTest, + public testing::WithParamInterface<bool> {}; + +TEST_P(LayerTreeHostReadbackNonFirstNonRootRenderPassPixelTest, + ReadbackNonRootOrFirstLayer) { + // This test has 3 render passes with the copy request on the render pass in + // the middle. Doing a copy request can be destructive of state, so for render + // passes after the first drawn the code path is different. This verifies the + // non-first and non-root path. See http://crbug.com/99393 for more info. + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); + + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); + blue->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( + base::Bind(&IgnoreReadbackResult))); + background->AddChild(blue); + + RunReadbackTestWithReadbackTarget( + GetParam() ? PIXEL_TEST_GL : PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + background.get(), + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); +} + +INSTANTIATE_TEST_CASE_P( + LayerTreeHostReadbackNonFirstNonRootRenderPassPixelTests, + LayerTreeHostReadbackNonFirstNonRootRenderPassPixelTest, + testing::Bool()); + } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 35828e3f..8dab1af16 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1106,17 +1106,16 @@ void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override { + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override { // Set layer opacity to 0. if (test_layer_) test_layer_->SetOpacity(0.f); } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); } @@ -2329,17 +2328,16 @@ int paint_count() const { return paint_count_; } - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override { - FakeContentLayerClient::PaintContents(canvas, clip, gc_status); + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override { + FakeContentLayerClient::PaintContents(canvas, clip, picture_control); ++paint_count_; } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); } @@ -2607,16 +2605,15 @@ void set_layer(Layer* layer) { layer_ = layer; } - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override { + void PaintContents(SkCanvas* canvas, + const gfx::Rect& clip, + PaintingControlSetting picture_control) override { layer_->SetBounds(gfx::Size(2, 2)); } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override { + PaintingControlSetting picture_control) override { NOTIMPLEMENTED(); return DisplayItemList::Create(); } @@ -5542,8 +5539,8 @@ EndTest(); } - void ApplyViewportDeltas(const gfx::Vector2d& inner, - const gfx::Vector2d& outer, + void ApplyViewportDeltas(const gfx::Vector2dF& inner, + const gfx::Vector2dF& outer, const gfx::Vector2dF& elastic_overscroll_delta, float scale_delta, float top_controls_delta) override {
diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc index 260bfbe..d2014eab 100644 --- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc +++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
@@ -58,8 +58,8 @@ void BeginMainFrame(const BeginFrameArgs& args) override {} void DidBeginMainFrame() override {} void Layout() override {} - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {}
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index 1c20b4c..03a0860 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -429,19 +429,14 @@ PostSetNeedsCommitToMainThread(); break; case 1: - EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), - gfx::ToFlooredVector2d(scroll_amount_)); - EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), - gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f)); + EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), scroll_amount_); + EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2dF()); PostSetNeedsCommitToMainThread(); break; case 2: - EXPECT_VECTOR_EQ( - scroll_layer->BaseScrollOffset(), - gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_)); - EXPECT_VECTOR_EQ( - scroll_layer->ScrollDelta(), - gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f)); + EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), + (scroll_amount_ + scroll_amount_)); + EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2dF()); EndTest(); break; } @@ -1044,21 +1039,24 @@ // Set max_scroll_offset = (100, 100). scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); - EXPECT_EQ(InputHandler::ScrollStarted, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), - InputHandler::Gesture)); + EXPECT_EQ( + InputHandler::ScrollStarted, + scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture, + ScrollBlocksOnNone)); // Set max_scroll_offset = (0, 0). scroll_layer->SetBounds(root->bounds()); - EXPECT_EQ(InputHandler::ScrollIgnored, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), - InputHandler::Gesture)); + EXPECT_EQ( + InputHandler::ScrollIgnored, + scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture, + ScrollBlocksOnNone)); // Set max_scroll_offset = (-100, -100). scroll_layer->SetBounds(gfx::Size()); - EXPECT_EQ(InputHandler::ScrollIgnored, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), - InputHandler::Gesture)); + EXPECT_EQ( + InputHandler::ScrollIgnored, + scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture, + ScrollBlocksOnNone)); EndTest(); }
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 97ebb009..0759425 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -4,6 +4,7 @@ #include "cc/trees/layer_tree_impl.h" +#include <algorithm> #include <limits> #include <set> @@ -76,6 +77,7 @@ LayerTreeImpl::LayerTreeImpl( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, + scoped_refptr<SyncedTopControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll) : layer_tree_host_impl_(layer_tree_host_impl), source_frame_number_(-1), @@ -102,9 +104,7 @@ render_surface_layer_list_id_(0), top_controls_shrink_blink_size_(false), top_controls_height_(0), - top_controls_content_offset_(0), - top_controls_delta_(0), - sent_top_controls_delta_(0) { + top_controls_shown_ratio_(top_controls_shown_ratio) { } LayerTreeImpl::~LayerTreeImpl() { @@ -122,7 +122,12 @@ void LayerTreeImpl::ReleaseResources() { if (root_layer_) - ReleaseResourcesRecursive(root_layer_.get()); + ProcessLayersRecursive(root_layer_.get(), &LayerImpl::ReleaseResources); +} + +void LayerTreeImpl::RecreateResources() { + if (root_layer_) + ProcessLayersRecursive(root_layer_.get(), &LayerImpl::RecreateResources); } void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { @@ -205,20 +210,10 @@ target_tree->PassSwapPromises(&swap_promise_list_); - // Track the change in top controls height to offset the top_controls_delta - // properly. This is so that the top controls offset will be maintained - // across height changes. - float top_controls_height_delta = - target_tree->top_controls_height_ - top_controls_height_; - - target_tree->top_controls_shrink_blink_size_ = - top_controls_shrink_blink_size_; - target_tree->top_controls_height_ = top_controls_height_; - target_tree->top_controls_content_offset_ = top_controls_content_offset_; - target_tree->top_controls_delta_ = target_tree->top_controls_delta_ - - target_tree->sent_top_controls_delta_ - - top_controls_height_delta; - target_tree->sent_top_controls_delta_ = 0.f; + target_tree->set_top_controls_shrink_blink_size( + top_controls_shrink_blink_size_); + target_tree->set_top_controls_height(top_controls_height_); + target_tree->PushTopControls(nullptr); // Active tree already shares the page_scale_factor object with pending // tree so only the limits need to be provided. @@ -359,6 +354,48 @@ DidUpdatePageScale(); } +void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) { + if (top_controls_shrink_blink_size_ == shrink) + return; + + top_controls_shrink_blink_size_ = shrink; + if (IsActiveTree()) + layer_tree_host_impl_->UpdateViewportContainerSizes(); +} + +void LayerTreeImpl::set_top_controls_height(float top_controls_height) { + if (top_controls_height_ == top_controls_height) + return; + + top_controls_height_ = top_controls_height; + if (IsActiveTree()) + layer_tree_host_impl_->UpdateViewportContainerSizes(); +} + +bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) { + ratio = std::max(ratio, 0.f); + ratio = std::min(ratio, 1.f); + return top_controls_shown_ratio_->SetCurrent(ratio); +} + +void LayerTreeImpl::PushTopControlsFromMainThread( + float top_controls_shown_ratio) { + PushTopControls(&top_controls_shown_ratio); +} + +void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) { + DCHECK(top_controls_shown_ratio || IsActiveTree()); + + if (top_controls_shown_ratio) { + DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree()); + top_controls_shown_ratio_->PushFromMainThread(*top_controls_shown_ratio); + } + if (IsActiveTree()) { + if (top_controls_shown_ratio_->PushPendingToActive()) + layer_tree_host_impl_->DidChangeTopControlsPosition(); + } +} + bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor, float max_page_scale_factor) { if (min_page_scale_factor == min_page_scale_factor_ && @@ -446,12 +483,9 @@ DCHECK(IsActiveTree()); page_scale_factor()->AbortCommit(); + top_controls_shown_ratio()->AbortCommit(); elastic_overscroll()->AbortCommit(); - top_controls_content_offset_ += sent_top_controls_delta_; - top_controls_delta_ -= sent_top_controls_delta_; - sent_top_controls_delta_ = 0.f; - if (!root_layer()) return; @@ -1159,15 +1193,16 @@ return layers_with_copy_output_request_; } -void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) { +void LayerTreeImpl::ProcessLayersRecursive(LayerImpl* current, + void (LayerImpl::*function)()) { DCHECK(current); - current->ReleaseResources(); + (current->*function)(); if (current->mask_layer()) - ReleaseResourcesRecursive(current->mask_layer()); + ProcessLayersRecursive(current->mask_layer(), function); if (current->replica_layer()) - ReleaseResourcesRecursive(current->replica_layer()); + ProcessLayersRecursive(current->replica_layer(), function); for (size_t i = 0; i < current->children().size(); ++i) - ReleaseResourcesRecursive(current->children()[i]); + ProcessLayersRecursive(current->children()[i], function); } template <typename LayerType>
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index a58b645..19bba86 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -19,10 +19,16 @@ #include "cc/resources/ui_resource_client.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { @@ -49,6 +55,7 @@ struct SelectionHandle; typedef std::vector<UIResourceRequest> UIResourceRequestQueue; +typedef SyncedProperty<AdditionGroup<float>> SyncedTopControls; typedef SyncedProperty<AdditionGroup<gfx::Vector2dF>> SyncedElasticOverscroll; class CC_EXPORT LayerTreeImpl { @@ -56,14 +63,17 @@ static scoped_ptr<LayerTreeImpl> create( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, + scoped_refptr<SyncedTopControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll) { - return make_scoped_ptr(new LayerTreeImpl( - layer_tree_host_impl, page_scale_factor, elastic_overscroll)); + return make_scoped_ptr( + new LayerTreeImpl(layer_tree_host_impl, page_scale_factor, + top_controls_shown_ratio, elastic_overscroll)); } virtual ~LayerTreeImpl(); void Shutdown(); void ReleaseResources(); + void RecreateResources(); // Methods called by the layer tree that pass-through or access LTHI. // --------------------------------------------------------------------------- @@ -185,6 +195,13 @@ return elastic_overscroll_.get(); } + SyncedTopControls* top_controls_shown_ratio() { + return top_controls_shown_ratio_.get(); + } + const SyncedTopControls* top_controls_shown_ratio() const { + return top_controls_shown_ratio_.get(); + } + // Updates draw properties and render surface layer list, as well as tile // priorities. Returns false if it was unable to update. bool UpdateDrawProperties(); @@ -296,36 +313,17 @@ void RegisterPictureLayerImpl(PictureLayerImpl* layer); void UnregisterPictureLayerImpl(PictureLayerImpl* layer); - void set_top_controls_shrink_blink_size(bool shrink) { - top_controls_shrink_blink_size_ = shrink; - } - void set_top_controls_height(float height) { top_controls_height_ = height; } - void set_top_controls_content_offset(float offset) { - top_controls_content_offset_ = offset; - } - void set_top_controls_delta(float delta) { - top_controls_delta_ = delta; - } - void set_sent_top_controls_delta(float sent_delta) { - sent_top_controls_delta_ = sent_delta; - } - + void set_top_controls_shrink_blink_size(bool shrink); bool top_controls_shrink_blink_size() const { return top_controls_shrink_blink_size_; } + bool SetCurrentTopControlsShownRatio(float ratio); + float CurrentTopControlsShownRatio() const { + return top_controls_shown_ratio_->Current(IsActiveTree()); + } + void set_top_controls_height(float top_controls_height); float top_controls_height() const { return top_controls_height_; } - float top_controls_content_offset() const { - return top_controls_content_offset_; - } - float top_controls_delta() const { - return top_controls_delta_; - } - float sent_top_controls_delta() const { - return sent_top_controls_delta_; - } - float total_top_controls_content_offset() const { - return top_controls_content_offset_ + top_controls_delta_; - } + void PushTopControlsFromMainThread(float top_controls_shown_ratio); void SetPendingPageScaleAnimation( scoped_ptr<PendingPageScaleAnimation> pending_animation); @@ -335,8 +333,10 @@ explicit LayerTreeImpl( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, + scoped_refptr<SyncedTopControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll); - void ReleaseResourcesRecursive(LayerImpl* current); + void ProcessLayersRecursive(LayerImpl* current, + void (LayerImpl::*function)()); float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, float min_page_scale_factor, @@ -345,7 +345,7 @@ float max_page_scale_factor); void DidUpdatePageScale(); void HideInnerViewportScrollbarsIfNearMinimumScale(); - + void PushTopControls(const float* top_controls_shown_ratio); LayerTreeHostImpl* layer_tree_host_impl_; int source_frame_number_; scoped_ptr<LayerImpl> root_layer_; @@ -408,11 +408,9 @@ float top_controls_height_; - // The up-to-date content offset of the top controls, i.e. the amount that the - // web contents have been shifted down from the top of the device viewport. - float top_controls_content_offset_; - float top_controls_delta_; - float sent_top_controls_delta_; + // The amount that the top controls are shown from 0 (hidden) to 1 (fully + // shown). + scoped_refptr<SyncedTopControls> top_controls_shown_ratio_; scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 5eacdf8..8ba859a 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -9,7 +9,9 @@ #include "cc/base/cc_export.h" #include "cc/debug/layer_tree_debug_state.h" #include "cc/output/renderer_settings.h" +#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkTypeface.h" #include "ui/gfx/geometry/size.h" namespace cc { @@ -83,6 +85,7 @@ bool record_full_layer; bool use_display_lists; bool verify_property_trees; + skia::RefPtr<SkTypeface> hud_typeface; LayerTreeDebugState initial_debug_state; };
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 1afd4bdd..934e1fc 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -171,10 +171,12 @@ } TransformNode* node = data_for_children->transform_tree->back(); + layer->set_transform_tree_index(node->id); node->data.flattens = layer->should_flatten_transform(); node->data.target_id = data_from_ancestor.render_target->transform_tree_index(); + DCHECK_NE(node->data.target_id, -1); node->data.is_animated = layer->TransformIsAnimating(); gfx::Transform transform; @@ -214,7 +216,6 @@ data_from_ancestor.transform_tree->UpdateScreenSpaceTransform(node->id); layer->set_offset_to_transform_parent(gfx::Vector2dF()); - layer->set_transform_tree_index(node->id); } void BuildPropertyTreesInternal(Layer* layer,
diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index 206af66d..2f181fc 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h
@@ -17,11 +17,17 @@ #include "cc/base/cc_export.h" namespace base { -namespace debug { +namespace trace_event { class TracedValue; } -class SingleThreadTaskRunner; + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } +class SingleThreadTaskRunner; +} // namespace base namespace gfx { class Rect;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 6deb300..903ff50 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -51,8 +51,6 @@ "app/chrome_watcher_command_line_win.h", "app/client_util.cc", "app/client_util.h", - "app/chrome_watcher_command_line_win.cc", - "app/chrome_watcher_command_line_win.h", "app/signature_validator_win.cc", "app/signature_validator_win.h", "common/crash_keys.cc", @@ -154,7 +152,7 @@ # TODO(GYP) some stuff from GYP including chrome_multiple_dll. } - if (enable_plugins) { + if (is_linux && enable_plugins) { deps += [ "//pdf" ] } }
diff --git a/chrome/VERSION b/chrome/VERSION index fdcf034..acd0166 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=42 MINOR=0 -BUILD=2296 +BUILD=2300 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 2e86b19..b7dd7d0 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -108,6 +108,7 @@ "//chrome:page_info_connection_type_javagen", "//chrome:content_setting_javagen", "//chrome:content_settings_type_javagen", + "//components/enhanced_bookmarks:enhanced_bookmarks_launch_location_srcjar", ] DEPRECATED_java_in_dir = "java/src" @@ -456,6 +457,7 @@ "//sync:sync_java_test_support", "//third_party/android_tools:android_support_v13_java", "//third_party/android_tools:android_support_v7_appcompat_java", + "//ui/android:ui_java", ] apk_name = "ChromeSyncShellTest" DEPRECATED_java_in_dir = "sync_shell/javatests/src"
diff --git a/chrome/android/java/res/color/edit_text_tint.xml b/chrome/android/java/res/color/edit_text_tint.xml index 81dde28..228f36b 100644 --- a/chrome/android/java/res/color/edit_text_tint.xml +++ b/chrome/android/java/res/color/edit_text_tint.xml
@@ -11,5 +11,5 @@ <item android:state_enabled="false" android:alpha="@dimen/disabled_alpha_material_dark" android:color="@color/default_text_color" /> - <item android:color="@color/default_text_color" /> + <item android:color="@color/input_underline_color" /> </selector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable-hdpi/btn_incognito_tabs.png b/chrome/android/java/res/drawable-hdpi/btn_incognito_tabs.png new file mode 100644 index 0000000..b502b2f --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/btn_incognito_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/btn_normal_tabs.png b/chrome/android/java/res/drawable-hdpi/btn_normal_tabs.png new file mode 100644 index 0000000..33dc5c6 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/btn_normal_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/google_play.png b/chrome/android/java/res/drawable-hdpi/google_play.png new file mode 100644 index 0000000..9d872d6a --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/google_play.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_collapse.png b/chrome/android/java/res/drawable-hdpi/ic_collapse.png new file mode 100644 index 0000000..979661d --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_collapse.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_expand.png b/chrome/android/java/res/drawable-hdpi/ic_expand.png new file mode 100644 index 0000000..355d8f97 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_expand.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_expand_less.png b/chrome/android/java/res/drawable-hdpi/ic_expand_less.png deleted file mode 100644 index 09ad8b1..0000000 --- a/chrome/android/java/res/drawable-hdpi/ic_expand_less.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_expand_more.png b/chrome/android/java/res/drawable-hdpi/ic_expand_more.png deleted file mode 100644 index acb01ebc..0000000 --- a/chrome/android/java/res/drawable-hdpi/ic_expand_more.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/star_gray.png b/chrome/android/java/res/drawable-hdpi/star_gray.png new file mode 100644 index 0000000..074c0c8 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/star_gray.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/star_green.png b/chrome/android/java/res/drawable-hdpi/star_green.png new file mode 100644 index 0000000..417e79b --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/star_green.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tab_close_white.png b/chrome/android/java/res/drawable-hdpi/tab_close_white.png deleted file mode 100644 index f9dc0638..0000000 --- a/chrome/android/java/res/drawable-hdpi/tab_close_white.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tab_close_white_active.png b/chrome/android/java/res/drawable-hdpi/tab_close_white_active.png deleted file mode 100644 index a53f578..0000000 --- a/chrome/android/java/res/drawable-hdpi/tab_close_white_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito.png b/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito.png deleted file mode 100644 index ff71d0d9..0000000 --- a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito_active.png b/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito_active.png deleted file mode 100644 index 0781e05..0000000 --- a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_incognito_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal.png b/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal.png deleted file mode 100644 index cde042a..0000000 --- a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal_active.png b/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal_active.png deleted file mode 100644 index bfb13c9b..0000000 --- a/chrome/android/java/res/drawable-hdpi/tabstrip_incognito_switch_normal_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_incognito_tabs.png b/chrome/android/java/res/drawable-mdpi/btn_incognito_tabs.png new file mode 100644 index 0000000..8c616c3 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/btn_incognito_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_normal_tabs.png b/chrome/android/java/res/drawable-mdpi/btn_normal_tabs.png new file mode 100644 index 0000000..4a11db5 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/btn_normal_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/google_play.png b/chrome/android/java/res/drawable-mdpi/google_play.png new file mode 100644 index 0000000..c77683b6 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/google_play.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_collapse.png b/chrome/android/java/res/drawable-mdpi/ic_collapse.png new file mode 100644 index 0000000..69c35bd --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_collapse.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_expand.png b/chrome/android/java/res/drawable-mdpi/ic_expand.png new file mode 100644 index 0000000..fe2088d --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_expand.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_expand_less.png b/chrome/android/java/res/drawable-mdpi/ic_expand_less.png deleted file mode 100644 index a91d298..0000000 --- a/chrome/android/java/res/drawable-mdpi/ic_expand_less.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_expand_more.png b/chrome/android/java/res/drawable-mdpi/ic_expand_more.png deleted file mode 100644 index f33b069..0000000 --- a/chrome/android/java/res/drawable-mdpi/ic_expand_more.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/star_gray.png b/chrome/android/java/res/drawable-mdpi/star_gray.png new file mode 100644 index 0000000..613d3e23 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/star_gray.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/star_green.png b/chrome/android/java/res/drawable-mdpi/star_green.png new file mode 100644 index 0000000..01583ef --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/star_green.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tab_close_white.png b/chrome/android/java/res/drawable-mdpi/tab_close_white.png deleted file mode 100644 index 114b207..0000000 --- a/chrome/android/java/res/drawable-mdpi/tab_close_white.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tab_close_white_active.png b/chrome/android/java/res/drawable-mdpi/tab_close_white_active.png deleted file mode 100644 index fd63f27..0000000 --- a/chrome/android/java/res/drawable-mdpi/tab_close_white_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito.png b/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito.png deleted file mode 100644 index 7b65431..0000000 --- a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito_active.png b/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito_active.png deleted file mode 100644 index 117ccf8..0000000 --- a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_incognito_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal.png b/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal.png deleted file mode 100644 index 66a6f85..0000000 --- a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal_active.png b/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal_active.png deleted file mode 100644 index 3d3a878..0000000 --- a/chrome/android/java/res/drawable-mdpi/tabstrip_incognito_switch_normal_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-v21/button_borderless_compat.xml b/chrome/android/java/res/drawable-v21/button_borderless_compat.xml new file mode 100644 index 0000000..472fe1c --- /dev/null +++ b/chrome/android/java/res/drawable-v21/button_borderless_compat.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?attr/colorControlHighlight"> + <item android:id="@android:id/mask" + android:drawable="@drawable/button_compat_shape" /> +</ripple>
diff --git a/chrome/android/java/res/drawable-v21/button_compat.xml b/chrome/android/java/res/drawable-v21/button_compat.xml new file mode 100644 index 0000000..62992f2 --- /dev/null +++ b/chrome/android/java/res/drawable-v21/button_compat.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?attr/colorControlHighlight"> + <item android:drawable="@drawable/button_compat_shape" /> +</ripple>
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_incognito_tabs.png b/chrome/android/java/res/drawable-xhdpi/btn_incognito_tabs.png new file mode 100644 index 0000000..bc2ef8a --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/btn_incognito_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_normal_tabs.png b/chrome/android/java/res/drawable-xhdpi/btn_normal_tabs.png new file mode 100644 index 0000000..cda2fdd --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/btn_normal_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/google_play.png b/chrome/android/java/res/drawable-xhdpi/google_play.png new file mode 100644 index 0000000..78011be --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/google_play.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_collapse.png b/chrome/android/java/res/drawable-xhdpi/ic_collapse.png new file mode 100644 index 0000000..dae11cc1 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_collapse.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_expand.png b/chrome/android/java/res/drawable-xhdpi/ic_expand.png new file mode 100644 index 0000000..3a92185 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_expand.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_expand_less.png b/chrome/android/java/res/drawable-xhdpi/ic_expand_less.png deleted file mode 100644 index c13b4da..0000000 --- a/chrome/android/java/res/drawable-xhdpi/ic_expand_less.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_expand_more.png b/chrome/android/java/res/drawable-xhdpi/ic_expand_more.png deleted file mode 100644 index dfbd9be..0000000 --- a/chrome/android/java/res/drawable-xhdpi/ic_expand_more.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/star_gray.png b/chrome/android/java/res/drawable-xhdpi/star_gray.png new file mode 100644 index 0000000..13cd9851 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/star_gray.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/star_green.png b/chrome/android/java/res/drawable-xhdpi/star_green.png new file mode 100644 index 0000000..0ee5e8b --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/star_green.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tab_close_white.png b/chrome/android/java/res/drawable-xhdpi/tab_close_white.png deleted file mode 100644 index 8e44ede9..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tab_close_white.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tab_close_white_active.png b/chrome/android/java/res/drawable-xhdpi/tab_close_white_active.png deleted file mode 100644 index 8499cd0..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tab_close_white_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito.png b/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito.png deleted file mode 100644 index ec5da210..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito_active.png b/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito_active.png deleted file mode 100644 index 09a6e30..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_incognito_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal.png b/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal.png deleted file mode 100644 index 359129082..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal_active.png b/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal_active.png deleted file mode 100644 index 4f1b7d5d..0000000 --- a/chrome/android/java/res/drawable-xhdpi/tabstrip_incognito_switch_normal_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_incognito_tabs.png b/chrome/android/java/res/drawable-xxhdpi/btn_incognito_tabs.png new file mode 100644 index 0000000..f2de4444 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/btn_incognito_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_normal_tabs.png b/chrome/android/java/res/drawable-xxhdpi/btn_normal_tabs.png new file mode 100644 index 0000000..facef2f --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/btn_normal_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/card_background_default.9.png b/chrome/android/java/res/drawable-xxhdpi/card_background_default.9.png deleted file mode 100644 index 7036d64..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/card_background_default.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/google_play.png b/chrome/android/java/res/drawable-xxhdpi/google_play.png new file mode 100644 index 0000000..56cde19e --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/google_play.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_collapse.png b/chrome/android/java/res/drawable-xxhdpi/ic_collapse.png new file mode 100644 index 0000000..5f91ae6 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_collapse.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_expand.png b/chrome/android/java/res/drawable-xxhdpi/ic_expand.png new file mode 100644 index 0000000..d1f0187 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_expand.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_expand_less.png b/chrome/android/java/res/drawable-xxhdpi/ic_expand_less.png deleted file mode 100644 index 1ad004a..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/ic_expand_less.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_expand_more.png b/chrome/android/java/res/drawable-xxhdpi/ic_expand_more.png deleted file mode 100644 index f9b619ab..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/ic_expand_more.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/star_gray.png b/chrome/android/java/res/drawable-xxhdpi/star_gray.png new file mode 100644 index 0000000..1ca389f --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/star_gray.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/star_green.png b/chrome/android/java/res/drawable-xxhdpi/star_green.png new file mode 100644 index 0000000..a526a09 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/star_green.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tab_close_white.png b/chrome/android/java/res/drawable-xxhdpi/tab_close_white.png deleted file mode 100644 index f2380f54..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tab_close_white.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tab_close_white_active.png b/chrome/android/java/res/drawable-xxhdpi/tab_close_white_active.png deleted file mode 100644 index cf959edb..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tab_close_white_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito.png b/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito.png deleted file mode 100644 index b012a8b..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito_active.png b/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito_active.png deleted file mode 100644 index 617a63a..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_incognito_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal.png b/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal.png deleted file mode 100644 index b8ba8d61..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal_active.png b/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal_active.png deleted file mode 100644 index 284c5ff..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/tabstrip_incognito_switch_normal_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_incognito_tabs.png b/chrome/android/java/res/drawable-xxxhdpi/btn_incognito_tabs.png new file mode 100644 index 0000000..9959ce11 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/btn_incognito_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_normal_tabs.png b/chrome/android/java/res/drawable-xxxhdpi/btn_normal_tabs.png new file mode 100644 index 0000000..ec73e48 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/btn_normal_tabs.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/google_play.png b/chrome/android/java/res/drawable-xxxhdpi/google_play.png new file mode 100644 index 0000000..59c57ef --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/google_play.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_collapse.png b/chrome/android/java/res/drawable-xxxhdpi/ic_collapse.png new file mode 100644 index 0000000..2e13231 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_collapse.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_expand.png b/chrome/android/java/res/drawable-xxxhdpi/ic_expand.png new file mode 100644 index 0000000..fe5c01c8 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_expand.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_expand_less.png b/chrome/android/java/res/drawable-xxxhdpi/ic_expand_less.png deleted file mode 100644 index da39a759..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/ic_expand_less.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_expand_more.png b/chrome/android/java/res/drawable-xxxhdpi/ic_expand_more.png deleted file mode 100644 index e3d9ff3f..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/ic_expand_more.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/star_gray.png b/chrome/android/java/res/drawable-xxxhdpi/star_gray.png new file mode 100644 index 0000000..014bc4a --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/star_gray.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/star_green.png b/chrome/android/java/res/drawable-xxxhdpi/star_green.png new file mode 100644 index 0000000..377b3f97a --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/star_green.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tab_close_white.png b/chrome/android/java/res/drawable-xxxhdpi/tab_close_white.png deleted file mode 100644 index c9aaa8b..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tab_close_white.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tab_close_white_active.png b/chrome/android/java/res/drawable-xxxhdpi/tab_close_white_active.png deleted file mode 100644 index e43f417..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tab_close_white_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito.png b/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito.png deleted file mode 100644 index 96ca9ca3..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito_active.png b/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito_active.png deleted file mode 100644 index b40a12a..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_incognito_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal.png b/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal.png deleted file mode 100644 index 1c9a9cc..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal_active.png b/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal_active.png deleted file mode 100644 index 845a099..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_incognito_switch_normal_active.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable/btn_tab_close.xml b/chrome/android/java/res/drawable/btn_tab_close.xml deleted file mode 100644 index d2f1ed8..0000000 --- a/chrome/android/java/res/drawable/btn_tab_close.xml +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="false" - android:drawable="@drawable/tab_close_white" /> - <item android:state_pressed="true" - android:drawable="@drawable/tab_close_white_active" /> - <item android:state_selected="true" - android:drawable="@drawable/tab_close_white_active" /> - <item android:state_focused="true" - android:drawable="@drawable/tab_close_white_active" /> - <item android:drawable="@drawable/tab_close_white" /> -</selector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch.xml b/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch.xml deleted file mode 100644 index 30b87978..0000000 --- a/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch.xml +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="false" - android:drawable="@drawable/tabstrip_incognito_switch_normal" /> - <item android:state_pressed="true" - android:drawable="@drawable/tabstrip_incognito_switch_normal_active" /> - <item android:state_selected="true" - android:drawable="@drawable/tabstrip_incognito_switch_normal_active" /> - <item android:state_focused="true" - android:drawable="@drawable/tabstrip_incognito_switch_normal_active" /> - <item android:drawable="@drawable/tabstrip_incognito_switch_normal" /> -</selector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch_incognito.xml b/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch_incognito.xml deleted file mode 100644 index c267eb2..0000000 --- a/chrome/android/java/res/drawable/btn_tabstrip_incognito_switch_incognito.xml +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="false" - android:drawable="@drawable/tabstrip_incognito_switch_incognito" /> - <item android:state_pressed="true" - android:drawable="@drawable/tabstrip_incognito_switch_incognito_active" /> - <item android:state_selected="true" - android:drawable="@drawable/tabstrip_incognito_switch_incognito_active" /> - <item android:state_focused="true" - android:drawable="@drawable/tabstrip_incognito_switch_incognito_active" /> - <item android:drawable="@drawable/tabstrip_incognito_switch_incognito" /> -</selector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/button_compat_shape.xml b/chrome/android/java/res/drawable/button_compat_shape.xml new file mode 100644 index 0000000..bbcfab2 --- /dev/null +++ b/chrome/android/java/res/drawable/button_compat_shape.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="#fff" /> + <corners android:radius="2dp" /> +</shape>
diff --git a/chrome/android/java/res/drawable/rating_bar.xml b/chrome/android/java/res/drawable/rating_bar.xml new file mode 100644 index 0000000..3adb580 --- /dev/null +++ b/chrome/android/java/res/drawable/rating_bar.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@android:id/background" android:drawable="@drawable/star_gray" /> + <item android:id="@android:id/secondaryProgress" android:drawable="@drawable/star_gray" /> + <item android:id="@android:id/progress" android:drawable="@drawable/star_green" /> +</layer-list> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/accessibility_tab_switcher.xml b/chrome/android/java/res/layout/accessibility_tab_switcher.xml index ff9b080..40237828 100644 --- a/chrome/android/java/res/layout/accessibility_tab_switcher.xml +++ b/chrome/android/java/res/layout/accessibility_tab_switcher.xml
@@ -8,6 +8,7 @@ <org.chromium.chrome.browser.widget.accessibility.AccessibilityTabModelWrapper xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:chrome="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" @@ -30,13 +31,14 @@ android:id="@+id/button_wrapper" android:visibility="gone"> - <ImageButton + <org.chromium.chrome.browser.widget.TintedImageButton android:id="@+id/standard_tabs_button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/btn_bg_holo_active" - android:src="@drawable/btn_tabstrip_incognito_switch" + android:src="@drawable/btn_normal_tabs" + chrome:tint="@color/light_mode_tint" android:contentDescription="@string/accessibility_tab_switcher_standard_stack" style="?android:attr/borderlessButtonStyle" /> @@ -46,12 +48,13 @@ android:layout_gravity="center_vertical" android:background="#292929" /> - <ImageButton + <org.chromium.chrome.browser.widget.TintedImageButton android:id="@+id/incognito_tabs_button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:src="@drawable/btn_tabstrip_incognito_switch_incognito" + android:src="@drawable/btn_incognito_tabs" + chrome:tint="@color/light_mode_tint" android:background="@drawable/btn_bg_holo" android:contentDescription="@string/accessibility_tab_switcher_incognito_stack" style="?android:attr/borderlessButtonStyle" />
diff --git a/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml b/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml index 152920e..66addb2 100644 --- a/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml +++ b/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml
@@ -8,6 +8,7 @@ <org.chromium.chrome.browser.widget.accessibility.AccessibilityTabModelListItem xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:chrome="http://schemas.android.com/apk/res-auto" android:id="@+id/list_item_frame" android:layout_width="match_parent" android:layout_height="@dimen/accessibility_tab_height"> @@ -40,7 +41,7 @@ android:padding="4dp" android:textColor="@android:color/white" android:textSize="18sp" /> - <ImageButton + <org.chromium.chrome.browser.widget.TintedImageButton android:id="@+id/close_btn" android:scaleType="centerInside" android:layout_width="wrap_content" @@ -49,7 +50,8 @@ android:padding="4dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/accessibility_tabstrip_btn_close_tab" - android:src="@drawable/btn_tab_close" + android:src="@drawable/btn_close" + chrome:tint="@color/light_mode_tint" android:gravity="end|center_vertical" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/app_banner_title.xml b/chrome/android/java/res/layout/app_banner_title.xml new file mode 100644 index 0000000..f2e1098 --- /dev/null +++ b/chrome/android/java/res/layout/app_banner_title.xml
@@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="start" > + + <TextView + android:id="@+id/app_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fontFamily="sans-serif-medium" + android:singleLine="true" + android:textAlignment="viewStart" + android:textSize="18sp" + android:textColor="@color/default_text_color" /> + + <RatingBar + android:id="@+id/rating_bar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:progressDrawable="@drawable/rating_bar" + android:indeterminateDrawable="@drawable/rating_bar" + android:minHeight="16dp" + android:maxHeight="16dp" + android:isIndicator="true" + android:numStars="5" + android:stepSize="0.5" /> + + <TextView + android:id="@+id/web_app_url" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:singleLine="true" + android:textAlignment="viewStart" + android:textSize="14sp" + android:textColor="#646464" /> + +</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/app_banner_view.xml b/chrome/android/java/res/layout/app_banner_view.xml deleted file mode 100644 index 10b834a..0000000 --- a/chrome/android/java/res/layout/app_banner_view.xml +++ /dev/null
@@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<org.chromium.chrome.browser.banners.AppBannerView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/app_banner_view" - android:background="@drawable/card_background_default" - android:clickable="true" - android:focusableInTouchMode="true" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <FrameLayout - android:id="@+id/banner_container" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <!-- View showing the icon. --> - <ImageView - android:id="@+id/app_icon" - android:adjustViewBounds="true" - android:layout_width="wrap_content" - android:layout_height="@dimen/app_banner_icon_size" - android:layout_marginEnd="@dimen/app_banner_icon_margin_end" /> - - <!-- View showing the app's title. --> - <TextView - android:id="@+id/app_title" - android:textAppearance="@style/AppBannerTitle" - android:includeFontPadding="false" - android:lines="1" - android:ellipsize="end" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/app_banner_title_margin_top" - android:layout_marginBottom="@dimen/app_banner_title_margin_bottom" /> - - <!-- Button that triggers installation and opening of the app. --> - <Button - android:id="@+id/app_install_button" - style="@style/AppBannerButton" - android:textColor="@color/app_banner_install_button_fg" - android:ellipsize="end" - android:singleLine="true" - android:minHeight="@dimen/app_banner_button_height" - android:paddingStart="@dimen/app_banner_button_padding_sides" - android:paddingEnd="@dimen/app_banner_button_padding_sides" - android:paddingTop="@dimen/app_banner_button_padding_above_below" - android:paddingBottom="@dimen/app_banner_button_padding_above_below" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/app_banner_button_margin_top" /> - - <!-- Logo for the store. --> - <ImageView - android:id="@+id/store_logo" - android:src="@drawable/google_play_logo" - android:adjustViewBounds="true" - android:layout_width="wrap_content" - android:layout_height="@dimen/app_banner_logo_height" - android:layout_marginTop="@dimen/app_banner_logo_margin_top" - android:layout_marginBottom="@dimen/app_banner_logo_margin_bottom" - android:layout_marginEnd="@dimen/app_banner_logo_margin_end"/> - - <!-- View showing how well the app is rated. --> - <org.chromium.chrome.browser.banners.RatingView - android:id="@+id/app_rating" - android:adjustViewBounds="true" - android:layout_width="wrap_content" - android:layout_height="@dimen/app_banner_star_height" /> - - <!-- Button that closes the banner. --> - <ImageButton - android:id="@+id/close_button" - android:contentDescription="@string/infobar_close" - android:adjustViewBounds="true" - android:src="@drawable/btn_close" - android:background="@drawable/app_banner_button_close" - android:padding="@dimen/app_banner_close_button_padding" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - - <!-- View covering the entire banner. Used to indicate the banner is highlighted. --> - <View - android:id="@+id/banner_highlight" - android:background="@color/app_banner_card_highlight" - android:visibility="gone" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - </FrameLayout> -</org.chromium.chrome.browser.banners.AppBannerView>
diff --git a/chrome/android/java/res/layout/autofill_credit_card_editor.xml b/chrome/android/java/res/layout/autofill_credit_card_editor.xml index 2211041..4ef788d 100644 --- a/chrome/android/java/res/layout/autofill_credit_card_editor.xml +++ b/chrome/android/java/res/layout/autofill_credit_card_editor.xml
@@ -20,28 +20,31 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:focusableInTouchMode="true" > + android:focusableInTouchMode="true" + android:paddingTop="6dp" > <org.chromium.chrome.browser.widget.FloatLabelLayout + android:id="@+id/credit_card_name_label" android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText - android:id="@+id/autofill_credit_card_editor_name_edit" + android:id="@+id/credit_card_name_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:imeOptions="flagNoExtractUi" - android:contentDescription="@string/accessibility_autofill_cc_name_textbox" + android:contentDescription="@string/autofill_credit_card_editor_name" android:inputType="textCapWords" android:hint="@string/autofill_credit_card_editor_name" /> </org.chromium.chrome.browser.widget.FloatLabelLayout> <org.chromium.chrome.browser.widget.FloatLabelLayout + android:id="@+id/credit_card_number_label" android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText - android:id="@+id/autofill_credit_card_editor_number_edit" + android:id="@+id/credit_card_number_edit" android:layout_width="match_parent" - android:contentDescription="@string/accessibility_autofill_cc_number_textbox" + android:contentDescription="@string/autofill_credit_card_editor_number" android:layout_height="wrap_content" android:imeOptions="flagNoExtractUi" android:inputType="phone" @@ -53,28 +56,44 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:focusable="true" - android:paddingTop="10dp" + android:paddingTop="@dimen/pref_autofill_field_top_padding" android:textAppearance="@style/PreferenceFloatLabelTextAppearance" - android:text="@string/autofill_credit_card_editor_expiration_date" /> + android:text="@string/autofill_credit_card_editor_expiration_date" + android:paddingStart="@dimen/pref_autofill_field_horizontal_padding" + android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" > + android:orientation="horizontal" + android:paddingTop="8dp" + android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding" + android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" > - <Spinner - android:id="@+id/autofill_credit_card_editor_month_spinner" + <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:paddingTop="8dp" /> + android:orientation="vertical" + android:paddingEnd="10dp" > + <Spinner + android:id="@+id/autofill_credit_card_editor_month_spinner" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <View style="@style/PreferenceSpinnerUnderlineView" /> + </LinearLayout> - <Spinner - android:id="@+id/autofill_credit_card_editor_year_spinner" + <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:paddingTop="8dp" /> + android:orientation="vertical" > + <Spinner + android:id="@+id/autofill_credit_card_editor_year_spinner" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <View style="@style/PreferenceSpinnerUnderlineView" /> + </LinearLayout> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/autofill_profile_editor.xml b/chrome/android/java/res/layout/autofill_profile_editor.xml index 6f06d18..209f6372 100644 --- a/chrome/android/java/res/layout/autofill_profile_editor.xml +++ b/chrome/android/java/res/layout/autofill_profile_editor.xml
@@ -19,19 +19,29 @@ style="@style/PreferenceScreenLayout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical"> + android:orientation="vertical" > <!-- Editable fields for the profile --> - <TextView + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:focusable="true" - android:textAppearance="@style/PreferenceFloatLabelTextAppearance" - android:text="@string/autofill_profile_editor_country" /> - <Spinner - android:id="@+id/countries" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> + android:layout_height="match_parent" + android:orientation="vertical" + android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding" + android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" + android:paddingBottom="5dp" > + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="true" + android:textAppearance="@style/PreferenceFloatLabelTextAppearance" + android:text="@string/autofill_profile_editor_country" + android:paddingBottom="8dp" /> + <Spinner + android:id="@+id/countries" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + <View style="@style/PreferenceSpinnerUnderlineView" /> + </LinearLayout> <LinearLayout android:id="@+id/autofill_profile_widget_root"
diff --git a/chrome/android/java/res/layout/infobar_text.xml b/chrome/android/java/res/layout/infobar_text.xml index 1dd4198..cdc2f7c 100644 --- a/chrome/android/java/res/layout/infobar_text.xml +++ b/chrome/android/java/res/layout/infobar_text.xml
@@ -1,15 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2013 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> + found in the LICENSE file. --> <org.chromium.ui.widget.TextViewWithClickableSpans xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/infobar_message" - android:layout_marginTop="@dimen/infobar_margin" - android:layout_marginBottom="@dimen/infobar_margin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineSpacingMultiplier="1.25"
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 18f7f56..5fe7c958f 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -11,7 +11,11 @@ <item name="android:buttonStyle">@style/PreferenceButtonStyle</item> <item name="android:textAppearanceMedium">@style/PreferenceTextAppearanceMedium</item> <item name="android:preferenceCategoryStyle">@style/PreferenceCategory</item> + <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> <item name="floatLabelTextAppearance">@style/PreferenceFloatLabelTextAppearance</item> + <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_padding</item> </style> <style name="PreferenceButtonStyle" parent="@android:style/Widget.Holo.Light.Button"> <!-- TODO(twellington): Delete btn_default_preferences.xml once the AppCompat theme supports @@ -72,6 +76,15 @@ <item name="android:textColor">@color/float_label</item> <item name="android:textSize">14sp</item> </style> + <style name="PreferenceSpinnerItem"> + <item name="android:textAppearance">@style/PreferenceTextAppearanceMedium</item> + </style> + <style name="PreferenceSpinnerUnderlineView"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">1dp</item> + <item name="android:layout_marginTop">2dp</item> + <item name="android:background">@color/input_underline_color</item> + </style> <style name="ThemeWithActionBar" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:windowBackground">@android:color/white</item> @@ -184,4 +197,25 @@ <item name="android:windowEnterAnimation">@anim/fullscreen_notification_in</item> </style> + <!-- Buttons --> + <style name="ButtonCompatBase"> + <item name="android:minWidth">88dp</item> + <item name="android:minHeight">36dp</item> + <item name="android:textSize">14sp</item> + <item name="android:paddingStart">20dp</item> + <item name="android:paddingEnd">20dp</item> + <item name="android:paddingTop">5dp</item> + <item name="android:paddingBottom">5dp</item> + <item name="android:textAllCaps">true</item> + <item name="android:focusable">true</item> + <item name="android:clickable">true</item> + <item name="android:gravity">center_vertical|center_horizontal</item> + </style> + <style name="ButtonCompat" parent="ButtonCompatBase"> + <item name="android:background">@drawable/button_compat_shape</item> + </style> + <style name="ButtonBorderlessCompat" parent="ButtonCompat"> + <item name="android:background">?attr/selectableItemBackground</item> + </style> + </resources>
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml index 3b5006a..6bbefde6 100644 --- a/chrome/android/java/res/values-v21/styles.xml +++ b/chrome/android/java/res/values-v21/styles.xml
@@ -12,7 +12,11 @@ <item name="android:colorButtonNormal">@color/btn_default_preferences</item> <item name="android:editTextBackground">@drawable/abc_edit_text_material</item> <item name="android:editTextStyle">@style/PreferenceEditTextStyle</item> + <item name="android:spinnerItemStyle">@style/PreferenceSpinnerItem</item> <item name="floatLabelTextAppearance">@style/PreferenceFloatLabelTextAppearance</item> + <item name="floatLabelPaddingLeft">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingRight">@dimen/pref_autofill_field_horizontal_padding</item> + <item name="floatLabelPaddingTop">@dimen/pref_autofill_field_top_padding</item> </style> <style name="PreferencesDialogTheme" parent="@android:style/Theme.Material.Light.Dialog.Alert"> <item name="android:colorAccent">@color/pref_accent_color</item> @@ -51,4 +55,13 @@ </style> <style name="PreferenceLayout" parent="PreferenceLayoutBase" /> + <!-- Buttons --> + <style name="ButtonCompat" parent="ButtonCompatBase"> + <item name="android:background">@drawable/button_compat</item> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + <style name="ButtonBorderlessCompat" parent="ButtonCompat"> + <item name="android:background">@drawable/button_borderless_compat</item> + </style> + </resources>
diff --git a/chrome/android/java/res/values/attrs.xml b/chrome/android/java/res/values/attrs.xml index 4a25bfd..dc01196 100644 --- a/chrome/android/java/res/values/attrs.xml +++ b/chrome/android/java/res/values/attrs.xml
@@ -30,4 +30,9 @@ <!-- The hint to display in the floating label --> <attr name="floatLabelHint" format="reference|string" /> </declare-styleable> + + <declare-styleable name="ButtonCompat"> + <attr name="buttonColor" format="reference|color"/> + </declare-styleable> + </resources>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index d2bd89ab..eda9411 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -10,6 +10,7 @@ <color name="default_primary_color">#f2f2f2</color> <color name="light_normal_color">#5A5A5A</color> <color name="light_active_color">#4285F4</color> + <color name="input_underline_color">#e5e5e5</color> <!-- Infobar colors --> <color name="infobar_background">#fff</color> @@ -30,6 +31,7 @@ <color name="accessibility_close_undo_text">#3adaff</color> <!-- App banner colors --> + <color name="app_banner_install_button_bg">#689f38</color> <color name="app_banner_install_button_fg">#ffffff</color> <color name="app_banner_open_button_fg">#777777</color> <color name="app_banner_card_highlight">#33999999</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index ee7a18a6..b46e348 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -56,6 +56,9 @@ <dimen name="infobar_icon_size">36dp</dimen> <!-- App banner dimensions --> + <dimen name="app_banner_infobar_icon_size">48dp</dimen> + <dimen name="app_banner_infobar_icon_spacing">16dp</dimen> + <dimen name="app_banner_max_width">424dp</dimen> <dimen name="app_banner_margin_sides">8dp</dimen> <dimen name="app_banner_margin_bottom">8dp</dimen> @@ -98,6 +101,8 @@ <dimen name="pref_button_vertical_padding">10dp</dimen> <dimen name="pref_homepage_layout_margin">10dp</dimen> + <dimen name="pref_autofill_field_horizontal_padding">3dp</dimen> + <dimen name="pref_autofill_field_top_padding">10dp</dimen> <!-- Minimum height/width for a touchable item --> <dimen name="min_touch_target_size">48dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java index 205804b..5409ede 100644 --- a/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java +++ b/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java
@@ -131,6 +131,12 @@ */ public static final String USE_SANDBOX_WALLET_ENVIRONMENT = "wallet-service-use-sandbox"; + /** + * Change Google base URL. + * Native switch - switches::kGoogleBaseURL. + */ + public static final String GOOGLE_BASE_URL = "google-base-url"; + // Prevent instantiation. private ChromeSwitches() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java index 860c2ab..f4828de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java
@@ -728,7 +728,9 @@ result.putBoolean(CLIENT_API_RESULT_KEY, isBookmarkInMobileBookmarksBranch(extras.getLong(argKey(0)))); } else if (CLIENT_API_DELETE_ALL_USER_BOOKMARKS.equals(method)) { + android.util.Log.i(TAG, "before nativeRemoveAllUserBookmarks"); nativeRemoveAllUserBookmarks(mNativeChromeBrowserProvider); + android.util.Log.i(TAG, "after nativeRemoveAllUserBookmarks"); } else { Log.w(TAG, "Received invalid method " + method); return null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProviderClient.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProviderClient.java index b7d7469..b42595fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProviderClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProviderClient.java
@@ -173,8 +173,10 @@ @SuppressWarnings("unchecked") private static <T extends Object> T chromeBrowserProviderCall(Class returnType, String name, Context context, Bundle args) { + android.util.Log.i(TAG, "before executing " + name + " call"); Bundle result = context.getContentResolver().call(getPrivateProviderUri(context), name, null, args); + android.util.Log.i(TAG, "after executing " + name + " call"); if (result == null) return null; if (Parcelable.class.isAssignableFrom(returnType)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromiumApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromiumApplication.java index 8e0ddec..646cc59 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromiumApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromiumApplication.java
@@ -4,8 +4,14 @@ package org.chromium.chrome.browser; +import android.os.Build; + import org.chromium.base.CalledByNative; import org.chromium.chrome.browser.preferences.LocationSettings; +import org.chromium.chrome.browser.preferences.PreferencesLauncher; +import org.chromium.chrome.browser.preferences.ProtectedContentPreferences; +import org.chromium.chrome.browser.preferences.autofill.AutofillPreferences; +import org.chromium.chrome.browser.preferences.password.ManageSavedPasswordsPreferences; import org.chromium.content.app.ContentApplication; /** @@ -23,13 +29,23 @@ * Opens a protected content settings page, if available. */ @CalledByNative - protected void openProtectedContentSettings() {} + protected void openProtectedContentSettings() { + assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + PreferencesLauncher.launchSettingsPage(this, + ProtectedContentPreferences.class.getName()); + } @CalledByNative - protected void showAutofillSettings() {} + protected void showAutofillSettings() { + PreferencesLauncher.launchSettingsPage(this, + AutofillPreferences.class.getName()); + } @CalledByNative - protected void showPasswordSettings() {} + protected void showPasswordSettings() { + PreferencesLauncher.launchSettingsPage(this, + ManageSavedPasswordsPreferences.class.getName()); + } /** * Returns an instance of LocationSettings to be installed as a singleton.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/EnhancedBookmarksBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/EnhancedBookmarksBridge.java index c04e753..3ff5ecc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/EnhancedBookmarksBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/EnhancedBookmarksBridge.java
@@ -4,6 +4,10 @@ package org.chromium.chrome.browser; +import android.graphics.Bitmap; +import android.util.LruCache; +import android.util.Pair; + import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; import org.chromium.base.ObserverList; @@ -13,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; /** * Access gate to C++ side enhanced bookmarks functionalities. @@ -25,6 +30,22 @@ private final ObserverList<SearchServiceObserver> mSearchObservers = new ObserverList<SearchServiceObserver>(); + private LruCache<String, Pair<String, Bitmap>> mSalientImageCache; + + /** + * Interface for getting result back from SalientImageForUrl function. + */ + public interface SalientImageCallback { + /** + * Callback method for fetching salient image. + * @param image Salient image. This can be null if the image cannot be found. + * @param imageUrl Url of the image. Note this is not the same as the url of the website + * containing the image. + */ + @CalledByNative("SalientImageCallback") + void onSalientImageReady(Bitmap image, String imageUrl); + } + /** * Interface to provide consumers notifications to changes in clusters */ @@ -46,6 +67,19 @@ void onSearchResultsReturned(); } + public EnhancedBookmarksBridge(Profile profile, int maxCacheSize) { + this(profile); + // Do not initialize LruCache if cache size is set to 0. + if (maxCacheSize != 0) { + mSalientImageCache = new LruCache<String, Pair<String, Bitmap>>(maxCacheSize) { + @Override + protected int sizeOf(String key, Pair<String, Bitmap> urlImage) { + return urlImage.first.length() + urlImage.second.getByteCount(); + } + }; + } + } + public EnhancedBookmarksBridge(Profile profile) { mNativeEnhancedBookmarksBridge = nativeInit(profile); } @@ -54,6 +88,14 @@ assert mNativeEnhancedBookmarksBridge != 0; nativeDestroy(mNativeEnhancedBookmarksBridge); mNativeEnhancedBookmarksBridge = 0; + + if (mSalientImageCache != null) { + for (Map.Entry<String, Pair<String, Bitmap>> entry : + mSalientImageCache.snapshot().entrySet()) { + entry.getValue().second.recycle(); + } + mSalientImageCache.evictAll(); + } } /** @@ -171,6 +213,39 @@ } /** + * Request bookmark salient image for the given URL. Please refer to + * |BookmarkImageService::SalientImageForUrl|. + * @return True if this method is executed synchronously. False if + * {@link SalientImageCallback#onSalientImageReady(Bitmap, String)} is called later + * (asynchronously). + */ + public boolean salientImageForUrl(final String url, final SalientImageCallback callback) { + assert callback != null; + SalientImageCallback callbackWrapper = callback; + + if (mSalientImageCache != null) { + Pair<String, Bitmap> cached = mSalientImageCache.get(url); + if (cached != null) { + callback.onSalientImageReady(cached.second, cached.first); + return true; + } + + callbackWrapper = new SalientImageCallback() { + @Override + public void onSalientImageReady(Bitmap image, String imageUrl) { + if (image != null) { + mSalientImageCache.put(url, new Pair<String, Bitmap>(imageUrl, image)); + } + callback.onSalientImageReady(image, imageUrl); + } + }; + } + + nativeSalientImageForUrl(mNativeEnhancedBookmarksBridge, url, callbackWrapper); + return false; + } + + /** * Get all filters associated with the given bookmark. * * @param bookmark The bookmark to find filters for. @@ -235,4 +310,6 @@ private native BookmarkId nativeAddBookmark(long nativeEnhancedBookmarksBridge, BookmarkId parent, int index, String title, String url); private native void nativeSendSearchRequest(long nativeEnhancedBookmarksBridge, String query); + private static native void nativeSalientImageForUrl(long nativeEnhancedBookmarksBridge, + String url, SalientImageCallback callback); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java index a6f9c7a..87803be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
@@ -1241,12 +1241,17 @@ } /** - * Perform any subclass-specific initialization tasks. + * Perform any class-specific initialization tasks. * @param tabContentManager A {@link TabContentManager} instance or {@code null} if the web * content will be managed/displayed manually. */ protected void internalInit(TabContentManager tabContentManager) { initializeNative(); + + if (AppBannerManager.isEnabled()) { + mAppBannerManager = new AppBannerManager(this); + addObserver(mAppBannerManager); + } } /** @@ -1370,10 +1375,6 @@ } mInfoBarContainer.setContentViewCore(mContentViewCore); - if (AppBannerManager.isEnabled() && mAppBannerManager == null) { - mAppBannerManager = new AppBannerManager(this); - } - if (DomDistillerFeedbackReporter.isEnabled() && mDomDistillerFeedbackReporter == null) { mDomDistillerFeedbackReporter = new DomDistillerFeedbackReporter(this); } @@ -1467,6 +1468,13 @@ mInfoBarContainer = null; } + // Destroy the AppBannerManager after the InfoBarContainer because it monitors for infobar + // removals. + if (mAppBannerManager != null) { + mAppBannerManager.destroy(); + mAppBannerManager = null; + } + mPreviousFullscreenTopControlsOffsetY = Float.NaN; mPreviousFullscreenContentOffsetY = Float.NaN;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java index be5d1dc..db9c507 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java
@@ -4,33 +4,37 @@ package org.chromium.chrome.browser.banners; -import android.app.PendingIntent; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Looper; import android.text.TextUtils; +import org.chromium.base.ApplicationStatus; import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; +import org.chromium.chrome.R; import org.chromium.chrome.browser.EmptyTabObserver; import org.chromium.chrome.browser.Tab; -import org.chromium.chrome.browser.TabObserver; -import org.chromium.content.browser.ContentViewCore; +import org.chromium.chrome.browser.infobar.AppBannerInfoBar; import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.R; +import org.chromium.ui.base.WindowAndroid; /** - * Manages an AppBannerView for a Tab and its ContentView. + * Manages an AppBannerInfoBar for a Tab. * - * The AppBannerManager manages a single AppBannerView, dismissing it when the user navigates to a - * new page or creating a new one when it detects that the current webpage is requesting a banner to - * be built. The actual observation of the WebContents (which triggers the automatic creation and - * removal of banners, among other things) is done by the native-side AppBannerManager. + * The AppBannerManager manages a single AppBannerInfoBar, creating a new one when it detects that + * the current webpage is requesting a banner to be built. The actual observation of the WebContents + * (which triggers the automatic creation and removal of banners, among other things) is done by the + * native-side AppBannerManager. * * This Java-side class owns its native-side counterpart, which is basically used to grab resources * from the network. */ @JNINamespace("banners") -public class AppBannerManager implements AppBannerView.Observer, AppDetailsDelegate.Observer { +public class AppBannerManager extends EmptyTabObserver { private static final String TAG = "AppBannerManager"; /** Retrieves information about a given package. */ @@ -42,14 +46,11 @@ /** Tab that the AppBannerView/AppBannerManager is owned by. */ private final Tab mTab; - /** ContentViewCore that the AppBannerView/AppBannerManager is currently attached to. */ - private ContentViewCore mContentViewCore; + /** Monitors an installation in progress. */ + private InstallerDelegate mInstallTask; - /** Current banner being shown. */ - private AppBannerView mBannerView; - - /** Data about the app being advertised. */ - private AppData mAppData; + /** Monitors for application state changes. */ + private final ApplicationStatus.ApplicationStateListener mListener; /** * Checks if app banners are enabled. @@ -75,49 +76,55 @@ public AppBannerManager(Tab tab) { mNativePointer = nativeInit(); mTab = tab; - mTab.addObserver(createTabObserver()); updatePointers(); + mListener = createApplicationStateListener(); + ApplicationStatus.registerApplicationStateListener(mListener); } - /** - * Creates a TabObserver for monitoring a Tab, used to react to changes in the ContentView - * or to trigger its own destruction. - * @return TabObserver that can be used to monitor a Tab. - */ - private TabObserver createTabObserver() { - return new EmptyTabObserver() { + private ApplicationStatus.ApplicationStateListener createApplicationStateListener() { + return new ApplicationStatus.ApplicationStateListener() { @Override - public void onWebContentsSwapped(Tab tab, boolean didStartLoad, - boolean didFinishLoad) { - updatePointers(); - } - - @Override - public void onContentChanged(Tab tab) { - updatePointers(); - } - - @Override - public void onDestroyed(Tab tab) { - nativeDestroy(mNativePointer); - mContentViewCore = null; - resetState(); + public void onApplicationStateChange(int newState) { + if (!ApplicationStatus.hasVisibleActivities()) return; + nativeUpdateInstallState(mNativePointer); } }; } + @Override + public void onWebContentsSwapped(Tab tab, boolean didStartLoad, + boolean didFinishLoad) { + updatePointers(); + } + + @Override + public void onContentChanged(Tab tab) { + updatePointers(); + } + /** - * Updates which ContentView and WebContents the AppBannerView is monitoring. + * Destroys the native AppBannerManager. + */ + public void destroy() { + if (mInstallTask != null) { + mInstallTask.cancel(); + mInstallTask = null; + } + ApplicationStatus.unregisterApplicationStateListener(mListener); + nativeDestroy(mNativePointer); + } + + /** + * Updates which WebContents the native AppBannerManager is monitoring. */ private void updatePointers() { - if (mContentViewCore != mTab.getContentViewCore()) - mContentViewCore = mTab.getContentViewCore(); nativeReplaceWebContents(mNativePointer, mTab.getWebContents()); } @CalledByNative private int getPreferredIconSize() { - return AppBannerView.getIconSize(mContentViewCore.getContext()); + return ApplicationStatus.getApplicationContext().getResources().getDimensionPixelSize( + R.dimen.app_banner_icon_size); } /** @@ -126,112 +133,108 @@ * @param packageName Name of the package that is being advertised. */ @CalledByNative - private void prepareBanner(String url, String packageName) { - // Get rid of whatever banner is there currently. - if (mBannerView != null) dismissCurrentBanner(AppBannerMetricsIds.DISMISS_ERROR); - - if (sAppDetailsDelegate == null || !isBannerForCurrentPage(url)) return; - + private void fetchAppDetails(String url, String packageName) { + if (sAppDetailsDelegate == null) return; int iconSize = getPreferredIconSize(); - sAppDetailsDelegate.getAppDetailsAsynchronously(this, url, packageName, iconSize); + sAppDetailsDelegate.getAppDetailsAsynchronously( + createAppDetailsObserver(), url, packageName, iconSize); } - /** - * Called when data about the package has been retrieved, which includes the url for the app's - * icon but not the icon Bitmap itself. Kicks off a background task to retrieve it. - * @param data Data about the app. Null if the task failed. - */ - @Override - public void onAppDetailsRetrieved(AppData data) { - if (data == null || !isBannerForCurrentPage(data.siteUrl())) return; + private AppDetailsDelegate.Observer createAppDetailsObserver() { + return new AppDetailsDelegate.Observer() { + /** + * Called when data about the package has been retrieved, which includes the url for the + * app's icon but not the icon Bitmap itself. + * @param data Data about the app. Null if the task failed. + */ + @Override + public void onAppDetailsRetrieved(AppData data) { + if (data == null) return; - mAppData = data; - String imageUrl = data.imageUrl(); - if (TextUtils.isEmpty(imageUrl) || !nativeFetchIcon(mNativePointer, imageUrl)) resetState(); + String imageUrl = data.imageUrl(); + if (TextUtils.isEmpty(imageUrl)) return; + + nativeOnAppDetailsRetrieved( + mNativePointer, data, data.title(), data.packageName(), data.imageUrl()); + } + }; } - /** - * Called when all the data required to show a banner has finally been retrieved. - * Creates the banner and shows it, as long as the banner is still meant for the current page. - * @param imageUrl URL of the icon. - * @param appIcon Bitmap containing the icon itself. - * @return Whether or not the banner was created. - */ @CalledByNative - private boolean createBanner(String imageUrl, Bitmap appIcon) { - if (mAppData == null || !isBannerForCurrentPage(mAppData.siteUrl())) return false; + private boolean installOrOpenNativeApp(AppData appData) { + Context context = ApplicationStatus.getApplicationContext(); + String packageName = appData.packageName(); + PackageManager packageManager = context.getPackageManager(); - if (!TextUtils.equals(mAppData.imageUrl(), imageUrl)) { - resetState(); - return false; + if (InstallerDelegate.isInstalled(packageManager, packageName)) { + // Open the app. + Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName); + if (launchIntent == null) return true; + context.startActivity(launchIntent); + return true; + } else { + // Try installing the app. If the installation was kicked off, return false to prevent + // the infobar from disappearing. + return !mTab.getWindowAndroid().showIntent( + appData.installIntent(), createIntentCallback(appData), + R.string.low_memory_error); } - - mAppData.setIcon(new BitmapDrawable(mContentViewCore.getContext().getResources(), appIcon)); - mBannerView = AppBannerView.create(mContentViewCore, this, mAppData); - return true; } - /** - * Dismisses whatever banner is currently being displayed. This is treated as an automatic - * dismissal and not one that blocks the banner from appearing in the future. - * @param dismissalType What triggered the dismissal. - */ + private WindowAndroid.IntentCallback createIntentCallback(final AppData appData) { + return new WindowAndroid.IntentCallback() { + @Override + public void onIntentCompleted(WindowAndroid window, int resultCode, + ContentResolver contentResolver, Intent data) { + boolean isInstalling = resultCode == Activity.RESULT_OK; + if (isInstalling) { + // Start monitoring the install. + PackageManager pm = + ApplicationStatus.getApplicationContext().getPackageManager(); + mInstallTask = new InstallerDelegate( + Looper.getMainLooper(), pm, createInstallerDelegateObserver(), + appData.packageName()); + mInstallTask.start(); + } + + nativeOnInstallIntentReturned(mNativePointer, isInstalling); + } + }; + } + + private InstallerDelegate.Observer createInstallerDelegateObserver() { + return new InstallerDelegate.Observer() { + @Override + public void onInstallFinished(InstallerDelegate task, boolean success) { + if (mInstallTask != task) return; + mInstallTask = null; + nativeOnInstallFinished(mNativePointer, success); + } + }; + } + @CalledByNative - private void dismissCurrentBanner(int dismissalType) { - if (mBannerView != null) mBannerView.dismiss(dismissalType); - resetState(); + private void showAppDetails(AppData appData) { + WindowAndroid.IntentCallback emptyCallback = new WindowAndroid.IntentCallback() { + @Override + public void onIntentCompleted(WindowAndroid window, int resultCode, + ContentResolver contentResolver, Intent data) { + // Do nothing. + } + }; + + mTab.getWindowAndroid().showIntent( + appData.detailsIntent(), emptyCallback, R.string.low_memory_error); } - @Override - public void onBannerRemoved(AppBannerView banner) { - if (mBannerView != banner) return; - resetState(); - } + @CalledByNative + private int determineInstallState(AppData data) { + if (mInstallTask != null) return AppBannerInfoBar.INSTALL_STATE_INSTALLING; - @Override - public void onBannerBlocked(AppBannerView banner, String url, String packageName) { - if (mBannerView != banner) return; - nativeBlockBanner(mNativePointer, url, packageName); - } - - @Override - public void onBannerDismissEvent(AppBannerView banner, int eventType) { - if (mBannerView != banner) return; - nativeRecordDismissEvent(eventType); - } - - @Override - public void onBannerInstallEvent(AppBannerView banner, int eventType) { - if (mBannerView != banner) return; - nativeRecordInstallEvent(eventType); - } - - @Override - public boolean onFireIntent(AppBannerView banner, PendingIntent intent) { - if (mBannerView != banner) return false; - return mTab.getWindowAndroid().showIntent(intent, banner, R.string.low_memory_error); - } - - /** - * Resets all of the state, killing off any running tasks. - */ - private void resetState() { - if (mBannerView != null) { - mBannerView.destroy(); - mBannerView = null; - } - - mAppData = null; - } - - /** - * Checks to see if the banner is for the currently displayed page. - * @param bannerUrl URL that requested a banner. - * @return True if the user is still on the same page. - */ - private boolean isBannerForCurrentPage(String bannerUrl) { - return mContentViewCore != null - && TextUtils.equals(mContentViewCore.getWebContents().getUrl(), bannerUrl); + PackageManager pm = ApplicationStatus.getApplicationContext().getPackageManager(); + boolean isInstalled = InstallerDelegate.isInstalled(pm, data.packageName()); + return isInstalled ? AppBannerInfoBar.INSTALL_STATE_INSTALLED + : AppBannerInfoBar.INSTALL_STATE_NOT_INSTALLED; } private static native boolean nativeIsEnabled(); @@ -239,9 +242,12 @@ private native void nativeDestroy(long nativeAppBannerManager); private native void nativeReplaceWebContents(long nativeAppBannerManager, WebContents webContents); - private native void nativeBlockBanner( - long nativeAppBannerManager, String url, String packageName); - private native boolean nativeFetchIcon(long nativeAppBannerManager, String imageUrl); + private native boolean nativeOnAppDetailsRetrieved(long nativeAppBannerManager, AppData data, + String title, String packageName, String imageUrl); + private native void nativeOnInstallIntentReturned( + long nativeAppBannerManager, boolean isInstalling); + private native void nativeOnInstallFinished(long nativeAppBannerManager, boolean success); + private native void nativeUpdateInstallState(long nativeAppBannerManager); // UMA tracking. private static native void nativeRecordDismissEvent(int metric);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerView.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerView.java deleted file mode 100644 index 564e70a..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerView.java +++ /dev/null
@@ -1,864 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.banners; - -import android.animation.ObjectAnimator; -import android.app.Activity; -import android.app.PendingIntent; -import android.content.ActivityNotFoundException; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentSender; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Rect; -import android.os.Looper; -import android.util.AttributeSet; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; -import org.chromium.content.browser.ContentViewCore; -import org.chromium.ui.base.LocalizationUtils; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.ui.base.WindowAndroid.IntentCallback; - -/** - * Lays out a banner for showing info about an app on the Play Store. - * The banner mimics the appearance of a Google Now card using a background Drawable with a shadow. - * - * PADDING CALCULATIONS - * The banner has three different types of padding that need to be accounted for: - * 1) The background Drawable of the banner looks like card with a drop shadow. The Drawable - * defines a padding around the card that solely encompasses the space occupied by the drop - * shadow. - * 2) The card itself needs to have padding so that the widgets don't abut the borders of the card. - * This is defined as mPaddingCard, and is equally applied to all four sides. - * 3) Controls other than the icon are further constrained by mPaddingControls, which applies only - * to the bottom and end margins. - * See {@link #AppBannerView.onMeasure(int, int)} for details. - * - * MARGIN CALCULATIONS - * Margin calculations for the banner are complicated by the background Drawable's drop shadows, - * since the drop shadows are meant to be counted as being part of the margin. To deal with this, - * the margins are calculated by deducting the background Drawable's padding from the margins - * defined by the XML files. - * - * EVEN MORE LAYOUT QUIRKS - * The layout of the banner, which includes its widget sizes, may change when the screen is rotated - * to account for less screen real estate. This means that all of the View's widgets and cached - * dimensions must be rebuilt from scratch. - */ -public class AppBannerView extends SwipableOverlayView - implements View.OnClickListener, InstallerDelegate.Observer, IntentCallback { - private static final String TAG = "AppBannerView"; - - /** - * Class that is alerted about things happening to the BannerView. - */ - public static interface Observer { - /** - * Called when the banner is removed from the hierarchy. - * @param banner Banner being dismissed. - */ - public void onBannerRemoved(AppBannerView banner); - - /** - * Called when the user manually closes a banner. - * @param banner Banner being blocked. - * @param url URL of the page that requested the banner. - * @param packageName Name of the app's package. - */ - public void onBannerBlocked(AppBannerView banner, String url, String packageName); - - /** - * Called when the banner begins to be dismissed. - * @param banner Banner being closed. - * @param dismissType Type of dismissal performed. - */ - public void onBannerDismissEvent(AppBannerView banner, int dismissType); - - /** - * Called when an install event has occurred. - */ - public void onBannerInstallEvent(AppBannerView banner, int eventType); - - /** - * Called when the banner needs to have an Activity started for a result. - * @param banner Banner firing the event. - * @param intent Intent to fire. - */ - public boolean onFireIntent(AppBannerView banner, PendingIntent intent); - } - - // Installation states. - private static final int INSTALL_STATE_NOT_INSTALLED = 0; - private static final int INSTALL_STATE_INSTALLING = 1; - private static final int INSTALL_STATE_INSTALLED = 2; - - // XML layout for the BannerView. - private static final int BANNER_LAYOUT = R.layout.app_banner_view; - - // True if the layout is in left-to-right layout mode (regular mode). - private final boolean mIsLayoutLTR; - - // Class to alert about BannerView events. - private AppBannerView.Observer mObserver; - - // Information about the package. Shouldn't ever be null after calling {@link #initialize()}. - private AppData mAppData; - - // Views comprising the app banner. - private ViewGroup mContainerView; - private ImageView mIconView; - private TextView mTitleView; - private Button mInstallButtonView; - private RatingView mRatingView; - private View mLogoView; - private View mBannerHighlightView; - private ImageButton mCloseButtonView; - - // Dimension values. - private int mDefinedMaxWidth; - private int mPaddingCard; - private int mPaddingControls; - private int mMarginLeft; - private int mMarginRight; - private int mMarginBottom; - private int mTouchSlop; - - // Highlight variables. - private boolean mIsBannerPressed; - private float mInitialXForHighlight; - - // Initial padding values. - private final Rect mBackgroundDrawablePadding; - - // Install tracking. - private boolean mWasInstallDialogShown; - private InstallerDelegate mInstallTask; - private int mInstallState; - - /** - * Creates a BannerView and adds it to the given ContentViewCore. - * @param contentViewCore ContentViewCore to display the AppBannerView for. - * @param observer Class that is alerted for AppBannerView events. - * @param data Data about the app. - * @return The created banner. - */ - public static AppBannerView create( - ContentViewCore contentViewCore, Observer observer, AppData data) { - Context context = contentViewCore.getContext().getApplicationContext(); - AppBannerView banner = - (AppBannerView) LayoutInflater.from(context).inflate(BANNER_LAYOUT, null); - banner.initialize(observer, data); - banner.setContentViewCore(contentViewCore); - banner.addToParentView(contentViewCore.getContainerView()); - return banner; - } - - /** - * Creates a BannerView from an XML layout. - */ - public AppBannerView(Context context, AttributeSet attrs) { - super(context, attrs); - mIsLayoutLTR = !LocalizationUtils.isLayoutRtl(); - - // Store the background Drawable's padding. The background used for banners is a 9-patch, - // which means that it already defines padding. We need to take it into account when adding - // even more padding to the inside of it. - mBackgroundDrawablePadding = new Rect(); - mBackgroundDrawablePadding.left = ApiCompatibilityUtils.getPaddingStart(this); - mBackgroundDrawablePadding.right = ApiCompatibilityUtils.getPaddingEnd(this); - mBackgroundDrawablePadding.top = getPaddingTop(); - mBackgroundDrawablePadding.bottom = getPaddingBottom(); - - mInstallState = INSTALL_STATE_NOT_INSTALLED; - } - - /** - * Initialize the banner with information about the package. - * @param observer Class to alert about changes to the banner. - * @param data Information about the app being advertised. - */ - private void initialize(Observer observer, AppData data) { - mObserver = observer; - mAppData = data; - initializeControls(); - } - - private void initializeControls() { - // Cache the banner dimensions, adjusting margins for drop shadows defined in the background - // Drawable. - Resources res = getResources(); - mDefinedMaxWidth = res.getDimensionPixelSize(R.dimen.app_banner_max_width); - mPaddingCard = res.getDimensionPixelSize(R.dimen.app_banner_padding); - mPaddingControls = res.getDimensionPixelSize(R.dimen.app_banner_padding_controls); - mMarginLeft = res.getDimensionPixelSize(R.dimen.app_banner_margin_sides) - - mBackgroundDrawablePadding.left; - mMarginRight = res.getDimensionPixelSize(R.dimen.app_banner_margin_sides) - - mBackgroundDrawablePadding.right; - mMarginBottom = res.getDimensionPixelSize(R.dimen.app_banner_margin_bottom) - - mBackgroundDrawablePadding.bottom; - if (getLayoutParams() != null) { - MarginLayoutParams params = (MarginLayoutParams) getLayoutParams(); - params.leftMargin = mMarginLeft; - params.rightMargin = mMarginRight; - params.bottomMargin = mMarginBottom; - } - - // Pull out all of the controls we are expecting. - mContainerView = (ViewGroup) findViewById(R.id.banner_container); - mIconView = (ImageView) findViewById(R.id.app_icon); - mTitleView = (TextView) findViewById(R.id.app_title); - mInstallButtonView = (Button) findViewById(R.id.app_install_button); - mRatingView = (RatingView) findViewById(R.id.app_rating); - mLogoView = findViewById(R.id.store_logo); - mBannerHighlightView = findViewById(R.id.banner_highlight); - mCloseButtonView = (ImageButton) findViewById(R.id.close_button); - - assert mIconView != null; - assert mTitleView != null; - assert mInstallButtonView != null; - assert mLogoView != null; - assert mRatingView != null; - assert mBannerHighlightView != null; - assert mCloseButtonView != null; - - // Set up the buttons to fire an event. - mInstallButtonView.setOnClickListener(this); - mCloseButtonView.setOnClickListener(this); - - // Configure the controls with the package information. - mTitleView.setText(mAppData.title()); - mIconView.setImageDrawable(mAppData.icon()); - mRatingView.initialize(mAppData.rating()); - setAccessibilityInformation(); - - // Determine how much the user can drag sideways before their touch is considered a scroll. - mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); - - // Set up the install button. - updateButtonStatus(); - } - - /** - * Creates a succinct description about the app being advertised. - */ - private void setAccessibilityInformation() { - String bannerText = getContext().getString( - R.string.app_banner_view_accessibility, mAppData.title(), mAppData.rating()); - setContentDescription(bannerText); - } - - @Override - public void onClick(View view) { - if (mObserver == null) return; - - // Only allow the button to be clicked when the banner's in a neutral position. - if (Math.abs(getTranslationX()) > ZERO_THRESHOLD - || Math.abs(getTranslationY()) > ZERO_THRESHOLD) { - return; - } - - if (view == mInstallButtonView) { - // Check that nothing happened in the background to change the install state of the app. - int previousState = mInstallState; - updateButtonStatus(); - if (mInstallState != previousState) return; - - // Ignore button clicks when the app is installing. - if (mInstallState == INSTALL_STATE_INSTALLING) return; - - mInstallButtonView.setEnabled(false); - - if (mInstallState == INSTALL_STATE_NOT_INSTALLED) { - // The user initiated an install. Track it happening only once. - if (!mWasInstallDialogShown) { - mObserver.onBannerInstallEvent(this, AppBannerMetricsIds.INSTALL_TRIGGERED); - mWasInstallDialogShown = true; - } - - if (mObserver.onFireIntent(this, mAppData.installIntent())) { - // Temporarily hide the banner. - createVerticalSnapAnimation(false); - } else { - Log.e(TAG, "Failed to fire install intent."); - dismiss(AppBannerMetricsIds.DISMISS_ERROR); - } - } else if (mInstallState == INSTALL_STATE_INSTALLED) { - // The app is installed. Open it. - try { - Intent appIntent = getAppLaunchIntent(); - if (appIntent != null) getContext().startActivity(appIntent); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Failed to find app package: " + mAppData.packageName()); - } - - dismiss(AppBannerMetricsIds.DISMISS_APP_OPEN); - } - } else if (view == mCloseButtonView) { - if (mObserver != null) { - mObserver.onBannerBlocked(this, mAppData.siteUrl(), mAppData.packageName()); - } - - dismiss(AppBannerMetricsIds.DISMISS_CLOSE_BUTTON); - } - } - - @Override - protected void onViewSwipedAway() { - if (mObserver == null) return; - mObserver.onBannerDismissEvent(this, AppBannerMetricsIds.DISMISS_BANNER_SWIPE); - mObserver.onBannerBlocked(this, mAppData.siteUrl(), mAppData.packageName()); - } - - @Override - protected void onViewClicked() { - // Send the user to the app's Play store page. - try { - IntentSender sender = mAppData.detailsIntent().getIntentSender(); - getContext().startIntentSender(sender, new Intent(), 0, 0, 0); - } catch (IntentSender.SendIntentException e) { - Log.e(TAG, "Failed to launch details intent."); - } - - dismiss(AppBannerMetricsIds.DISMISS_BANNER_CLICK); - } - - @Override - protected void onViewPressed(MotionEvent event) { - // Highlight the banner when the user has held it for long enough and doesn't move. - mInitialXForHighlight = event.getRawX(); - mIsBannerPressed = true; - mBannerHighlightView.setVisibility(View.VISIBLE); - } - - @Override - public void onIntentCompleted(WindowAndroid window, int resultCode, - ContentResolver contentResolver, Intent data) { - if (isDismissed()) return; - - createVerticalSnapAnimation(true); - if (resultCode == Activity.RESULT_OK) { - // The user chose to install the app. Watch the PackageManager to see when it finishes - // installing it. - mObserver.onBannerInstallEvent(this, AppBannerMetricsIds.INSTALL_STARTED); - - PackageManager pm = getContext().getPackageManager(); - mInstallTask = - new InstallerDelegate(Looper.getMainLooper(), pm, this, mAppData.packageName()); - mInstallTask.start(); - mInstallState = INSTALL_STATE_INSTALLING; - } - updateButtonStatus(); - } - - - @Override - public void onInstallFinished(InstallerDelegate monitor, boolean success) { - if (isDismissed() || mInstallTask != monitor) return; - - if (success) { - // Let the user open the app from here. - mObserver.onBannerInstallEvent(this, AppBannerMetricsIds.INSTALL_COMPLETED); - mInstallState = INSTALL_STATE_INSTALLED; - updateButtonStatus(); - } else { - dismiss(AppBannerMetricsIds.DISMISS_INSTALL_TIMEOUT); - } - } - - @Override - public ViewGroup.MarginLayoutParams createLayoutParams() { - // Define the margin around the entire banner that accounts for the drop shadow. - ViewGroup.MarginLayoutParams params = super.createLayoutParams(); - params.setMargins(mMarginLeft, 0, mMarginRight, mMarginBottom); - return params; - } - - /** - * Removes this View from its parent and alerts any observers of the dismissal. - * @return Whether or not the View was successfully dismissed. - */ - @Override - public boolean removeFromParentView() { - if (super.removeFromParentView()) { - mObserver.onBannerRemoved(this); - destroy(); - return true; - } - - return false; - } - - /** - * Dismisses the banner. - * @param eventType Event that triggered the dismissal. See {@link AppBannerMetricsIds}. - */ - public void dismiss(int eventType) { - if (isDismissed() || mObserver == null) return; - - dismiss(eventType == AppBannerMetricsIds.DISMISS_CLOSE_BUTTON); - mObserver.onBannerDismissEvent(this, eventType); - } - - /** - * Destroys the Banner. - */ - public void destroy() { - if (!isDismissed()) dismiss(AppBannerMetricsIds.DISMISS_ERROR); - - if (mInstallTask != null) { - mInstallTask.cancel(); - mInstallTask = null; - } - } - - /** - * Updates the install button (install state, text, color, etc.). - */ - void updateButtonStatus() { - if (mInstallButtonView == null) return; - - // Determine if the saved install status of the app is out of date. - // It is not easily possible to detect if an app is in the process of being installed, so we - // can't properly transition to that state from here. - if (getAppLaunchIntent() == null) { - if (mInstallState == INSTALL_STATE_INSTALLED) { - mInstallState = INSTALL_STATE_NOT_INSTALLED; - } - } else { - mInstallState = INSTALL_STATE_INSTALLED; - } - - // Update what the button looks like. - Resources res = getResources(); - int fgColor; - String text; - if (mInstallState == INSTALL_STATE_INSTALLED) { - ApiCompatibilityUtils.setBackgroundForView(mInstallButtonView, - res.getDrawable(R.drawable.app_banner_button_open)); - fgColor = res.getColor(R.color.app_banner_open_button_fg); - text = res.getString(R.string.app_banner_open); - } else { - ApiCompatibilityUtils.setBackgroundForView(mInstallButtonView, - res.getDrawable(R.drawable.app_banner_button_install)); - fgColor = res.getColor(R.color.app_banner_install_button_fg); - if (mInstallState == INSTALL_STATE_NOT_INSTALLED) { - text = mAppData.installButtonText(); - mInstallButtonView.setContentDescription( - getContext().getString(R.string.app_banner_install_accessibility, text)); - } else { - text = res.getString(R.string.app_banner_installing); - } - } - - mInstallButtonView.setTextColor(fgColor); - mInstallButtonView.setText(text); - mInstallButtonView.setEnabled(mInstallState != INSTALL_STATE_INSTALLING); - } - - /** - * Determine how big an icon needs to be for the Layout. - * @param context Context to grab resources from. - * @return How big the icon is expected to be, in pixels. - */ - static int getIconSize(Context context) { - return context.getResources().getDimensionPixelSize(R.dimen.app_banner_icon_size); - } - - /** - * Passes all touch events through to the parent. - */ - @Override - public boolean onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - if (mIsBannerPressed) { - // Mimic Google Now card behavior, where the card stops being highlighted if the user - // scrolls a bit to the side. - float xDifference = Math.abs(event.getRawX() - mInitialXForHighlight); - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL - || (action == MotionEvent.ACTION_MOVE && xDifference > mTouchSlop)) { - mIsBannerPressed = false; - mBannerHighlightView.setVisibility(View.INVISIBLE); - } - } - - return super.onTouchEvent(event); - } - - /** - * Fade the banner back into view. - */ - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - ObjectAnimator.ofFloat(this, "alpha", getAlpha(), 1.f).setDuration( - MS_ANIMATION_DURATION).start(); - setVisibility(VISIBLE); - } - - /** - * Immediately hide the banner to avoid having them show up in snapshots. - */ - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - setAlpha(0.0f); - setVisibility(INVISIBLE); - } - - /** - * Watch for changes in the available screen height, which triggers a complete recreation of the - * banner widgets. This is mainly due to the fact that the Nexus 7 has a smaller banner defined - * for its landscape versus its portrait layouts. - */ - @Override - protected void onConfigurationChanged(Configuration config) { - super.onConfigurationChanged(config); - - if (isDismissed()) return; - - // If the card's maximum width hasn't changed, the individual views can't have, either. - int newDefinedWidth = getResources().getDimensionPixelSize(R.dimen.app_banner_max_width); - if (mDefinedMaxWidth == newDefinedWidth) return; - - // Cannibalize another version of this layout to get Views using the new resources and - // sizes. - while (getChildCount() > 0) removeViewAt(0); - mIconView = null; - mTitleView = null; - mInstallButtonView = null; - mRatingView = null; - mLogoView = null; - mBannerHighlightView = null; - - AppBannerView cannibalized = - (AppBannerView) LayoutInflater.from(getContext()).inflate(BANNER_LAYOUT, null); - while (cannibalized.getChildCount() > 0) { - View child = cannibalized.getChildAt(0); - cannibalized.removeViewAt(0); - addView(child); - } - initializeControls(); - requestLayout(); - } - - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - if (hasWindowFocus) updateButtonStatus(); - } - - /** - * @return Intent to launch the app that is being promoted. - */ - private Intent getAppLaunchIntent() { - String packageName = mAppData.packageName(); - PackageManager packageManager = getContext().getPackageManager(); - return packageManager.getLaunchIntentForPackage(packageName); - } - - /** - * Measures the banner and its children Views for the given space. - * - * DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD - * DPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPD - * DP...... cPD - * DP...... TITLE----------------------- XcPD - * DP.ICON. ***** cPD - * DP...... LOGO BUTTONcPD - * DP...... cccccccccccccccccccccccccccccccPD - * DPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPD - * DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD - * - * The three paddings mentioned in the class Javadoc are denoted by: - * D) Drop shadow padding. - * P) Inner card padding. - * c) Control padding. - * - * Measurement for components of the banner are performed assuming that components are laid out - * inside of the banner's background as follows: - * 1) A maximum width is enforced on the banner to keep the whole thing on screen and keep it a - * reasonable size. - * 2) The icon takes up the left side of the banner. - * 3) The install button occupies the bottom-right of the banner. - * 4) The Google Play logo occupies the space to the left of the button. - * 5) The rating is assigned space above the logo and below the title. - * 6) The close button (if visible) sits in the top right of the banner. - * 7) The title is assigned whatever space is left and sits on top of the tallest stack of - * controls. - * - * See {@link #android.view.View.onMeasure(int, int)} for the parameters. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Enforce a maximum width on the banner, which is defined as the smallest of: - // 1) The smallest width for the device (in either landscape or portrait mode). - // 2) The defined maximum width in the dimens.xml files. - // 3) The width passed in through the MeasureSpec. - Resources res = getResources(); - float density = res.getDisplayMetrics().density; - int screenSmallestWidth = (int) (res.getConfiguration().smallestScreenWidthDp * density); - int specWidth = MeasureSpec.getSize(widthMeasureSpec); - int bannerWidth = Math.min(Math.min(specWidth, mDefinedMaxWidth), screenSmallestWidth); - - // Track how much space is available inside the banner's card-shaped background Drawable. - // To calculate this, we need to account for both the padding of the background (which - // is occupied by the card's drop shadows) as well as the padding defined on the inside of - // the card. - int bgPaddingWidth = mBackgroundDrawablePadding.left + mBackgroundDrawablePadding.right; - int bgPaddingHeight = mBackgroundDrawablePadding.top + mBackgroundDrawablePadding.bottom; - final int maxControlWidth = bannerWidth - bgPaddingWidth - (mPaddingCard * 2); - - // Control height is constrained to provide a reasonable aspect ratio. - // In practice, the only controls which can cause an issue are the title and the install - // button, since they have strings that can change size according to user preference. The - // other controls are all defined to be a certain height. - int specHeight = MeasureSpec.getSize(heightMeasureSpec); - int reasonableHeight = maxControlWidth / 4; - int paddingHeight = bgPaddingHeight + (mPaddingCard * 2); - final int maxControlHeight = Math.min(specHeight, reasonableHeight) - paddingHeight; - final int maxStackedControlHeight = maxControlWidth / 3; - - // Determine how big each component wants to be. The icon is measured separately because - // it is not stacked with the other controls. - measureChildForSpace(mIconView, maxControlWidth, maxControlHeight); - for (int i = 0; i < mContainerView.getChildCount(); i++) { - View child = mContainerView.getChildAt(i); - if (child != mIconView) { - measureChildForSpace(child, maxControlWidth, maxStackedControlHeight); - } - } - - // Determine how tall the banner needs to be to fit everything by calculating the combined - // height of the stacked controls. There are three competing stacks to measure: - // 1) The icon. - // 2) The app title + control padding + star rating + store logo. - // 3) The app title + control padding + install button. - // The control padding is extra padding that applies only to the non-icon widgets. - // The close button does not get counted as part of a stack. - int iconStackHeight = getHeightWithMargins(mIconView); - int logoStackHeight = getHeightWithMargins(mTitleView) + mPaddingControls - + getHeightWithMargins(mRatingView) + getHeightWithMargins(mLogoView); - int buttonStackHeight = getHeightWithMargins(mTitleView) + mPaddingControls - + getHeightWithMargins(mInstallButtonView); - int biggestStackHeight = - Math.max(iconStackHeight, Math.max(logoStackHeight, buttonStackHeight)); - - // The icon hugs the banner's starting edge, from the top of the banner to the bottom. - final int iconSize = biggestStackHeight; - measureChildForSpaceExactly(mIconView, iconSize, iconSize); - - // The rest of the content is laid out to the right of the icon. - // Additional padding is defined for non-icon content on the end and bottom. - final int contentWidth = - maxControlWidth - getWidthWithMargins(mIconView) - mPaddingControls; - final int contentHeight = biggestStackHeight - mPaddingControls; - measureChildForSpace(mLogoView, contentWidth, contentHeight); - - // Restrict the button size to prevent overrunning the Google Play logo. - int remainingButtonWidth = - maxControlWidth - getWidthWithMargins(mLogoView) - getWidthWithMargins(mIconView); - mInstallButtonView.setMaxWidth(remainingButtonWidth); - measureChildForSpace(mInstallButtonView, contentWidth, contentHeight); - - // Measure the star rating, which sits below the title and above the logo. - final int ratingWidth = contentWidth; - final int ratingHeight = contentHeight - getHeightWithMargins(mLogoView); - measureChildForSpace(mRatingView, ratingWidth, ratingHeight); - - // The close button sits to the right of the title and above the install button. - final int closeWidth = contentWidth; - final int closeHeight = contentHeight - getHeightWithMargins(mInstallButtonView); - measureChildForSpace(mCloseButtonView, closeWidth, closeHeight); - - // The app title spans the top of the banner and sits on top of the other controls, and to - // the left of the close button. The computation for the width available to the title is - // complicated by how the button sits in the corner and absorbs the padding that would - // normally be there. - int biggerStack = Math.max(getHeightWithMargins(mInstallButtonView), - getHeightWithMargins(mLogoView) + getHeightWithMargins(mRatingView)); - final int titleWidth = contentWidth - getWidthWithMargins(mCloseButtonView) + mPaddingCard; - final int titleHeight = contentHeight - biggerStack; - measureChildForSpace(mTitleView, titleWidth, titleHeight); - - // Set the measured dimensions for the banner. The banner's height is defined by the - // tallest stack of components, the padding of the banner's card background, and the extra - // padding around the banner's components. - int bannerPadding = mBackgroundDrawablePadding.top + mBackgroundDrawablePadding.bottom - + (mPaddingCard * 2); - int bannerHeight = biggestStackHeight + bannerPadding; - setMeasuredDimension(bannerWidth, bannerHeight); - measureChildForSpaceExactly(mContainerView, bannerWidth, bannerHeight); - - // Make the banner highlight view be the exact same size as the banner's card background. - final int cardWidth = bannerWidth - bgPaddingWidth; - final int cardHeight = bannerHeight - bgPaddingHeight; - measureChildForSpaceExactly(mBannerHighlightView, cardWidth, cardHeight); - } - - /** - * Lays out the controls according to the algorithm in {@link #onMeasure}. - * See {@link #android.view.View.onLayout(boolean, int, int, int, int)} for the parameters. - */ - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - mContainerView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); - - int top = mBackgroundDrawablePadding.top; - int bottom = getMeasuredHeight() - mBackgroundDrawablePadding.bottom; - int start = mBackgroundDrawablePadding.left; - int end = getMeasuredWidth() - mBackgroundDrawablePadding.right; - - // The highlight overlay covers the entire banner (minus drop shadow padding). - mBannerHighlightView.layout(start, top, end, bottom); - - // Lay out the close button in the top-right corner. Padding that would normally go to the - // card is applied to the close button so that it has a bigger touch target. - if (mCloseButtonView.getVisibility() == VISIBLE) { - int closeWidth = mCloseButtonView.getMeasuredWidth(); - int closeTop = - top + ((MarginLayoutParams) mCloseButtonView.getLayoutParams()).topMargin; - int closeBottom = closeTop + mCloseButtonView.getMeasuredHeight(); - int closeRight = mIsLayoutLTR ? end : (getMeasuredWidth() - end + closeWidth); - int closeLeft = closeRight - closeWidth; - mCloseButtonView.layout(closeLeft, closeTop, closeRight, closeBottom); - } - - // Apply the padding for the rest of the widgets. - top += mPaddingCard; - bottom -= mPaddingCard; - start += mPaddingCard; - end -= mPaddingCard; - - // Lay out the icon. - int iconWidth = mIconView.getMeasuredWidth(); - int iconLeft = mIsLayoutLTR ? start : (getMeasuredWidth() - start - iconWidth); - mIconView.layout(iconLeft, top, iconLeft + iconWidth, top + mIconView.getMeasuredHeight()); - start += getWidthWithMargins(mIconView); - - // Factor in the additional padding, which is only tacked onto the end and bottom. - end -= mPaddingControls; - bottom -= mPaddingControls; - - // Lay out the app title text. - int titleWidth = mTitleView.getMeasuredWidth(); - int titleTop = top + ((MarginLayoutParams) mTitleView.getLayoutParams()).topMargin; - int titleBottom = titleTop + mTitleView.getMeasuredHeight(); - int titleLeft = mIsLayoutLTR ? start : (getMeasuredWidth() - start - titleWidth); - mTitleView.layout(titleLeft, titleTop, titleLeft + titleWidth, titleBottom); - - // The mock shows the margin eating into the descender area of the TextView. - int textBaseline = mTitleView.getLineBounds(mTitleView.getLineCount() - 1, null); - top = titleTop + textBaseline - + ((MarginLayoutParams) mTitleView.getLayoutParams()).bottomMargin; - - // Lay out the app rating below the title. - int starWidth = mRatingView.getMeasuredWidth(); - int starTop = top + ((MarginLayoutParams) mRatingView.getLayoutParams()).topMargin; - int starBottom = starTop + mRatingView.getMeasuredHeight(); - int starLeft = mIsLayoutLTR ? start : (getMeasuredWidth() - start - starWidth); - mRatingView.layout(starLeft, starTop, starLeft + starWidth, starBottom); - - // Lay out the logo in the bottom-left. - int logoWidth = mLogoView.getMeasuredWidth(); - int logoBottom = bottom - ((MarginLayoutParams) mLogoView.getLayoutParams()).bottomMargin; - int logoTop = logoBottom - mLogoView.getMeasuredHeight(); - int logoLeft = mIsLayoutLTR ? start : (getMeasuredWidth() - start - logoWidth); - mLogoView.layout(logoLeft, logoTop, logoLeft + logoWidth, logoBottom); - - // Lay out the install button in the bottom-right corner. - int buttonHeight = mInstallButtonView.getMeasuredHeight(); - int buttonWidth = mInstallButtonView.getMeasuredWidth(); - int buttonRight = mIsLayoutLTR ? end : (getMeasuredWidth() - end + buttonWidth); - int buttonLeft = buttonRight - buttonWidth; - mInstallButtonView.layout(buttonLeft, bottom - buttonHeight, buttonRight, bottom); - } - - /** - * Measures a child for the given space, accounting for defined heights and margins. - * @param child View to measure. - * @param availableWidth Available width for the view. - * @param availableHeight Available height for the view. - */ - private void measureChildForSpace(View child, int availableWidth, int availableHeight) { - // Handle margins. - availableWidth -= getMarginWidth(child); - availableHeight -= getMarginHeight(child); - - // Account for any layout-defined dimensions for the view. - int childWidth = child.getLayoutParams().width; - int childHeight = child.getLayoutParams().height; - if (childWidth >= 0) availableWidth = Math.min(availableWidth, childWidth); - if (childHeight >= 0) availableHeight = Math.min(availableHeight, childHeight); - - int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); - int heightSpec = MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST); - child.measure(widthSpec, heightSpec); - } - - /** - * Forces a child to exactly occupy the given space. - * @param child View to measure. - * @param availableWidth Available width for the view. - * @param availableHeight Available height for the view. - */ - private void measureChildForSpaceExactly(View child, int availableWidth, int availableHeight) { - int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY); - int heightSpec = MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.EXACTLY); - child.measure(widthSpec, heightSpec); - } - - /** - * Calculates how wide the margins are for the given View. - * @param view View to measure. - * @return Measured width of the margins. - */ - private static int getMarginWidth(View view) { - MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - return params.leftMargin + params.rightMargin; - } - - /** - * Calculates how wide the given View has been measured to be, including its margins. - * @param view View to measure. - * @return Measured width of the view plus its margins. - */ - private static int getWidthWithMargins(View view) { - return view.getMeasuredWidth() + getMarginWidth(view); - } - - /** - * Calculates how tall the margins are for the given View. - * @param view View to measure. - * @return Measured height of the margins. - */ - private static int getMarginHeight(View view) { - MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - return params.topMargin + params.bottomMargin; - } - - /** - * Calculates how tall the given View has been measured to be, including its margins. - * @param view View to measure. - * @return Measured height of the view plus its margins. - */ - private static int getHeightWithMargins(View view) { - return view.getMeasuredHeight() + getMarginHeight(view); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java index 2da22f50..5960a06 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppData.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.banners; import android.app.PendingIntent; -import android.graphics.drawable.Drawable; /** * Stores information about a particular app. @@ -23,9 +22,6 @@ private PendingIntent mDetailsIntent; private PendingIntent mInstallIntent; - // Data that can be updated asynchronously. - private Drawable mIcon; - /** * Creates a new AppData for the given page and package. * @param siteUrl URL for the site requesting the banner. @@ -56,7 +52,7 @@ * Returns the title to display for the app in the banner. * @return The String to display. */ - String title() { + public String title() { return mTitle; } @@ -69,18 +65,10 @@ } /** - * Returns the Drawable depicting the app's icon. - * @return The Drawable to use as the app icon. - */ - Drawable icon() { - return mIcon; - } - - /** * Returns how well the app was rated, on a scale from 0 to 5. * @return The rating of the app. */ - float rating() { + public float rating() { return mRating; } @@ -88,7 +76,7 @@ * Returns text to display on the install button when the app is not installed on the system. * @return The String to display. */ - String installButtonText() { + public String installButtonText() { return mInstallButtonText; } @@ -97,7 +85,7 @@ * The IntentSender stored inside dictates what package needs to be launched. * @return Intent that triggers the details page. */ - PendingIntent detailsIntent() { + public PendingIntent detailsIntent() { return mDetailsIntent; } @@ -128,12 +116,4 @@ mDetailsIntent = detailsIntent; mInstallIntent = installIntent; } - - /** - * Sets the icon used to depict the app. - * @param Drawable App icon in Drawable form. - */ - void setIcon(Drawable icon) { - mIcon = icon; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java index 2428ce59..da59c37 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java
@@ -63,7 +63,7 @@ * @param observer Alerted when the package has been completely installed. * @param packageName Name of the package for the app to monitor. */ - InstallerDelegate( + public InstallerDelegate( Looper looper, PackageManager packageManager, Observer observer, String packageName) { mHandler = new Handler(looper); mPackageManager = packageManager; @@ -100,14 +100,24 @@ /** * Checks if the app has been installed on the system. + * @param packageManager PackageManager to use. + * @param packageName Name of the package to check. + * @return True if the PackageManager reports that the app is installed, false otherwise. + */ + public static boolean isInstalled(PackageManager packageManager, String packageName) { + List<PackageInfo> packs = packageManager.getInstalledPackages(0); + for (int i = 0; i < packs.size(); i++) { + if (TextUtils.equals(packs.get(i).packageName, packageName)) return true; + } + return false; + } + + /** + * Checks if the app has been installed on the system. * @return True if the PackageManager reports that the app is installed, false otherwise. */ private boolean isInstalled() { - List<PackageInfo> packs = mPackageManager.getInstalledPackages(0); - for (int i = 0; i < packs.size(); i++) { - if (TextUtils.equals(packs.get(i).packageName, mPackageName)) return true; - } - return false; + return isInstalled(mPackageManager, mPackageName); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/child_accounts/ChildAccountService.java b/chrome/android/java/src/org/chromium/chrome/browser/child_accounts/ChildAccountService.java index 15066cc..012513b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/child_accounts/ChildAccountService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/child_accounts/ChildAccountService.java
@@ -128,6 +128,7 @@ new AccountManagerCallback<Boolean>() { @Override public void run(AccountManagerFuture<Boolean> future) { + Log.i(TAG, "completed AM request"); assert future == mAccountManagerFuture; assert future.isDone(); @@ -143,7 +144,10 @@ timer.schedule(new TimerTask() { @Override public void run() { - if (!mAccountManagerFuture.isDone()) mAccountManagerFuture.cancel(true); + if (!mAccountManagerFuture.isDone()) { + Log.i(TAG, "cancelling AM request"); + mAccountManagerFuture.cancel(true); + } }}, CHILD_ACCOUNT_TIMEOUT_MS); } @@ -155,7 +159,10 @@ private boolean getFutureResult() { try { - return mAccountManagerFuture.getResult(); + Log.i(TAG, "before mAccountManagerFuture.getResult()"); + boolean result = mAccountManagerFuture.getResult(); + Log.i(TAG, "after mAccountManagerFuture.getResult()"); + return result; } catch (OperationCanceledException e) { Log.e(TAG, "Timed out fetching child account flag: ", e); } catch (AuthenticatorException e) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java index f66455b..66eaaf66 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java
@@ -4,27 +4,166 @@ package org.chromium.chrome.browser.infobar; +import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.RatingBar; import android.widget.TextView; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.CalledByNative; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.banners.AppData; + /** * Infobar informing the user about an app related to this page. */ -public class AppBannerInfoBar extends ConfirmInfoBar { - /** Web app: URL pointing to the web app. */ +public class AppBannerInfoBar extends ConfirmInfoBar implements View.OnClickListener { + // Installation states. + public static final int INSTALL_STATE_NOT_INSTALLED = 0; + public static final int INSTALL_STATE_INSTALLING = 1; + public static final int INSTALL_STATE_INSTALLED = 2; + + // Views composing the infobar. + private Button mButton; + private ViewGroup mTitleView; + private View mIconView; + + private final String mAppTitle; + + // Data for native app installs. + private final AppData mAppData; + private int mInstallState; + + // Data for web app installs. private final String mAppUrl; - public AppBannerInfoBar(long nativeInfoBar, String appTitle, Bitmap iconBitmap, - String installText, String url) { - super(nativeInfoBar, null, 0, iconBitmap, appTitle, null, installText, null); + // Banner for native apps. + private AppBannerInfoBar(long nativeInfoBar, String appTitle, Bitmap iconBitmap, AppData data) { + super(nativeInfoBar, null, 0, iconBitmap, appTitle, null, data.installButtonText(), null); + mAppTitle = appTitle; + mAppData = data; + mAppUrl = null; + mInstallState = INSTALL_STATE_NOT_INSTALLED; + } + + // Banner for web apps. + private AppBannerInfoBar(long nativeInfoBar, String appTitle, Bitmap iconBitmap, String url) { + super(nativeInfoBar, null, 0, iconBitmap, appTitle, null, getAddToHomescreenText(), null); + mAppTitle = appTitle; + mAppData = null; mAppUrl = url; + mInstallState = INSTALL_STATE_NOT_INSTALLED; } @Override public void createContent(InfoBarLayout layout) { - TextView url = new TextView(layout.getContext()); - url.setText(mAppUrl); - layout.setCustomContent(url); super.createContent(layout); + + mButton = layout.getPrimaryButton(); + mIconView = layout.getIcon(); + + Resources res = getContext().getResources(); + int iconSize = res.getDimensionPixelSize(R.dimen.app_banner_infobar_icon_size); + int iconSpacing = res.getDimensionPixelSize(R.dimen.app_banner_infobar_icon_spacing); + layout.setIconSizeAndSpacing(iconSize, iconSize, iconSpacing); + + mTitleView = (ViewGroup) LayoutInflater.from(getContext()).inflate( + R.layout.app_banner_title, null); + TextView appName = (TextView) mTitleView.findViewById(R.id.app_name); + RatingBar ratingView = (RatingBar) mTitleView.findViewById(R.id.rating_bar); + TextView webAppUrl = (TextView) mTitleView.findViewById(R.id.web_app_url); + appName.setText(mAppTitle); + layout.setMessageView(mTitleView); + + Context context = getContext(); + if (mAppData != null) { + // Native app. + ImageView playLogo = new ImageView(layout.getContext()); + playLogo.setImageResource(R.drawable.google_play); + layout.setCustomViewInButtonRow(playLogo); + + ratingView.setRating(mAppData.rating()); + layout.getPrimaryButton().setButtonColor(getContext().getResources().getColor( + R.color.app_banner_install_button_bg)); + layout.setContentDescription(context.getString( + R.string.app_banner_view_native_app_accessibility, mAppTitle, + mAppData.rating())); + mTitleView.removeView(webAppUrl); + } else { + // Web app. + webAppUrl.setText(mAppUrl); + layout.setContentDescription(context.getString( + R.string.app_banner_view_web_app_accessibility, mAppTitle, + mAppUrl)); + mTitleView.removeView(ratingView); + } + + // Set up clicking on the controls to bring up the app details. + mTitleView.setOnClickListener(this); + if (mIconView != null) mIconView.setOnClickListener(this); } -} \ No newline at end of file + + @Override + public void onButtonClicked(boolean isPrimaryButton) { + if (mInstallState == INSTALL_STATE_INSTALLING) { + setControlsEnabled(true); + updateButton(); + return; + } + super.onButtonClicked(isPrimaryButton); + } + + @CalledByNative + public void onInstallStateChanged(int newState) { + setControlsEnabled(true); + mInstallState = newState; + updateButton(); + } + + private void updateButton() { + String text; + String accessibilityText = null; + boolean enabled = true; + if (mInstallState == INSTALL_STATE_NOT_INSTALLED) { + text = mAppData.installButtonText(); + accessibilityText = + getContext().getString(R.string.app_banner_install_accessibility, text); + } else if (mInstallState == INSTALL_STATE_INSTALLING) { + text = getContext().getString(R.string.app_banner_installing); + enabled = false; + } else { + text = getContext().getString(R.string.app_banner_open); + } + + mButton.setText(text); + mButton.setContentDescription(accessibilityText); + mButton.setEnabled(enabled); + } + + @Override + public void onClick(View v) { + if (v == mTitleView || v == mIconView) onLinkClicked(); + } + + private static String getAddToHomescreenText() { + return ApplicationStatus.getApplicationContext().getString(R.string.menu_add_to_homescreen); + } + + @CalledByNative + private static InfoBar createNativeAppInfoBar( + long nativeInfoBar, String appTitle, Bitmap iconBitmap, AppData appData) { + return new AppBannerInfoBar(nativeInfoBar, appTitle, iconBitmap, appData); + } + + @CalledByNative + private static InfoBar createWebAppInfoBar( + long nativeInfoBar, String appTitle, Bitmap iconBitmap, String url) { + return new AppBannerInfoBar(nativeInfoBar, appTitle, iconBitmap, url); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java deleted file mode 100644 index 9573af6..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.infobar; - -import android.graphics.Bitmap; - -import org.chromium.base.CalledByNative; - -/** - * Handles creation of AppBannerInfoBars. - */ -public class AppBannerInfoBarDelegate { - private AppBannerInfoBarDelegate() { - } - - @CalledByNative - private static AppBannerInfoBarDelegate create() { - return new AppBannerInfoBarDelegate(); - } - - @CalledByNative - private InfoBar showInfoBar( - long nativeInfoBar, String appTitle, Bitmap iconBitmap, String buttonText, String url) { - return new AppBannerInfoBar(nativeInfoBar, appTitle, iconBitmap, buttonText, url); - } -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java index be4d3d3..3405852 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java
@@ -152,6 +152,7 @@ InfoBarLayout layout = new InfoBarLayout(mContext, this, mIconDrawableId, mIconBitmap, mMessage); createContent(layout); + layout.onContentCreated(); return layout; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java index 356c10f..b350e84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
@@ -23,6 +23,9 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.ButtonCompat; + +import java.util.ArrayList; /** * Layout that arranges an InfoBar's views. An InfoBarLayout consists of: @@ -76,6 +79,18 @@ /** Whether the views are vertically stacked. */ public boolean isStacked; + Group(View... views) { + this.views = views; + } + + static View[] filterNullViews(View... views) { + ArrayList<View> viewsList = new ArrayList<View>(); + for (View v : views) { + if (v != null) viewsList.add(v); + } + return viewsList.toArray(new View[viewsList.size()]); + } + void setHorizontalMode(int horizontalSpacing, int startMargin, int endMargin) { isStacked = false; for (int i = 0; i < views.length; i++) { @@ -85,7 +100,6 @@ lp.endMargin = i == views.length - 1 ? endMargin : 0; lp.bottomMargin = 0; } - } void setVerticalMode(int verticalSpacing, int bottomMargin) { @@ -109,9 +123,14 @@ private final int mAccentColor; private final InfoBarView mInfoBarView; - private final TextView mMessageView; private final ImageButton mCloseButton; + private TextView mMessageTextView; + private View mMessageView; private ImageView mIconView; + private ButtonCompat mPrimaryButton; + private Button mSecondaryButton; + private Button mTertiaryButton; + private View mCustomButton; private Group mMainGroup; private Group mCustomGroup; @@ -169,7 +188,6 @@ mCloseButton.setOnClickListener(this); mCloseButton.setContentDescription(res.getString(R.string.infobar_close)); mCloseButton.setLayoutParams(new LayoutParams(0, -mMargin, -mMargin, -mMargin)); - addView(mCloseButton); // Set up the icon. if (iconResourceId != 0 || iconBitmap != null) { @@ -186,24 +204,27 @@ } // Set up the message view. - mMessageView = (TextView) LayoutInflater.from(context).inflate(R.layout.infobar_text, null); - mMessageView.setText(message, TextView.BufferType.SPANNABLE); - mMessageView.setMovementMethod(LinkMovementMethod.getInstance()); - mMessageView.setLinkTextColor(mAccentColor); - mMessageView.setLayoutParams(new LayoutParams(0, mMargin / 4, 0, 0)); - - if (mIconView == null) { - mMainGroup = addGroup(mMessageView); - } else { - mMainGroup = addGroup(mIconView, mMessageView); - } + mMessageTextView = (TextView) LayoutInflater.from(context).inflate(R.layout.infobar_text, + null); + mMessageTextView.setText(message, TextView.BufferType.SPANNABLE); + mMessageTextView.setMovementMethod(LinkMovementMethod.getInstance()); + mMessageTextView.setLinkTextColor(mAccentColor); + mMessageView = mMessageTextView; } /** * Sets the message to show on the infobar. */ public void setMessage(CharSequence message) { - mMessageView.setText(message, TextView.BufferType.SPANNABLE); + mMessageTextView.setText(message, TextView.BufferType.SPANNABLE); + } + + /** + * Sets a custom view to show in place of the message. + */ + public void setMessageView(View view) { + mMessageView = view; + mMessageTextView = null; } /** @@ -215,7 +236,7 @@ * - Stacked above each other on two separate rows, taking up the full width of the infobar. */ public void setCustomContent(View view1, View view2) { - mCustomGroup = addGroup(view1, view2); + mCustomGroup = new Group(view1, view2); } /** @@ -227,7 +248,7 @@ * - On a separate row, start-aligned */ public void setCustomContent(View view) { - mCustomGroup = addGroup(view); + mCustomGroup = new Group(view); } /** @@ -247,53 +268,85 @@ public void setButtons(String primaryText, String secondaryText, String tertiaryText) { if (TextUtils.isEmpty(primaryText)) return; - LayoutInflater inflater = LayoutInflater.from(getContext()); - Button primaryButton = (Button) inflater.inflate(R.layout.infobar_button, null); - primaryButton.setId(R.id.button_primary); - primaryButton.setOnClickListener(this); - primaryButton.setText(primaryText); - primaryButton.setBackgroundResource(R.drawable.btn_infobar_blue); - primaryButton.setTextColor(Color.WHITE); + mPrimaryButton = new ButtonCompat(getContext(), mAccentColor); + mPrimaryButton.setId(R.id.button_primary); + mPrimaryButton.setOnClickListener(this); + mPrimaryButton.setText(primaryText); + mPrimaryButton.setTextColor(Color.WHITE); - if (TextUtils.isEmpty(secondaryText)) { - mButtonGroup = addGroup(primaryButton); - return; - } + if (TextUtils.isEmpty(secondaryText)) return; - Button secondaryButton = (Button) inflater.inflate(R.layout.infobar_button, null); - secondaryButton.setId(R.id.button_secondary); - secondaryButton.setOnClickListener(this); - secondaryButton.setText(secondaryText); - secondaryButton.setTextColor(mAccentColor); + mSecondaryButton = ButtonCompat.createBorderlessButton(getContext()); + mSecondaryButton.setId(R.id.button_secondary); + mSecondaryButton.setOnClickListener(this); + mSecondaryButton.setText(secondaryText); + mSecondaryButton.setTextColor(mAccentColor); - if (TextUtils.isEmpty(tertiaryText)) { - mButtonGroup = addGroup(secondaryButton, primaryButton); - return; - } + if (TextUtils.isEmpty(tertiaryText)) return; - Button tertiaryButton = (Button) inflater.inflate(R.layout.infobar_button, null); - tertiaryButton.setId(R.id.button_tertiary); - tertiaryButton.setOnClickListener(this); - tertiaryButton.setText(tertiaryText); - tertiaryButton.setPadding(mMargin / 2, tertiaryButton.getPaddingTop(), mMargin / 2, - tertiaryButton.getPaddingBottom()); - tertiaryButton.setTextColor( + mTertiaryButton = ButtonCompat.createBorderlessButton(getContext()); + mTertiaryButton.setId(R.id.button_tertiary); + mTertiaryButton.setOnClickListener(this); + mTertiaryButton.setText(tertiaryText); + mTertiaryButton.setPadding(mMargin / 2, mTertiaryButton.getPaddingTop(), mMargin / 2, + mTertiaryButton.getPaddingBottom()); + mTertiaryButton.setTextColor( getContext().getResources().getColor(R.color.infobar_tertiary_button_text)); - - mButtonGroup = addGroup(tertiaryButton, secondaryButton, primaryButton); } /** - * Adds a group of Views that are measured and laid out together. + * Adds a custom view to show in the button row in place of the tertiary button. */ - private Group addGroup(View... views) { - Group group = new Group(); - group.views = views; + public void setCustomViewInButtonRow(View view) { + mCustomButton = view; + } - for (View v : views) { - addView(v); + /** + * Sets the size of the icon and the spacing between it and the message. + */ + public void setIconSizeAndSpacing(int width, int height, int iconMessageSpacing) { + LayoutParams lp = (LayoutParams) mIconView.getLayoutParams(); + lp.width = width; + lp.height = height; + lp.endMargin = iconMessageSpacing; + } + + + /** + * Returns the primary button, or null if it doesn't exist. + */ + public ButtonCompat getPrimaryButton() { + return mPrimaryButton; + } + + /** + * Returns the icon, or null if it doesn't exist. + */ + public ImageView getIcon() { + return mIconView; + } + + /** + * Must be called after the message, buttons, and custom content have been set, and before the + * first call to onMeasure(). + */ + void onContentCreated() { + mMessageView.setLayoutParams(new LayoutParams(0, mMargin / 4, 0, 0)); + mMainGroup = new Group(Group.filterNullViews(mIconView, mMessageView)); + + View[] buttons = Group.filterNullViews(mCustomButton, mTertiaryButton, + mSecondaryButton, mPrimaryButton); + if (buttons.length != 0) mButtonGroup = new Group(buttons); + + // Add the child views in the desired focus order. + for (View v : mMainGroup.views) addView(v); + if (mCustomGroup != null) { + for (View v : mCustomGroup.views) addView(v); } - return group; + if (mButtonGroup != null) { + for (View v : mButtonGroup.views) addView(v); + } + addView(mCloseButton); } @Override @@ -393,13 +446,32 @@ // If the infobar consists of just a main row and a buttons row, the buttons must be // at least 32dp below the bottom of the message text. - if (mCustomGroup == null) { - LayoutParams lp = (LayoutParams) mMessageView.getLayoutParams(); - int messageBottom = lp.top + mMessageView.getMeasuredHeight(); + if (mCustomGroup == null && mMessageTextView != null) { + LayoutParams lp = (LayoutParams) mMessageTextView.getLayoutParams(); + int messageBottom = lp.top + mMessageTextView.getMeasuredHeight(); mTop = Math.max(mTop, messageBottom + 2 * mMargin); } } placeGroup(mButtonGroup); + + if (mCustomButton != null && !buttonGroupOnMainRow) { + // The custom button is start-aligned with the message view (unless that causes it + // to overlap the primary button). + LayoutParams primaryButtonLP = (LayoutParams) mPrimaryButton.getLayoutParams(); + LayoutParams customButtonLP = (LayoutParams) mCustomButton.getLayoutParams(); + LayoutParams messageLP = (LayoutParams) mMessageView.getLayoutParams(); + if (customButtonLP.start >= messageLP.start) { + customButtonLP.start = messageLP.start; + } else { + customButtonLP.start = mMargin; + } + if (!mButtonGroup.isStacked) { + // Center the custom button vertically relative to the primary button. + customButtonLP.top = primaryButtonLP.top + + (mPrimaryButton.getMeasuredHeight() + - mCustomButton.getMeasuredHeight()) / 2; + } + } } startRow(); @@ -516,11 +588,15 @@ // Group is too wide to fit on a single row, so stack the group items vertically. mButtonGroup.setVerticalMode(mMargin / 2, 0); mButtonGroup.gravity = Gravity.FILL_HORIZONTAL; - } else if (mButtonGroup.views.length == 3) { - // Align tertiary button at the start and the other two buttons at the end. - ((LayoutParams) mButtonGroup.views[0].getLayoutParams()).endMargin += extraWidth; + } else if (mTertiaryButton != null) { + // Align tertiary or custom button at the start and the other buttons at the end. + ((LayoutParams) mTertiaryButton.getLayoutParams()).endMargin += extraWidth; } } + if (row == ROW_MAIN && mCustomButton != null) { + // Increase spacing between custom button and primary button. + ((LayoutParams) mCustomButton.getLayoutParams()).endMargin = mMargin; + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java index 3394df15..772aea5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java
@@ -64,8 +64,8 @@ } @Override - public void setIcon(int resourceId) { - mDrawable = getContext().getResources().getDrawable(resourceId); + public void setIcon(Drawable drawable) { + mDrawable = drawable; if (mImageView != null) mImageView.setImageDrawable(mDrawable); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java index a015cfd3..15ea958 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java
@@ -12,6 +12,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; @@ -20,6 +22,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; +import org.chromium.chrome.browser.widget.FloatLabelLayout; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -28,12 +31,15 @@ /** * Provides the Java-ui for editing a Credit Card autofill entry. */ -public class AutofillCreditCardEditor extends Fragment implements TextWatcher { +public class AutofillCreditCardEditor extends Fragment implements OnItemSelectedListener, + TextWatcher { // GUID of the profile we are editing. // May be the empty string if creating a new profile. private String mGUID; + private FloatLabelLayout mNameLabel; private EditText mNameText; + private FloatLabelLayout mNumberLabel; private EditText mNumberText; private Spinner mExpirationMonth; private Spinner mExpirationYear; @@ -52,10 +58,10 @@ super.onCreate(savedInstanceState); View v = inflater.inflate(R.layout.autofill_credit_card_editor, container, false); - mNameText = (EditText) v.findViewById( - R.id.autofill_credit_card_editor_name_edit); - mNumberText = (EditText) v.findViewById( - R.id.autofill_credit_card_editor_number_edit); + mNameLabel = (FloatLabelLayout) v.findViewById(R.id.credit_card_name_label); + mNameText = (EditText) v.findViewById(R.id.credit_card_name_edit); + mNumberLabel = (FloatLabelLayout) v.findViewById(R.id.credit_card_number_label); + mNumberText = (EditText) v.findViewById(R.id.credit_card_number_edit); // Set text watcher to format credit card number mNumberText.addTextChangedListener(new CreditCardNumberFormattingTextWatcher()); @@ -85,6 +91,17 @@ } @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + if ((parent == mExpirationYear && position != mInitialExpirationYearPos) + || (parent == mExpirationMonth && position != mInitialExpirationMonthPos)) { + enableSaveButton(); + } + } + + @Override + public void onNothingSelected(AdapterView<?> parent) {} + + @Override public void afterTextChanged(Editable s) {} @Override @@ -92,7 +109,7 @@ @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - updateSaveButtonState(); + enableSaveButton(); } void addSpinnerAdapters() { @@ -122,12 +139,24 @@ private void addCardDataToEditFields() { CreditCard card = PersonalDataManager.getInstance().getCreditCard(mGUID); if (card == null) { + // FloatLabelLayout animates showing the field label when its EditText is focused; + // to avoid this animation, manually set the name label to be visible, its EditText + // hint to null and request focus on its EditText field. + mNameLabel.getLabel().setVisibility(View.VISIBLE); + mNameText.setHint(null); mNameText.requestFocus(); return; } - mNameText.setText(card.getName()); - mNumberText.setText(card.getNumber()); + if (!TextUtils.isEmpty(card.getName())) { + mNameLabel.setText(card.getName()); + } + if (!TextUtils.isEmpty(card.getNumber())) { + mNumberLabel.setText(card.getNumber()); + } + + // Make the name label focusable in touch mode so that mNameText doesn't get focused. + mNameLabel.getLabel().setFocusableInTouchMode(true); int monthAsInt = 1; if (!card.getMonth().isEmpty()) { @@ -214,13 +243,13 @@ // Listen for changes to inputs. Enable the save button after something has changed. mNameText.addTextChangedListener(this); mNumberText.addTextChangedListener(this); + mExpirationMonth.setOnItemSelectedListener(this); + mExpirationYear.setOnItemSelectedListener(this); } - private void updateSaveButtonState() { + private void enableSaveButton() { Button button = (Button) getView().findViewById(R.id.autofill_credit_card_save); - boolean enabled = mNameText.getEditableText().toString().trim().length() > 0 - || mNumberText.getEditableText().toString().trim().length() > 0; - button.setEnabled(enabled); + button.setEnabled(true); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java index 79b615a..f2116ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java
@@ -6,7 +6,9 @@ import android.content.Context; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.preference.Preference; import android.view.View; @@ -57,6 +59,18 @@ mCategoryFilter = categoryFilter; mFilter = new WebsiteSettingsCategoryFilter(); setWidgetLayoutResource(R.layout.website_features); + + // To make sure the layout stays stable throughout, we assign a + // transparent drawable of the same size as the favicon. This is so that + // we can fetch the favicon in the background and not have to worry + // about the title appearing to jump (http://crbug.com/453626) when the + // favicon becomes available. + ColorDrawable drawable = new ColorDrawable(Color.TRANSPARENT); + int size = Math.round(FAVICON_SIZE_DP + * getContext().getResources().getDisplayMetrics().density); + drawable.setBounds(0, 0, size, size); + setIcon(drawable); + refresh(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferences.java index 53be86b..1682e8d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferences.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate; import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils; import org.chromium.chrome.browser.preferences.PrefServiceBridge; +import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; @@ -437,8 +438,9 @@ // Set the title and arrow icons for the header. allowedGroup.setGroupTitle(resourceId, numAllowed); - allowedGroup.setIcon( - mAllowListExpanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more); + TintedDrawable icon = TintedDrawable.constructTintedDrawable(getResources(), + mAllowListExpanded ? R.drawable.ic_expand : R.drawable.ic_collapse); + allowedGroup.setIcon(icon); } private void updateBlockedHeader(int numBlocked) { @@ -452,19 +454,22 @@ // Set the title and arrow icons for the header. blockedGroup.setGroupTitle(R.string.website_settings_blocked_group_heading, numBlocked); - blockedGroup.setIcon( - mBlockListExpanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more); + TintedDrawable icon = TintedDrawable.constructTintedDrawable(getResources(), + mBlockListExpanded ? R.drawable.ic_expand : R.drawable.ic_collapse); + blockedGroup.setIcon(icon); } private Website createSiteByOrigin(WebsiteAddress address) { String origin = address.getOrigin(); String host = address.getHost(); Website site = new Website(address); - if (!mSitesByOrigin.containsKey(origin)) + if (!mSitesByOrigin.containsKey(origin)) { mSitesByOrigin.put(origin, new HashSet<Website>()); + } mSitesByOrigin.get(origin).add(site); - if (!mSitesByHost.containsKey(host)) + if (!mSitesByHost.containsKey(host)) { mSitesByHost.put(host, new HashSet<Website>()); + } mSitesByHost.get(host).add(site); return site; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java new file mode 100644 index 0000000..a27cb3d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java
@@ -0,0 +1,139 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.widget; + +import android.animation.AnimatorInflater; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.GradientDrawable; +import android.os.Build; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.widget.Button; + +import org.chromium.chrome.R; + +/** + * A Material-styled button with a customizable background color. + * + * Create a button in Java: + * + * new ButtonCompat(context, Color.RED); + * + * Create a button in XML: + * + * <ButtonCompat + * android:layout_width="wrap_content" + * android:layout_height="wrap_content" + * android:text="Click me" + * chrome:buttonColor="#f00" /> + * + * On L devices, this is a true Material button. On earlier devices, the button is similar but lacks + * ripples and lacks a shadow when pressed. + */ +public class ButtonCompat extends Button { + + /** The amount by which to dim the button background when pressed. */ + private static final float PRE_L_DIM_AMOUNT = 0.85f; + + private int mColor; + + /** + * Returns a new borderless material-style button. + */ + public static Button createBorderlessButton(Context context) { + Context wrapper = new ContextThemeWrapper(context, R.style.ButtonBorderlessCompat); + return new Button(wrapper, null, 0); + } + + /** + * Constructs a button with the given buttonColor as its background. + */ + public ButtonCompat(Context context, int buttonColor) { + this(context, buttonColor, null); + } + + /** + * Constructor for inflating from XML. + */ + public ButtonCompat(Context context, AttributeSet attrs) { + this(context, getColorFromAttributeSet(context, attrs), attrs); + } + + private ButtonCompat(Context context, int buttonColor, AttributeSet attrs) { + // To apply the ButtonCompat style to this view, use a ContextThemeWrapper to inject the + // ButtonCompat style into the current theme, and pass 0 as the defStyleAttr to the super + // constructor to prevent the default Button style from being applied. + super(new ContextThemeWrapper(context, R.style.ButtonCompat), attrs, 0); + + getBackground().mutate(); + setButtonColor(buttonColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + // Use the StateListAnimator from the Widget.Material.Button style to animate the + // elevation when the button is pressed. + TypedArray a = getContext().obtainStyledAttributes(null, + new int[]{android.R.attr.stateListAnimator}, 0, + android.R.style.Widget_Material_Button); + setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), + a.getResourceId(0, 0))); + a.recycle(); + } + } + + /** + * Sets the background color of the button. + */ + public void setButtonColor(int color) { + if (color == mColor) return; + mColor = color; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getBackground().setColorFilter(mColor, PorterDuff.Mode.SRC_IN); + } else { + updateButtonBackgroundPreL(); + } + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + updateButtonBackgroundPreL(); + } + } + + private void updateButtonBackgroundPreL() { + int color = mColor; + for (int state : getDrawableState()) { + if (state == android.R.attr.state_pressed + || state == android.R.attr.state_focused + || state == android.R.attr.state_selected) { + color = getActiveColorPreL(); + break; + } + } + + GradientDrawable background = (GradientDrawable) getBackground(); + background.setColor(color); + } + + private int getActiveColorPreL() { + return Color.rgb( + Math.round(Color.red(mColor) * PRE_L_DIM_AMOUNT), + Math.round(Color.green(mColor) * PRE_L_DIM_AMOUNT), + Math.round(Color.blue(mColor) * PRE_L_DIM_AMOUNT) + ); + } + + private static int getColorFromAttributeSet(Context context, AttributeSet attrs) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ButtonCompat, 0, 0); + int color = a.getColor(R.styleable.ButtonCompat_buttonColor, Color.WHITE); + a.recycle(); + return color; + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java new file mode 100644 index 0000000..1e75427 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java
@@ -0,0 +1,96 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ProgressBar; + +import org.chromium.base.ApiCompatibilityUtils; + +/** + * A progress bar that smoothly animates incremental updates. + * <p> + * Consumers of this class need to be aware that calls to {@link #getProgress()} will return + * the currently visible progress value and not the one set in the last call to + * {@link #setProgress(int)}. + */ +public class SmoothProgressBar extends ProgressBar { + private static final int MAX = 100; + + // The amount of time between subsequent progress updates. 16ms is chosen to make 60fps. + private static final long PROGRESS_UPDATE_DELAY_MS = 16; + + private boolean mIsAnimated = false; + private int mTargetProgress; + + // Since the progress bar is being animated, the internal progress bar resolution should be + // at least fine as the width, not MAX. This multiplier will be applied to input progress + // to convert to a finer scale. + private int mResolutionMutiplier = 1; + + private Runnable mUpdateProgressRunnable = new Runnable() { + @Override + public void run() { + if (getProgress() == mTargetProgress) return; + if (!mIsAnimated) { + setProgressInternal(mTargetProgress); + return; + } + // Every time, the progress bar get's at least 20% closer to mTargetProcess. + // Add 3 to guarantee progressing even if they only differ by 1. + setProgressInternal(getProgress() + (mTargetProgress - getProgress() + 3) / 4); + ApiCompatibilityUtils.postOnAnimationDelayed( + SmoothProgressBar.this, this, PROGRESS_UPDATE_DELAY_MS); + } + }; + + /** + * Create a new progress bar with range 0...100 and initial progress of 0. + * @param context the application environment. + * @param attrs the xml attributes that should be used to initialize this view. + */ + public SmoothProgressBar(Context context, AttributeSet attrs) { + super(context, attrs); + setMax(MAX * mResolutionMutiplier); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + int normalizedProgress = getProgress() / mResolutionMutiplier; + + // Choose an integer resolution multiplier that makes the scale at least fine as the width. + mResolutionMutiplier = Math.max(1, (w + MAX - 1) / MAX); + setMax(mResolutionMutiplier * MAX); + setProgressInternal(normalizedProgress * mResolutionMutiplier); + } + + @Override + public void setProgress(int progress) { + final int targetProgress = progress * mResolutionMutiplier; + if (mTargetProgress == targetProgress) return; + mTargetProgress = targetProgress; + removeCallbacks(mUpdateProgressRunnable); + ApiCompatibilityUtils.postOnAnimation(this, mUpdateProgressRunnable); + } + + /** + * Sets whether to animate incremental updates or not. + * @param isAnimated True if it is needed to animate incremental updates. + */ + public void setAnimated(boolean isAnimated) { + mIsAnimated = isAnimated; + } + + /** + * Called to update the progress visuals. + * @param progress The progress value to set the visuals to. + */ + protected void setProgressInternal(int progress) { + super.setProgress(progress); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java new file mode 100644 index 0000000..5b59f278 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
@@ -0,0 +1,186 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.widget; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.util.AttributeSet; +import android.view.View; + +import org.chromium.base.VisibleForTesting; +import org.chromium.ui.interpolators.BakedBezierInterpolator; + +/** + * Progress bar for use in the Toolbar view. + */ +public class ToolbarProgressBar extends SmoothProgressBar { + private static final long PROGRESS_CLEARING_DELAY_MS = 200; + private static final int SHOW_HIDE_DURATION_MS = 100; + + private final Runnable mClearLoadProgressRunnable; + private int mDesiredVisibility; + private Animator mShowAnimator; + private Animator mHideAnimator; + + /** + * Creates a toolbar progress bar. + * @param context the application environment. + * @param attrs the xml attributes that should be used to initialize this view. + */ + public ToolbarProgressBar(Context context, AttributeSet attrs) { + super(context, attrs); + // The base constructor will trigger a progress change and alter the expected + // visibility, so force a visibility change to reset the state. + setVisibility(VISIBLE); + + mClearLoadProgressRunnable = new Runnable() { + @Override + public void run() { + setProgress(0); + } + }; + + // Hide the background portion of the system progress bar. + Drawable progressDrawable = getProgressDrawable(); + if (progressDrawable instanceof LayerDrawable) { + Drawable progressBackgroundDrawable = + ((LayerDrawable) progressDrawable) + .findDrawableByLayerId(android.R.id.background); + if (progressBackgroundDrawable != null) { + progressBackgroundDrawable.setVisible(false, false); + progressBackgroundDrawable.setAlpha(0); + } + } + } + + @Override + public void setSecondaryProgress(int secondaryProgress) { + super.setSecondaryProgress(secondaryProgress); + setVisibilityForProgress(); + } + + @Override + protected void setProgressInternal(int progress) { + super.setProgressInternal(progress); + + if (progress == getMax()) { + postDelayed(mClearLoadProgressRunnable, PROGRESS_CLEARING_DELAY_MS); + } + + setVisibilityForProgress(); + } + + @Override + public void setVisibility(int v) { + mDesiredVisibility = v; + setVisibilityForProgress(); + } + + private void setVisibilityForProgress() { + if (mDesiredVisibility != VISIBLE) { + super.setVisibility(mDesiredVisibility); + return; + } + + int progress = Math.max(getProgress(), getSecondaryProgress()); + super.setVisibility(progress == 0 ? INVISIBLE : VISIBLE); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + // Some versions of Android have a bug where they don't properly update the drawables with + // the correct bounds. setProgressDrawable has been overridden to properly push the bounds + // but on rotation they weren't always being set. Forcing a bounds update on size changes + // fixes the problem. + setProgressDrawable(getProgressDrawable()); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + buildAnimators(); + setPivotY(getHeight()); + } + + @Override + public void setProgressDrawable(Drawable d) { + Drawable currentDrawable = getProgressDrawable(); + + super.setProgressDrawable(d); + + if (currentDrawable != null && d instanceof LayerDrawable) { + LayerDrawable ld = (LayerDrawable) d; + for (int i = 0; i < ld.getNumberOfLayers(); i++) { + ld.getDrawable(i).setBounds(currentDrawable.getBounds()); + } + } + } + + /** + * @return Whether or not this progress bar has animations running for showing/hiding itself. + */ + @VisibleForTesting + boolean isAnimatingForShowOrHide() { + return (mShowAnimator != null && mShowAnimator.isStarted()) + || (mHideAnimator != null && mHideAnimator.isStarted()); + } + + private void buildAnimators() { + if (mShowAnimator != null && mShowAnimator.isRunning()) mShowAnimator.end(); + if (mHideAnimator != null && mHideAnimator.isRunning()) mHideAnimator.end(); + + mShowAnimator = ObjectAnimator.ofFloat(this, View.SCALE_Y, 0.f, 1.f); + mShowAnimator.setDuration(SHOW_HIDE_DURATION_MS); + mShowAnimator.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE); + mShowAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + setSecondaryProgress(getMax()); + } + }); + + mHideAnimator = ObjectAnimator.ofFloat(this, View.SCALE_Y, 1.f, 0.f); + mHideAnimator.setDuration(SHOW_HIDE_DURATION_MS); + mHideAnimator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE); + mHideAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + setSecondaryProgress(0); + } + }); + } + + @Override + public void setProgress(int progress) { + // If the show animator has started, the progress bar needs to be tracked as if it is + // currently showing. This makes sure we trigger the proper hide animation and cancel the + // show animation if we show/hide the bar very fast. See crbug.com/453360. + boolean isShowing = + getProgress() > 0 || (mShowAnimator != null && mShowAnimator.isStarted()); + boolean willShow = progress > 0; + + removeCallbacks(mClearLoadProgressRunnable); + super.setProgress(progress); + + if (isShowing != willShow) { + if (mShowAnimator == null || mHideAnimator == null) buildAnimators(); + + if (mShowAnimator.isRunning()) mShowAnimator.end(); + if (mHideAnimator.isRunning()) mHideAnimator.end(); + + if (willShow) { + mShowAnimator.start(); + } else { + mHideAnimator.start(); + } + } + } +}
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 117bc2d..e330f5d1 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -161,12 +161,6 @@ <message name="IDS_AUTOFILL_CREDIT_CARD_EDITOR_EXPIRATION_DATE" desc="Label for text input field containing a credit card expiration date. [CHAR-LIMIT=32]"> Expiration date </message> - <message name="IDS_ACCESSIBILITY_AUTOFILL_CC_NAME_TEXTBOX" desc="Content description for text input field containing the name on a credit card."> - Name on card - </message> - <message name="IDS_ACCESSIBILITY_AUTOFILL_CC_NUMBER_TEXTBOX" desc="Content description for text input field containing a credit card number."> - Card number - </message> <!-- Autofill/Wallet integration preferences --> <message name="IDS_AUTOFILL_WALLET_TITLE" desc="Title for Autofill Wallet settings, which controls import of Wallet cards."> @@ -835,7 +829,10 @@ </message> <!-- App banner accessibility strings, used for touch exploration --> - <message name="IDS_APP_BANNER_VIEW_ACCESSIBILITY" desc="Accessibililty text: Describes the banner content, including the app name and rating."> + <message name="IDS_APP_BANNER_VIEW_WEB_APP_ACCESSIBILITY" desc="Accessibililty text: Describes the banner content, including the app name and its URL."> + Prompt to add page to the homescreen. App name: <ph name="APP_NAME">%1$s<ex>Gmail</ex></ph>. App URL: <ph name="APP_URL">%2$s<ex>http://gmail.com</ex></ph>. + </message> + <message name="IDS_APP_BANNER_VIEW_NATIVE_APP_ACCESSIBILITY" desc="Accessibililty text: Describes the banner content, including the app name and rating."> Prompt to get app from the Google Play Store. App name: <ph name="APP_NAME">%1$s<ex>Gmail</ex></ph>. App average rating: <ph name="APP_RATING">%2$.1f<ex>4.2</ex></ph>. </message> <message name="IDS_APP_BANNER_INSTALL_ACCESSIBILITY" desc="Accessibility text: Indicates that clicking on the button will purchase the app or install it.">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java index 73cf1a5..9596610 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
@@ -38,8 +38,12 @@ } /** Verifies that the form resubmission warning is not displayed upon first POST navigation. */ + /* @MediumTest @Feature({"Navigation"}) + crbug.com/454834 + */ + @DisabledTest public void testFormFirstNavigation() throws Throwable { // Load the url posting data for the first time. postNavigation();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectFileDialogTest.java index 75bf180e..3ddd7ae 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectFileDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectFileDialogTest.java
@@ -28,15 +28,15 @@ */ public class SelectFileDialogTest extends ChromeShellTestBase { private static final String DATA_URL = UrlUtils.encodeHtmlDataUri( - "<html><head><meta name=\"viewport\"" + - "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>" + - "<body><form action=\"about:blank\">" + - "<input id=\"input_file\" type=\"file\" /><br/>" + - "<input id=\"input_file_multiple\" type=\"file\" multiple /><br />" + - "<input id=\"input_image\" type=\"file\" accept=\"image/*\" capture /><br/>" + - "<input id=\"input_audio\" type=\"file\" accept=\"audio/*\" capture />" + - "</form>" + - "</body></html>"); + "<html><head><meta name=\"viewport\"" + + "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>" + + "<body><form action=\"about:blank\">" + + "<input id=\"input_file\" type=\"file\" /><br/>" + + "<input id=\"input_file_multiple\" type=\"file\" multiple /><br />" + + "<input id=\"input_image\" type=\"file\" accept=\"image/*\" capture /><br/>" + + "<input id=\"input_audio\" type=\"file\" accept=\"audio/*\" capture />" + + "</form>" + + "</body></html>"); private ContentViewCore mContentViewCore; private ActivityWindowAndroidForTest mActivityWindowAndroidForTest; @@ -52,7 +52,7 @@ } @Override - public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) { + public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { lastIntent = intent; lastCallback = callback; return 1;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java new file mode 100644 index 0000000..78782595 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
@@ -0,0 +1,83 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.widget; + +import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_PHONE; + +import android.test.suitebuilder.annotation.MediumTest; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.Restriction; +import org.chromium.chrome.shell.ChromeShellTestBase; +import org.chromium.chrome.shell.R; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; + +import java.util.concurrent.atomic.AtomicReference; + +/** + * Tests related to the ToolbarProgressBar. + */ +public class ToolbarProgressBarTest extends ChromeShellTestBase { + /** + * Test that calling progressBar.setProgress(# > 0) followed by progressBar.setProgress(0) + * results in a hidden progress bar (the secondary progress needs to be 0). + * @throws InterruptedException + */ + @Feature({"Android-Toolbar"}) + @MediumTest + @Restriction(RESTRICTION_TYPE_PHONE) + public void testProgressBarDisappearsAfterFastShowHide() throws InterruptedException { + launchChromeShellWithUrl("about:blank"); + waitForActiveShellToBeDoneLoading(); + + final AtomicReference<ToolbarProgressBar> progressBar = + new AtomicReference<ToolbarProgressBar>(); + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + progressBar.set((ToolbarProgressBar) getActivity().findViewById(R.id.progress)); + } + }); + + // Wait for the progress bar to be reset. + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return progressBar.get().getProgress() == 0; + } + }); + + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals("Progress bar should be hidden to start.", 0, + progressBar.get().getProgress()); + progressBar.get().setProgress(10); + assertTrue("Progress bar did not start animating", + progressBar.get().isAnimatingForShowOrHide()); + progressBar.get().setProgress(0); + } + }); + + // Wait for the progress bar to finish any and all animations. + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return !progressBar.get().isAnimatingForShowOrHide(); + } + }); + + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + // The secondary progress should be gone. + assertEquals("Progress bar background still visible.", 0, + progressBar.get().getSecondaryProgress()); + } + }); + } +} \ No newline at end of file
diff --git a/chrome/android/shell/chrome_main_delegate_chrome_shell_android.h b/chrome/android/shell/chrome_main_delegate_chrome_shell_android.h index 1bbe6b1..a4ee791b 100644 --- a/chrome/android/shell/chrome_main_delegate_chrome_shell_android.h +++ b/chrome/android/shell/chrome_main_delegate_chrome_shell_android.h
@@ -10,9 +10,9 @@ class ChromeMainDelegateChromeShellAndroid : public ChromeMainDelegateAndroid { public: ChromeMainDelegateChromeShellAndroid(); - virtual ~ChromeMainDelegateChromeShellAndroid(); + ~ChromeMainDelegateChromeShellAndroid() override; - virtual bool BasicStartupComplete(int* exit_code) override; + bool BasicStartupComplete(int* exit_code) override; private: DISALLOW_COPY_AND_ASSIGN(ChromeMainDelegateChromeShellAndroid);
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java index 9db47f5..2407b8e 100644 --- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java +++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java
@@ -170,6 +170,10 @@ } } }); + // Set up the animation placeholder to be the SurfaceView. This disables the + // SurfaceView's 'hole' clipping during animations that are notified to the window. + mWindow.setAnimationPlaceholderView( + mTabManager.getContentViewRenderView().getSurfaceView()); String startupUrl = getUrlFromIntent(getIntent()); if (!TextUtils.isEmpty(startupUrl)) {
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java index 35b8e4f..eea08de 100644 --- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java +++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java
@@ -7,7 +7,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; -import android.graphics.drawable.ClipDrawable; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; @@ -28,6 +27,7 @@ import org.chromium.chrome.browser.UrlUtilities; import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.appmenu.AppMenuHandler; +import org.chromium.chrome.browser.widget.SmoothProgressBar; import org.chromium.chrome.shell.omnibox.SuggestionPopup; import org.chromium.content.common.ContentSwitches; @@ -40,14 +40,14 @@ private final Runnable mClearProgressRunnable = new Runnable() { @Override public void run() { - mProgressDrawable.setLevel(0); + mProgressBar.setProgress(0); } }; private final Runnable mUpdateProgressRunnable = new Runnable() { @Override public void run() { - mProgressDrawable.setLevel(100 * mProgress); + mProgressBar.setProgress(mProgress); if (mLoading) { mStopReloadButton.setImageResource( R.drawable.btn_close); @@ -60,7 +60,7 @@ }; private EditText mUrlTextView; - private ClipDrawable mProgressDrawable; + private SmoothProgressBar mProgressBar; private ChromeShellTab mTab; private final TabObserver mTabObserver; @@ -140,7 +140,7 @@ protected void onFinishInflate() { super.onFinishInflate(); - mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground(); + mProgressBar = (SmoothProgressBar) findViewById(R.id.progress); initializeUrlField(); initializeTabSwitcherButton(); initializeMenuButton();
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java index ec36753..93ea158 100644 --- a/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java +++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java
@@ -110,6 +110,13 @@ } /** + * Get the ContentViewRenderView. + */ + public ContentViewRenderView getContentViewRenderView() { + return mContentViewRenderView; + } + + /** * @param startupUrl The URL that the first tab should navigate to. */ public void setStartupUrl(String startupUrl) {
diff --git a/chrome/android/shell/res/drawable/progress.xml b/chrome/android/shell/res/drawable/progress.xml deleted file mode 100644 index 121728f2..0000000 --- a/chrome/android/shell/res/drawable/progress.xml +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- Copyright 2012 The Chromium Authors. All rights reserved. - - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. - --> - -<clip xmlns:android="http://schemas.android.com/apk/res/android"> - <shape> - <solid android:color="@color/material_deep_teal_500" /> - </shape> -</clip>
diff --git a/chrome/android/shell/res/drawable/progress_bar.xml b/chrome/android/shell/res/drawable/progress_bar.xml new file mode 100644 index 0000000..58f6b54 --- /dev/null +++ b/chrome/android/shell/res/drawable/progress_bar.xml
@@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. +--> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@android:id/secondaryProgress"> + <clip android:gravity="left"> + <shape> + <solid android:color="@color/material_deep_teal_200" /> + </shape> + </clip> + </item> + <item android:id="@android:id/progress"> + <clip android:gravity="left"> + <shape> + <solid android:color="@color/material_deep_teal_500" /> + </shape> + </clip> + </item> +</layer-list> \ No newline at end of file
diff --git a/chrome/android/shell/res/layout/chrome_shell_activity.xml b/chrome/android/shell/res/layout/chrome_shell_activity.xml index c6050111..5edf9c0 100644 --- a/chrome/android/shell/res/layout/chrome_shell_activity.xml +++ b/chrome/android/shell/res/layout/chrome_shell_activity.xml
@@ -14,50 +14,59 @@ <org.chromium.chrome.shell.ChromeShellToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" - android:background="@drawable/progress"> - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/add_button" - android:layout_width="38dp" - android:layout_height="38dp" - android:src="@android:drawable/ic_menu_add" - android:visibility="gone" - android:scaleType="center"/> - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/stop_reload_button" - android:layout_width="38dp" - android:layout_height="38dp" - android:src="@drawable/btn_close" - android:background="?attr/selectableItemBackground" - android:scaleType="center"/> - <EditText android:id="@+id/url" - android:layout_width="0dp" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="bottom" - android:textSize="18sp" - android:autoText="true" - android:capitalize="sentences" - android:singleLine="true" - android:selectAllOnFocus="true" - android:hint="@string/url_hint" - android:inputType="textUri" - android:imeOptions="actionGo|flagNoExtractUi" /> - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/tab_switcher" - android:layout_width="38dp" - android:layout_height="38dp" - android:src="@drawable/btn_tabswitcher" - android:background="?attr/selectableItemBackground" - android:scaleType="center" - android:contentDescription="@null"/> - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/menu_button" - android:layout_width="38dp" - android:layout_height="38dp" - android:src="@drawable/btn_menu" - android:background="?attr/selectableItemBackground" - android:scaleType="center"/> + android:orientation="horizontal"> + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/add_button" + android:layout_width="38dp" + android:layout_height="38dp" + android:src="@android:drawable/ic_menu_add" + android:visibility="gone" + android:scaleType="center"/> + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/stop_reload_button" + android:layout_width="38dp" + android:layout_height="38dp" + android:src="@drawable/btn_close" + android:background="?attr/selectableItemBackground" + android:scaleType="center"/> + <EditText android:id="@+id/url" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="bottom" + android:textSize="18sp" + android:singleLine="true" + android:selectAllOnFocus="true" + android:hint="@string/url_hint" + android:inputType="textUri" + android:imeOptions="actionGo|flagNoExtractUi" /> + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/tab_switcher" + android:layout_width="38dp" + android:layout_height="38dp" + android:src="@drawable/btn_tabswitcher" + android:background="?attr/selectableItemBackground" + android:scaleType="center" + android:contentDescription="@null"/> + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/menu_button" + android:layout_width="38dp" + android:layout_height="38dp" + android:src="@drawable/btn_menu" + android:background="?attr/selectableItemBackground" + android:scaleType="center"/> + </LinearLayout> + <org.chromium.chrome.browser.widget.ToolbarProgressBar + android:id="@+id/progress" + style="@android:style/Widget.Holo.Light.ProgressBar.Horizontal" + android:progressDrawable="@drawable/progress_bar" + android:layout_width="match_parent" + android:layout_height="2dp" + android:progress="0" /> </org.chromium.chrome.shell.ChromeShellToolbar> <FrameLayout android:id="@+id/content_container" android:layout_width="match_parent"
diff --git a/chrome/android/shell/res/layout/suggestion_item.xml b/chrome/android/shell/res/layout/suggestion_item.xml index 9f3ff7f..3963790 100644 --- a/chrome/android/shell/res/layout/suggestion_item.xml +++ b/chrome/android/shell/res/layout/suggestion_item.xml
@@ -12,7 +12,7 @@ android:gravity="center_vertical" android:orientation="horizontal"> - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + <LinearLayout android:id="@+id/inner_layout" android:layout_width="0dp" android:layout_height="match_parent" @@ -28,6 +28,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" + android:gravity="start" android:textSize="18sp" android:includeFontPadding="false"/> @@ -41,6 +42,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" + android:gravity="start" android:includeFontPadding="false"/> </LinearLayout> @@ -51,6 +53,7 @@ android:layout_height="match_parent" android:gravity="end" android:scaleType="center" - android:src="@drawable/suggestion_arrow"/> + android:src="@drawable/suggestion_arrow" + android:contentDescription="@null" /> </LinearLayout>
diff --git a/chrome/android/shell/res/menu/main_menu.xml b/chrome/android/shell/res/menu/main_menu.xml index cf15312b..32899a2 100644 --- a/chrome/android/shell/res/menu/main_menu.xml +++ b/chrome/android/shell/res/menu/main_menu.xml
@@ -9,7 +9,7 @@ <group android:id="@+id/MAIN_MENU" android:visible="false" > - <item> + <item android:title="@null"> <menu> <item android:id="@+id/back_menu_id" @@ -37,7 +37,7 @@ <item android:id="@+id/distill_page" android:title="@string/distill_page_menu"/> - <item> + <item android:title="@null"> <menu> <item android:id="@+id/share_menu_id"
diff --git a/chrome/android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.h b/chrome/android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.h index 6b65925..bec75bf0 100644 --- a/chrome/android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.h +++ b/chrome/android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.h
@@ -11,11 +11,11 @@ : public ChromeMainDelegateAndroid { public: ChromeMainDelegateChromeSyncShellAndroid(); - virtual ~ChromeMainDelegateChromeSyncShellAndroid(); + ~ChromeMainDelegateChromeSyncShellAndroid() override; - virtual bool RegisterApplicationNativeMethods(JNIEnv* env) override; + bool RegisterApplicationNativeMethods(JNIEnv* env) override; - virtual bool BasicStartupComplete(int* exit_code) override; + bool BasicStartupComplete(int* exit_code) override; private: DISALLOW_COPY_AND_ASSIGN(ChromeMainDelegateChromeSyncShellAndroid);
diff --git a/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/FakeServerHelper.java b/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/FakeServerHelper.java index 09a25ce..51cd031 100644 --- a/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/FakeServerHelper.java +++ b/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/FakeServerHelper.java
@@ -7,7 +7,7 @@ import android.content.Context; import org.chromium.base.ThreadUtils; -//import org.chromium.chrome.browser.sync.ProfileSyncService; +import org.chromium.sync.internal_api.pub.base.ModelType; import java.util.concurrent.Callable; @@ -113,6 +113,25 @@ nativeDeleteFakeServer(mNativeFakeServerHelperAndroid, nativeFakeServer); } + /** + * Returns whether {@code count} entities exist on the fake Sync server with the given + * {@code modelType} and {@code name}. + * + * @param count the number of fake server entities to verify + * @param modelType the model type of entities to verify + * @param name the name of entities to verify + * + * @return whether the number of specified entities exist + */ + public boolean verifyEntityCountByTypeAndName(int count, ModelType modelType, String name) { + if (sNativeFakeServer == 0L) { + throw new IllegalStateException( + "useFakeServer must be called before data verification."); + } + return nativeVerifyEntityCountByTypeAndName(mNativeFakeServerHelperAndroid, + sNativeFakeServer, count, modelType.toString(), name); + } + // Native methods. private native long nativeInit(); private native long nativeCreateFakeServer(long nativeFakeServerHelperAndroid); @@ -120,4 +139,7 @@ long nativeFakeServerHelperAndroid, long nativeFakeServer); private native void nativeDeleteFakeServer( long nativeFakeServerHelperAndroid, long nativeFakeServer); + private native boolean nativeVerifyEntityCountByTypeAndName( + long nativeFakeServerHelperAndroid, long nativeFakeServer, int count, String modelType, + String name); }
diff --git a/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/SyncTest.java b/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/SyncTest.java index 4386426..24c142d 100644 --- a/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/SyncTest.java +++ b/chrome/android/sync_shell/javatests/src/chromium/chrome/browser/sync/SyncTest.java
@@ -23,11 +23,14 @@ import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.JavaScriptUtils; +import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.sync.AndroidSyncSettings; +import org.chromium.sync.internal_api.pub.base.ModelType; import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.sync.signin.ChromeSigninController; import org.chromium.sync.test.util.MockAccountManager; import org.chromium.sync.test.util.MockSyncContentResolverDelegate; +import org.chromium.ui.base.PageTransition; import java.util.concurrent.TimeoutException; @@ -43,6 +46,7 @@ private SyncTestUtil.SyncTestContext mContext; private MockAccountManager mAccountManager; private SyncController mSyncController; + private FakeServerHelper mFakeServerHelper; @Override protected void setUp() throws Exception { @@ -66,6 +70,7 @@ @Override public void run() { mSyncController = SyncController.get(mContext); + mFakeServerHelper = FakeServerHelper.get(); } }); FakeServerHelper.useFakeServer(getInstrumentation().getTargetContext()); @@ -181,6 +186,39 @@ SyncTestUtil.verifySignedInWithAccount(mContext, account); } + @LargeTest + @Feature({"Sync"}) + public void testUploadTypedUrl() throws Exception { + setupTestAccountAndSignInToSync(FOREIGN_SESSION_TEST_MACHINE_ID); + + // TestHttpServerClient is preferred here but it can't be used. The test server + // serves pages on localhost and Chrome doesn't sync localhost URLs as typed URLs. + // This type of URL requires no external data connection or resources. + final String urlToLoad = "data:text,testTypedUrl"; + assertTrue("A typed URL entity for " + urlToLoad + " already exists on the fake server.", + mFakeServerHelper.verifyEntityCountByTypeAndName(0, ModelType.TYPED_URL, + urlToLoad)); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + LoadUrlParams params = new LoadUrlParams(urlToLoad, PageTransition.TYPED); + getActivity().getActiveTab().loadUrl(params); + } + }); + + boolean synced = CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return mFakeServerHelper.verifyEntityCountByTypeAndName(1, ModelType.TYPED_URL, + urlToLoad); + } + }, SyncTestUtil.UI_TIMEOUT_MS, SyncTestUtil.CHECK_INTERVAL_MS); + + assertTrue("The typed URL entity for " + urlToLoad + " was not found on the fake server.", + synced); + } + private void setupTestAccountAndSignInToSync( final String syncClientIdentifier) throws InterruptedException {
diff --git a/chrome/app/android/chrome_main_delegate_android.h b/chrome/app/android/chrome_main_delegate_android.h index b268ab1..450e53a 100644 --- a/chrome/app/android/chrome_main_delegate_android.h +++ b/chrome/app/android/chrome_main_delegate_android.h
@@ -19,13 +19,13 @@ protected: ChromeMainDelegateAndroid(); - virtual ~ChromeMainDelegateAndroid(); + ~ChromeMainDelegateAndroid() override; - virtual bool BasicStartupComplete(int* exit_code) override; + bool BasicStartupComplete(int* exit_code) override; - virtual void SandboxInitialized(const std::string& process_type) override; + void SandboxInitialized(const std::string& process_type) override; - virtual int RunProcess( + int RunProcess( const std::string& process_type, const content::MainFunctionParams& main_function_params) override;
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index b3ecb3bb..4b7a3fe 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -213,6 +213,7 @@ #define IDC_EXTENSIONS_OVERFLOW_MENU 40245 #define IDC_SHOW_SRT_BUBBLE 40246 #define IDC_ELEVATED_RECOVERY_DIALOG 40247 +#define IDC_TAKE_SCREENSHOT 40248 // Spell-check // Insert any additional suggestions before _LAST; these have to be consecutive.
diff --git a/chrome/app/chrome_crash_reporter_client.h b/chrome/app/chrome_crash_reporter_client.h index d3eb42f..9e45ed0 100644 --- a/chrome/app/chrome_crash_reporter_client.h +++ b/chrome/app/chrome_crash_reporter_client.h
@@ -58,7 +58,7 @@ #endif #if defined(OS_ANDROID) - virtual int GetAndroidMinidumpDescriptor() override; + int GetAndroidMinidumpDescriptor() override; #endif #if defined(OS_MACOSX)
diff --git a/chrome/app/chrome_watcher_command_line_unittest_win.cc b/chrome/app/chrome_watcher_command_line_unittest_win.cc index 771094f0..6aac76e 100644 --- a/chrome/app/chrome_watcher_command_line_unittest_win.cc +++ b/chrome/app/chrome_watcher_command_line_unittest_win.cc
@@ -8,24 +8,22 @@ #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/process/process_handle.h" +#include "base/process/process.h" #include "base/win/scoped_handle.h" #include "testing/gtest/include/gtest/gtest.h" TEST(ChromeWatcherCommandLineTest, BasicTest) { - // Ownership of these handles is passed to the ScopedHandles below via - // InterpretChromeWatcherCommandLine(). - base::ProcessHandle current = nullptr; - ASSERT_TRUE(base::OpenProcessHandle(base::GetCurrentProcId(), ¤t)); + base::Process current = base::Process::Open(base::GetCurrentProcId()); + ASSERT_TRUE(current.IsValid()); HANDLE event = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); base::CommandLine cmd_line = GenerateChromeWatcherCommandLine( - base::FilePath(L"example.exe"), current, event); + base::FilePath(L"example.exe"), current.Handle(), event); base::win::ScopedHandle current_result; base::win::ScopedHandle event_result; ASSERT_TRUE(InterpretChromeWatcherCommandLine(cmd_line, ¤t_result, &event_result)); - ASSERT_EQ(current, current_result.Get()); + ASSERT_EQ(current.Handle(), current_result.Get()); ASSERT_EQ(event, event_result.Get()); }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index a3c1b9bb..c7f629f 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -445,6 +445,9 @@ <message name="IDS_FILE_BROWSER_SHARE_BUTTON_LABEL" desc="Menu item label, showing dialog to share the selected file."> Share </message> + <message name="IDS_FILE_BROWSER_CANCEL_SELECTION_BUTTON_LABEL" desc="Label for button that unselects all selected items."> + Cancel selection + </message> <message name="IDS_FILE_BROWSER_CLOUD_IMPORT_BUTTON_LABEL" desc="Label for button that initiates media backup to the cloud."> Import <ph name="FILE_COUNT">$1<ex>5</ex></ph> files to Google Drive </message>
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index b3d3d5d..c44fa8e 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1063,28 +1063,14 @@ You need to be signed in to Chromium to use apps. This allows Chromium to sync your apps, bookmarks, history, passwords and other settings across devices. </message> <if expr="not use_titlecase"> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove from Chromium - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove from Chromium... - </message> - </if> + <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> + Remove from Chromium... + </message> </if> <if expr="use_titlecase"> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove From Chromium - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove From Chromium... - </message> - </if> + <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> + Remove From Chromium... + </message> </if> </if>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 72ac2c8..2d6de4a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -1417,6 +1417,9 @@ <message name="IDS_TASK_MANAGER" desc="The text label of the Task Manager menu item"> &Task manager </message> + <message name="IDS_TAKE_SCREENSHOT" desc="The text label of the Take Screenshot menu item"> + T&ake screenshot + </message> <message name="IDS_RESTORE_TAB" desc="The text label of the Restore Tab menu item"> R&eopen closed tab </message> @@ -1443,6 +1446,9 @@ <message name="IDS_TASK_MANAGER" desc="In Title Case: The text label of the Task Manager menu item"> &Task Manager </message> + <message name="IDS_TAKE_SCREENSHOT" desc="The text label of the Take Screenshot menu item"> + T&ake Screenshot + </message> <message name="IDS_RESTORE_TAB" desc="In Title Case: The text label of the Restore Tab menu item"> R&eopen Closed Tab </message> @@ -2209,20 +2215,35 @@ </if> <!-- "Create application shortcuts" menu item --> + <if expr="is_win"> + <message name="IDS_ADD_TO_TASKBAR" desc="Button text for adding a bookmark app to the taskbar."> + Add to taskbar... + </message> + </if> + <if expr="is_macosx"> + <message name="IDS_ADD_TO_DOCK" desc="Button text for adding a bookmark app to the dock."> + Add to Dock... + </message> + </if> + <if expr="use_ash"> + <message name="IDS_ADD_TO_SHELF" desc="Button text for adding a bookmark app to the shelf."> + Add to shelf... + </message> + </if> <if expr="not use_titlecase"> <message name="IDS_CREATE_SHORTCUTS" desc="Default installation menu label"> Create application &shortcuts... </message> - <message name="IDS_CREATE_HOSTED_APP" desc="Button text for creating a hosted app from the current website"> - Add shortcut to this website... + <message name="IDS_ADD_TO_DESKTOP" desc="Button text for adding a bookmark app to the desktop."> + Add to desktop... </message> </if> <if expr="use_titlecase"> <message name="IDS_CREATE_SHORTCUTS" desc="In Title Case: Default installation menu label"> Create Application &Shortcuts... </message> - <message name="IDS_CREATE_HOSTED_APP" desc="In Title Case: Button text for creating a hosted app from the current website"> - Add Shortcut to this Website... + <message name="IDS_ADD_TO_DESKTOP" desc="Button text for adding a bookmark app to the desktop."> + Add to Desktop... </message> </if> @@ -2864,9 +2885,6 @@ <message name="IDS_CERT_DETAILS_NOT_AFTER" desc="The label of the Validity->Not After element in the details page of the certificate info dialog."> Not After </message> - <message name="IDS_CERT_DETAILS_UTC_TIMEZONE" desc="The string specifying the timezone in the Validity->Not Before and Validity->Not After elements in the details page of the certificate info dialog."> - (UTC) - </message> <message name="IDS_CERT_DETAILS_SUBJECT" desc="The label of the Subject element in the details page of the certificate info dialog. (In this case, subject refers to the entity the certificate was issued to.)"> Subject </message> @@ -4594,6 +4612,9 @@ <message name="IDS_EXTENSION_PROMPT_WARNING_EXPERIENCE_SAMPLING_PRIVATE" desc="Permission string for Experience Sampling Private API."> Monitor when you take actions in Chrome </message> + <message name="IDS_EXTENSION_PROMPT_WARNING_PLATFORMKEYS" desc="Permission string for access to client certificates."> + Use your client certificates + </message> <if expr="is_macosx"> <message name="IDS_EXTENSION_PROMPT_WARNING_INTERCEPT_ALL_KEYS" desc="Permission string for intercept all keyboard keys via packaged app extension APIs"> Read and change anything you type including task switching keys like CMD+TAB @@ -6055,6 +6076,12 @@ Disable user gesture requirement for playing media elements. Activating this will allow autoplay to work. </message> <if expr="use_ash"> + <message name="IDS_FLAGS_ASH_DISABLE_SCREEN_ORIENTATION_LOCK_NAME" desc="Title for the flag which can be used to disable support for javascript locking rotation."> + Disable Screen Orientation locking. + </message> + <message name="IDS_FLAGS_ASH_DISABLE_SCREEN_ORIENTATION_LOCK_DESCRIPTION" desc="Description for the flag which can be used to disable support for javascript locking rotation"> + Disables the ability for javascript to lock the screen orienation. + </message> <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME" desc="Title for the flag which can be used to test the TouchView maximizing mode."> Enable TouchView maximizing UI for testing </message> @@ -6563,11 +6590,11 @@ Do not use Smart Lock, which allows you to unlock your Chromebook when in proximity to your phone. If you are the owner of the device, this also turns off Smart Lock on sign-in screen. </message> </if> - <message name="IDS_FLAGS_ENABLE_NEW_BOOKMARK_APPS_NAME" desc="Name of the flag to enable the new bookmark app system."> - Enable the new bookmark app system. + <message name="IDS_FLAGS_DISABLE_NEW_BOOKMARK_APPS_NAME" desc="Name of the flag to disable the new bookmark app system."> + Disable the new bookmark app system. </message> - <message name="IDS_FLAGS_ENABLE_NEW_BOOKMARK_APPS_DESCRIPTION" desc="Description for the flag to enable the new bookmark app system."> - Enables the new system for creating bookmark apps. + <message name="IDS_FLAGS_DISABLE_NEW_BOOKMARK_APPS_DESCRIPTION" desc="Description for the flag to disable the new bookmark app system."> + Disables the new system for creating bookmark apps. </message> <message name="IDS_FLAGS_ENABLE_HOSTED_APP_SHIM_CREATION_NAME" desc="Name of the flag to enable creation of app shims for hosted apps on Mac."> Enable creation of app shims for hosted apps on Mac. @@ -6678,6 +6705,12 @@ <message name="IDS_FLAGS_OUT_OF_PROCESS_PDF_DESCRIPTION" desc="Description for the flag to enable out of process PDF."> Enable the out of process PDF plugin. </message> + <message name="IDS_FLAGS_PDF_MATERIAL_UI_NAME" desc="Title for the flag to enable the new material UI in the PDF Viewer."> + Enable material UI for PDF. + </message> + <message name="IDS_FLAGS_PDF_MATERIAL_UI_DESCRIPTION" desc="Description for the flag to enable the new material UI in the PDF Viewer."> + Enable the new material UI in the PDF Viewer. + </message> <message name="IDS_FLAGS_DISABLE_THREADED_SCROLLING_NAME" desc="Title for the flag to disable threaded scrolling."> Disable threaded scrolling. </message> @@ -13517,16 +13550,19 @@ <message name="IDS_ABOUT_SANDBOX_SUID_SANDBOX" desc="The name of a type of sandbox used by Chrome on UNIX like systems. The name 'SUID' stands for 'Set User ID', however it's a technical term and may be best left untranslated."> SUID Sandbox </message> - <message name="IDS_ABOUT_SANDBOX_PID_NAMESPACES" desc="This a technical term for an attribute of the SUID sandbox. PID stands for 'Process ID' but, as a technical term, may be best left untranslated. A namespace is another technical term which refers to set of names for objects which are disjoint from the members of all other namespaces."> + <message name="IDS_ABOUT_SANDBOX_NAMESPACE_SANDBOX" desc="The name of a type of sandbox used by Chrome on Linux systems. A namespace is a technical term which refers to set of names for objects which are disjoint from the members of all other namespaces."> + Namespace Sandbox + </message> + <message name="IDS_ABOUT_SANDBOX_PID_NAMESPACES" desc="This a technical term for an attribute of the SUID or namespace sandboxes. PID stands for 'Process ID' but, as a technical term, may be best left untranslated. A namespace is another technical term which refers to set of names for objects which are disjoint from the members of all other namespaces."> PID namespaces </message> - <message name="IDS_ABOUT_SANDBOX_NET_NAMESPACES" desc="This a technical term for an attribute of the SUID sandbox. A namespace is a technical term which refers to set of names for objects which are disjoint from the members of all other namespaces."> + <message name="IDS_ABOUT_SANDBOX_NET_NAMESPACES" desc="This a technical term for an attribute of the SUID or namespace sandboxes. A namespace is a technical term which refers to set of names for objects which are disjoint from the members of all other namespaces."> Network namespaces </message> - <message name="IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX" desc="The name of a type of sandbox used by Chrome on UNIX like systems. 'Seccomp-BPF' is a technical term which should be left untranslated."> + <message name="IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX" desc="The name of a type of sandbox used by Chrome on Linux systems. 'Seccomp-BPF' is a technical term which should be left untranslated."> Seccomp-BPF sandbox </message> - <message name="IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX_TSYNC" desc="The name of a type of sandbox used by Chrome on UNIX like systems. 'Seccomp-BPF' is a technical term which should be left untranslated. TSYNC is a technical term which should be left untranslated."> + <message name="IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX_TSYNC" desc="The name of a type of sandbox used by Chrome on Linux systems. 'Seccomp-BPF' is a technical term which should be left untranslated. TSYNC is a technical term which should be left untranslated."> Seccomp-BPF sandbox supports TSYNC </message> <message name="IDS_ABOUT_SANDBOX_YAMA_LSM" desc="The name of a Linux security module. It is a technical term that should be left untranslated."> @@ -14206,11 +14242,11 @@ Enable IME extensions to supply custom views for user input such as virtual keyboards. </message> - <message name="IDS_FLAGS_ENABLE_NEW_QP_INPUT_VIEW_NAME" desc="Name of about::flags option to enable QP style of input view virtual keyboard."> - Enable QP input view keyboard. + <message name="IDS_FLAGS_ENABLE_NEW_MD_INPUT_VIEW_NAME" desc="Name of about::flags option to enable material style of input view virtual keyboard."> + Enable input view keyboard in material design. </message> - <message name="IDS_FLAGS_ENABLE_NEW_QP_INPUT_VIEW_DESCRIPTION" desc="Description of about::flags option to enable the QP style of input view virtual keyboard."> - Enable input view keyboards in materia design style. + <message name="IDS_FLAGS_ENABLE_NEW_MD_INPUT_VIEW_DESCRIPTION" desc="Description of about::flags option to enable the material style of input view virtual keyboard."> + Enable input view keyboards in material design. </message> <message name="IDS_FLAGS_ENABLE_NEW_KOREAN_IME_NAME" desc="Name of about::flags option to enable the new Korean IME"> @@ -14488,18 +14524,10 @@ <message name="IDS_APP_LIST_CONTEXT_MENU_UNPIN" desc="Title text for the 'unpin' context menu item of an app list item."> Unpin from shelf </message> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_UNINSTALL_ITEM" - desc="Title text for the 'uninstall' context menu item of an app list item."> - Uninstall - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_UNINSTALL_ITEM" - desc="Title text for the 'uninstall' context menu item of an app list item."> - Uninstall... - </message> - </if> + <message name="IDS_APP_LIST_UNINSTALL_ITEM" + desc="Title text for the 'uninstall' context menu item of an app list item."> + Uninstall... + </message> <message name="IDS_SEARCH_BOX_HINT" desc="Hint text for the search box in app list window."> Search </message> @@ -14541,18 +14569,10 @@ <message name="IDS_APP_LIST_CONTEXT_MENU_UNPIN" desc="Title text for the 'unpin' context menu item of an app list item."> Unpin from Shelf </message> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_UNINSTALL_ITEM" - desc="Title text for the 'uninstall' context menu item of an app list item."> - Uninstall - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_UNINSTALL_ITEM" - desc="Title text for the 'uninstall' context menu item of an app list item."> - Uninstall... - </message> - </if> + <message name="IDS_APP_LIST_UNINSTALL_ITEM" + desc="Title text for the 'uninstall' context menu item of an app list item."> + Uninstall... + </message> <message name="IDS_SEARCH_BOX_HINT" desc="Hint text for the search box in app list window."> Search </message> @@ -15010,9 +15030,6 @@ <message name="IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_DESCRIPTION" desc="Description to allow app install alerts"> If enabled, websites will be parsed for app install alert meta tags. </message> - <message name="IDS_APP_INSTALL_ALERTS_ADD_TO_HOMESCREEN" desc="Infobar button text indicating that an app can be added to the home screen."> - Add to homescreen - </message> <!-- Flag strings for seccomp-bpf sandbox flag. --> <message name="IDS_FLAGS_ENABLE_SECCOMP_FILTER_SANDBOX_ANDROID_NAME" desc="Title for the flag to enable the seccomp-bpf sandbox on Android.">
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 957f355..50efc58 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -987,28 +987,14 @@ You need to be signed in to Chrome to use apps. This allows Chrome to sync your apps, bookmarks, history, passwords and other settings across devices. </message> <if expr="not use_titlecase"> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove from Chrome - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove from Chrome... - </message> - </if> + <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="Title text for the context menu item of a non-platform-app app list item that removes the app."> + Remove from Chrome... + </message> </if> <if expr="use_titlecase"> - <if expr="is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove From Chrome - </message> - </if> - <if expr="not is_macosx"> - <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> - Remove From Chrome... - </message> - </if> + <message name="IDS_APP_LIST_EXTENSIONS_UNINSTALL" desc="In Title Case: Title text for the context menu item of a non-platform-app app list item that removes the app."> + Remove From Chrome... + </message> </if> </if>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5a65805e..438728f 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -275,6 +275,7 @@ "//third_party/re2", "//third_party/smhasher:cityhash", "//third_party/webrtc/modules/desktop_capture", + "//ui/base/ime", "//ui/gl", "//ui/surface", "//ui/web_dialogs", @@ -1000,12 +1001,10 @@ "chromeos/input_method/mock_input_method_engine.h", "chromeos/input_method/mock_input_method_manager.cc", "chromeos/input_method/mock_input_method_manager.h", - "chromeos/login/fake_login_utils.cc", - "chromeos/login/fake_login_utils.h", - "chromeos/login/mock_login_utils.cc", - "chromeos/login/mock_login_utils.h", "chromeos/login/screens/mock_device_disabled_screen_actor.cc", "chromeos/login/screens/mock_device_disabled_screen_actor.h", + "chromeos/login/session/user_session_manager_test_api.cc", + "chromeos/login/session/user_session_manager_test_api.h", "chromeos/login/test/oobe_screen_waiter.cc", "chromeos/login/test/oobe_screen_waiter.h", "chromeos/login/test/js_checker.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 09cfc344..bdab68ff 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -160,9 +160,9 @@ # No inclusion of WebKit from the browser, other than strictly enum/POD, # header-only types, and some selected common code. "-third_party/WebKit", - "+third_party/WebKit/public/platform/WebPushPermissionStatus.h", "+third_party/WebKit/public/platform/WebReferrerPolicy.h", "+third_party/WebKit/public/platform/WebScreenOrientationLockType.h", + "+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h", "+third_party/WebKit/public/web/WebCache.h", "+third_party/WebKit/public/web/WebContextMenuData.h", "+third_party/WebKit/public/web/WebFindOptions.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 79c734b7..4347a84 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -932,6 +932,13 @@ kOsCrOS, SINGLE_VALUE_TYPE(ui::switches::kDisableDisplayColorCalibration), }, + { + "ash-disable-screen-orientation-lock", + IDS_FLAGS_ASH_DISABLE_SCREEN_ORIENTATION_LOCK_NAME, + IDS_FLAGS_ASH_DISABLE_SCREEN_ORIENTATION_LOCK_DESCRIPTION, + kOsCrOS, + SINGLE_VALUE_TYPE(ash::switches::kAshDisableScreenOrientationLock), + }, #endif // defined(OS_CHROMEOS) { "disable-accelerated-video-decode", IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_NAME, @@ -1268,11 +1275,11 @@ SINGLE_VALUE_TYPE(chromeos::switches::kEnableNewKoreanIme) }, { - "enable-new-qp-input-view", - IDS_FLAGS_ENABLE_NEW_QP_INPUT_VIEW_NAME, - IDS_FLAGS_ENABLE_NEW_QP_INPUT_VIEW_DESCRIPTION, + "enable-new-md-input-view", + IDS_FLAGS_ENABLE_NEW_MD_INPUT_VIEW_NAME, + IDS_FLAGS_ENABLE_NEW_MD_INPUT_VIEW_DESCRIPTION, kOsCrOS, - SINGLE_VALUE_TYPE(chromeos::switches::kEnableNewQPInputView) + SINGLE_VALUE_TYPE(chromeos::switches::kEnableNewMDInputView) }, { "disable-physical-keyboard-autocorrect", @@ -1513,11 +1520,11 @@ }, #endif { - "enable-new-bookmark-apps", - IDS_FLAGS_ENABLE_NEW_BOOKMARK_APPS_NAME, - IDS_FLAGS_ENABLE_NEW_BOOKMARK_APPS_DESCRIPTION, + "disable-new-bookmark-apps", + IDS_FLAGS_DISABLE_NEW_BOOKMARK_APPS_NAME, + IDS_FLAGS_DISABLE_NEW_BOOKMARK_APPS_DESCRIPTION, kOsWin | kOsCrOS | kOsLinux | kOsMac, - SINGLE_VALUE_TYPE(switches::kEnableNewBookmarkApps) + SINGLE_VALUE_TYPE(switches::kDisableNewBookmarkApps) }, #if defined(OS_MACOSX) { @@ -1717,6 +1724,14 @@ switches::kDisableOutOfProcessPdf) }, { + "enable-pdf-material-ui", + IDS_FLAGS_PDF_MATERIAL_UI_NAME, + IDS_FLAGS_PDF_MATERIAL_UI_DESCRIPTION, + kOsDesktop, + ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePdfMaterialUI, + switches::kDisablePdfMaterialUI) + }, + { "disable-cast-streaming-hw-encoding", IDS_FLAGS_DISABLE_CAST_STREAMING_HW_ENCODING_NAME, IDS_FLAGS_DISABLE_CAST_STREAMING_HW_ENCODING_DESCRIPTION,
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate.cc b/chrome/browser/android/banners/app_banner_infobar_delegate.cc index dfa580f..b32bfa3 100644 --- a/chrome/browser/android/banners/app_banner_infobar_delegate.cc +++ b/chrome/browser/android/banners/app_banner_infobar_delegate.cc
@@ -4,57 +4,58 @@ #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" +#include "base/android/jni_android.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/android/infobars/app_banner_infobar.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_manager.h" -#include "ui/base/l10n/l10n_util.h" namespace banners { -infobars::InfoBar* AppBannerInfoBarDelegate::CreateForWebApp( +// static +AppBannerInfoBar* AppBannerInfoBarDelegate::CreateForNativeApp( infobars::InfoBarManager* infobar_manager, - const AppDelegate* app_delegate, - const base::string16& app_name, - const GURL& url) { + AppDelegate* app_delegate, + const base::android::ScopedJavaGlobalRef<jobject>& japp_data) { scoped_ptr<AppBannerInfoBarDelegate> delegate(new AppBannerInfoBarDelegate( - app_delegate, - app_name, - url)); - - return infobar_manager->AddInfoBar( - make_scoped_ptr(new AppBannerInfoBar(delegate.Pass(), url))); + app_delegate)); + AppBannerInfoBar* infobar = new AppBannerInfoBar(delegate.Pass(), japp_data); + return infobar_manager->AddInfoBar(make_scoped_ptr(infobar)) + ? infobar : nullptr; } -AppBannerInfoBarDelegate::AppBannerInfoBarDelegate( - const AppDelegate* helper, - const base::string16& app_title, - const GURL& url) - : delegate_(helper), - app_title_(app_title), - url_(url), - button_text_(l10n_util::GetStringUTF16( - IDS_APP_INSTALL_ALERTS_ADD_TO_HOMESCREEN)) { +// static +AppBannerInfoBar* AppBannerInfoBarDelegate::CreateForWebApp( + infobars::InfoBarManager* infobar_manager, + AppDelegate* app_delegate, + const GURL& url) { + scoped_ptr<AppBannerInfoBarDelegate> delegate(new AppBannerInfoBarDelegate( + app_delegate)); + AppBannerInfoBar* infobar = new AppBannerInfoBar(delegate.Pass(), url); + return infobar_manager->AddInfoBar(make_scoped_ptr(infobar)) + ? infobar : nullptr; +} + +AppBannerInfoBarDelegate::AppBannerInfoBarDelegate(AppDelegate* app_delegate) + : delegate_(app_delegate) { } AppBannerInfoBarDelegate::~AppBannerInfoBarDelegate() { + DCHECK(delegate_); + delegate_->OnInfoBarDestroyed(); } base::string16 AppBannerInfoBarDelegate::GetMessageText() const { - return app_title_; + DCHECK(delegate_); + return delegate_->GetTitle(); } int AppBannerInfoBarDelegate::GetButtons() const { return BUTTON_OK; } -base::string16 AppBannerInfoBarDelegate::GetButtonLabel(InfoBarButton button) - const { - return button_text_; -} - gfx::Image AppBannerInfoBarDelegate::GetIcon() const { DCHECK(delegate_); return delegate_->GetIcon(); @@ -67,8 +68,12 @@ bool AppBannerInfoBarDelegate::Accept() { DCHECK(delegate_); - delegate_->Install(); - return true; + return delegate_->OnButtonClicked(); +} + +bool AppBannerInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) { + DCHECK(delegate_); + return delegate_->OnLinkClicked(); } } // namespace banners
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate.h b/chrome/browser/android/banners/app_banner_infobar_delegate.h index 01fddc6..252290c 100644 --- a/chrome/browser/android/banners/app_banner_infobar_delegate.h +++ b/chrome/browser/android/banners/app_banner_infobar_delegate.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_INFOBAR_DELEGATE_H_ #define CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_INFOBAR_DELEGATE_H_ +#include "base/android/scoped_java_ref.h" #include "base/strings/string16.h" #include "components/infobars/core/confirm_infobar_delegate.h" #include "ui/gfx/image/image.h" @@ -14,6 +15,8 @@ class InfoBarManager; } // namespace infobars +class AppBannerInfoBar; + namespace banners { // Displays information about an app being promoted by a webpage. @@ -26,26 +29,40 @@ // User has elected to block the banner from being displayed. virtual void Block() const = 0; - // User has requested that the app be installed. - virtual void Install() const = 0; + // User has clicked the button. + // Returns true if the infobar should be dismissed. + virtual bool OnButtonClicked() const = 0; - // Icon to display for the app. + // User has clicked the link. + // Returns true if the infobar should be dismissed. + virtual bool OnLinkClicked() const = 0; + + // Called when the infobar has been destroyed. + virtual void OnInfoBarDestroyed() = 0; + + // Returns the title of the app. + virtual base::string16 GetTitle() const = 0; + + // Returns the icon to display for the app. virtual gfx::Image GetIcon() const = 0; }; - // Creates a banner for the current page. + // Creates a banner for the current page that promotes a native app. // May return nullptr if the the infobar couldn't be created. - static infobars::InfoBar* CreateForWebApp( + static AppBannerInfoBar* CreateForNativeApp( infobars::InfoBarManager* infobar_manager, - const AppDelegate* delegate, - const base::string16& app_title, + AppDelegate* delegate, + const base::android::ScopedJavaGlobalRef<jobject>& japp_data); + + // Creates a banner for the current page that promotes a web app. + // May return nullptr if the the infobar couldn't be created. + static AppBannerInfoBar* CreateForWebApp( + infobars::InfoBarManager* infobar_manager, + AppDelegate* delegate, const GURL& url); ~AppBannerInfoBarDelegate() override; - // Changes the label of the button. - void SetButtonLabel(const std::string& button_text); - // InfoBarDelegate overrides. gfx::Image GetIcon() const override; void InfoBarDismissed() override; @@ -53,19 +70,13 @@ // ConfirmInfoBarDelegate overrides. base::string16 GetMessageText() const override; int GetButtons() const override; - base::string16 GetButtonLabel(InfoBarButton button) const override; bool Accept() override; + bool LinkClicked(WindowOpenDisposition disposition) override; private: - // Constructor for a banner for web apps. - AppBannerInfoBarDelegate(const AppDelegate* helper, - const base::string16& app_title, - const GURL& url); + explicit AppBannerInfoBarDelegate(AppDelegate* delegate); - const AppDelegate* delegate_; - base::string16 app_title_; - GURL url_; - base::string16 button_text_; + AppDelegate* delegate_; DISALLOW_COPY_AND_ASSIGN(AppBannerInfoBarDelegate); }; // AppBannerInfoBarDelegate
diff --git a/chrome/browser/android/banners/app_banner_manager.cc b/chrome/browser/android/banners/app_banner_manager.cc index cbd87921..795afb2 100644 --- a/chrome/browser/android/banners/app_banner_manager.cc +++ b/chrome/browser/android/banners/app_banner_manager.cc
@@ -24,8 +24,12 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" #include "content/public/browser/android/content_view_core.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/service_worker_context.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/frame_navigate_params.h" #include "content/public/common/manifest.h" @@ -35,6 +39,7 @@ #include "ui/gfx/screen.h" using base::android::ConvertJavaStringToUTF8; +using base::android::ConvertJavaStringToUTF16; using base::android::ConvertUTF8ToJavaString; using base::android::ConvertUTF16ToJavaString; @@ -45,7 +50,8 @@ namespace banners { AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj) - : weak_java_banner_view_manager_(env, obj) {} + : weak_java_banner_view_manager_(env, obj), weak_factory_(this) { +} AppBannerManager::~AppBannerManager() { } @@ -63,27 +69,84 @@ GURL url(ConvertJavaStringToUTF8(env, jurl)); std::string package_name = ConvertJavaStringToUTF8(env, jpackage); - AppBannerSettingsHelper::Block(web_contents(), url, package_name); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, package_name, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); } void AppBannerManager::Block() const { - if (!web_contents() || manifest_.IsEmpty()) - return; - - AppBannerSettingsHelper::Block(web_contents(), - web_contents()->GetURL(), - manifest_.start_url.spec()); -} - -void AppBannerManager::Install() const { if (!web_contents()) return; - if (!manifest_.IsEmpty()) { - InstallManifestApp(manifest_, *app_icon_.get()); + if (!native_app_data_.is_null()) { + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), web_contents()->GetURL(), + native_app_package_, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); + } else if (!web_app_data_.IsEmpty()) { + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), web_contents()->GetURL(), + web_app_data_.start_url.spec(), + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); } } +void AppBannerManager::OnInfoBarDestroyed() { + weak_infobar_ptr_ = nullptr; +} + +bool AppBannerManager::OnButtonClicked() const { + if (!web_contents()) + return true; + + if (!native_app_data_.is_null()) { + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); + if (jobj.is_null()) + return true; + + return Java_AppBannerManager_installOrOpenNativeApp(env, + jobj.obj(), + native_app_data_.obj()); + } else if (!web_app_data_.IsEmpty()) { + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), web_contents()->GetURL(), + web_app_data_.start_url.spec(), + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, + base::Time::Now()); + + InstallManifestApp(web_app_data_, *app_icon_.get()); + return true; + } + + return true; +} + +bool AppBannerManager::OnLinkClicked() const { + if (!web_contents()) + return true; + + if (!native_app_data_.is_null()) { + // Try to show the details for the native app. + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); + if (jobj.is_null()) + return true; + + Java_AppBannerManager_showAppDetails(env, + jobj.obj(), + native_app_data_.obj()); + return true; + } else { + // Nothing should happen if the user is installing a web app. + return false; + } +} + +base::string16 AppBannerManager::GetTitle() const { + return app_title_; +} + gfx::Image AppBannerManager::GetIcon() const { return gfx::Image::CreateFrom1xBitmap(*app_icon_.get()); } @@ -101,15 +164,11 @@ const content::FrameNavigateParams& params) { // Clear current state. fetcher_.reset(); - manifest_ = content::Manifest(); + app_title_ = base::string16(); app_icon_.reset(); - - // Get rid of the current banner. - JNIEnv* env = base::android::AttachCurrentThread(); - ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); - if (jobj.is_null()) - return; - Java_AppBannerManager_dismissCurrentBanner(env, jobj.obj(), DISMISS_NAVIGATE); + web_app_data_ = content::Manifest(); + native_app_data_.Reset(); + native_app_package_ = std::string(); } void AppBannerManager::DidFinishLoad( @@ -140,21 +199,59 @@ return; } - // TODO(benwells): Check triggering parameters here and if there is a meta - // tag. + web_app_data_ = manifest; + app_title_ = web_app_data_.name.string(); - // Create an infobar to promote the manifest's app. - manifest_ = manifest; + // Check to see if there is a single service worker controlling this page + // and the manifest's start url. + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + content::StoragePartition* storage_partition = + content::BrowserContext::GetStoragePartition( + profile, web_contents()->GetSiteInstance()); + DCHECK(storage_partition); - GURL icon_url = - ManifestIconSelector::FindBestMatchingIcon( - manifest.icons, - GetPreferredIconSize(), - gfx::Screen::GetScreenFor(web_contents()->GetNativeView())); - if (icon_url.is_empty()) - return; + storage_partition->GetServiceWorkerContext()->CheckHasServiceWorker( + validated_url_, manifest.start_url, + base::Bind(&AppBannerManager::OnDidCheckHasServiceWorker, + weak_factory_.GetWeakPtr())); +} - FetchIcon(icon_url); +void AppBannerManager::OnDidCheckHasServiceWorker(bool has_service_worker) { + if (has_service_worker) { + // TODO(benwells): Check triggering parameters. + // Create an infobar to promote the manifest's app. + GURL icon_url = + ManifestIconSelector::FindBestMatchingIcon( + web_app_data_.icons, + GetPreferredIconSize(), + gfx::Screen::GetScreenFor(web_contents()->GetNativeView())); + if (icon_url.is_empty()) + return; + + FetchIcon(icon_url); + } +} + +void AppBannerManager::RecordCouldShowBanner( + const std::string& package_or_start_url) { + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), validated_url_, package_or_start_url, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, base::Time::Now()); +} + +bool AppBannerManager::CheckIfShouldShow( + const std::string& package_or_start_url) { + if (!AppBannerSettingsHelper::ShouldShowBanner(web_contents(), validated_url_, + package_or_start_url, + base::Time::Now())) { + return false; + } + + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), validated_url_, package_or_start_url, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, base::Time::Now()); + return true; } bool AppBannerManager::OnMessageReceived(const IPC::Message& message) { @@ -168,40 +265,43 @@ } void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) { - if (bitmap) { - JNIEnv* env = base::android::AttachCurrentThread(); - - ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); - if (jobj.is_null()) - return; - - bool displayed; - if (manifest_.IsEmpty()) { - ScopedJavaLocalRef<jobject> jimage = gfx::ConvertToJavaBitmap(bitmap); - ScopedJavaLocalRef<jstring> jimage_url( - ConvertUTF8ToJavaString(env, url.spec())); - - displayed = Java_AppBannerManager_createBanner(env, - jobj.obj(), - jimage_url.obj(), - jimage.obj()); - } else { - app_icon_.reset(new SkBitmap(*bitmap)); - InfoBarService* service = InfoBarService::FromWebContents(web_contents()); - displayed = AppBannerInfoBarDelegate::CreateForWebApp( - service, - this, - manifest_.name.string(), - manifest_.start_url) != NULL; - } - - if (displayed) - banners::TrackDisplayEvent(DISPLAY_CREATED); - } else { + fetcher_.reset(); + if (!bitmap || url != app_icon_url_) { DVLOG(1) << "Failed to retrieve image: " << url; + return; } - fetcher_.reset(); + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); + if (jobj.is_null()) + return; + + app_icon_.reset(new SkBitmap(*bitmap)); + InfoBarService* service = InfoBarService::FromWebContents(web_contents()); + + weak_infobar_ptr_ = nullptr; + if (!native_app_data_.is_null()) { + RecordCouldShowBanner(native_app_package_); + if (!CheckIfShouldShow(native_app_package_)) + return; + + weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForNativeApp( + service, + this, + native_app_data_); + } else if (!web_app_data_.IsEmpty()){ + RecordCouldShowBanner(web_app_data_.start_url.spec()); + if (!CheckIfShouldShow(web_app_data_.start_url.spec())) + return; + + weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForWebApp( + service, + this, + web_app_data_.start_url); + } + + if (weak_infobar_ptr_ != nullptr) + banners::TrackDisplayEvent(DISPLAY_CREATED); } void AppBannerManager::OnDidRetrieveMetaTagContent( @@ -217,12 +317,6 @@ banners::TrackDisplayEvent(DISPLAY_BANNER_REQUESTED); - if (!AppBannerSettingsHelper::IsAllowed(web_contents(), - expected_url, - tag_content)) { - return; - } - // Send the info to the Java side to get info about the app. JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); @@ -233,19 +327,75 @@ ConvertUTF8ToJavaString(env, expected_url.spec())); ScopedJavaLocalRef<jstring> jpackage( ConvertUTF8ToJavaString(env, tag_content)); - Java_AppBannerManager_prepareBanner(env, - jobj.obj(), - jurl.obj(), - jpackage.obj()); + Java_AppBannerManager_fetchAppDetails(env, + jobj.obj(), + jurl.obj(), + jpackage.obj()); } -bool AppBannerManager::FetchIcon(JNIEnv* env, - jobject obj, - jstring jimage_url) { - std::string image_url = ConvertJavaStringToUTF8(env, jimage_url); +bool AppBannerManager::OnAppDetailsRetrieved(JNIEnv* env, + jobject obj, + jobject japp_data, + jstring japp_title, + jstring japp_package, + jstring jicon_url) { + if (validated_url_ != web_contents()->GetURL()) + return false; + + std::string image_url = ConvertJavaStringToUTF8(env, jicon_url); + app_title_ = ConvertJavaStringToUTF16(env, japp_title); + native_app_package_ = ConvertJavaStringToUTF8(env, japp_package); + native_app_data_.Reset(env, japp_data); return FetchIcon(GURL(image_url)); } +void AppBannerManager::OnInstallIntentReturned(JNIEnv* env, + jobject obj, + jboolean jis_installing) { + if (!weak_infobar_ptr_) + return; + + if (jis_installing) { + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), + web_contents()->GetURL(), + native_app_package_, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, + base::Time::Now()); + } + + UpdateInstallState(env, obj); +} + +void AppBannerManager::OnInstallFinished(JNIEnv* env, + jobject obj, + jboolean success) { + if (!weak_infobar_ptr_) + return; + + if (success) { + UpdateInstallState(env, obj); + } else { + InfoBarService* service = InfoBarService::FromWebContents(web_contents()); + service->RemoveInfoBar(weak_infobar_ptr_); + } +} + +void AppBannerManager::UpdateInstallState(JNIEnv* env, jobject obj) { + if (!weak_infobar_ptr_ || native_app_data_.is_null()) + return; + + ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); + if (jobj.is_null()) + return; + + int newState = Java_AppBannerManager_determineInstallState( + env, + jobj.obj(), + native_app_data_.obj()); + weak_infobar_ptr_->OnInstallStateChanged(newState); +} + bool AppBannerManager::FetchIcon(const GURL& image_url) { if (!web_contents()) return false; @@ -259,6 +409,7 @@ std::string(), net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, net::LOAD_NORMAL); + app_icon_url_ = image_url; return true; }
diff --git a/chrome/browser/android/banners/app_banner_manager.h b/chrome/browser/android/banners/app_banner_manager.h index 12ae72a3..ca616fa5 100644 --- a/chrome/browser/android/banners/app_banner_manager.h +++ b/chrome/browser/android/banners/app_banner_manager.h
@@ -7,9 +7,13 @@ #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" +#include "chrome/browser/ui/android/infobars/app_banner_infobar.h" +#include "components/infobars/core/infobar_manager.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/manifest.h" @@ -19,6 +23,10 @@ struct Manifest; } // namespace content +namespace infobars { +class InfoBar; +} // namspace infobars + /** * Manages when an app banner is created or dismissed. * @@ -77,11 +85,25 @@ jobject obj, jobject jweb_contents); - // Fetches the icon at the given URL asynchronously. - // Returns |false| if this couldn't be kicked off. - bool FetchIcon(JNIEnv* env, - jobject obj, - jstring jimage_url); + // Called when the Java-side has retrieved information for the app. + // Returns |false| if an icon fetch couldn't be kicked off. + bool OnAppDetailsRetrieved(JNIEnv* env, + jobject obj, + jobject japp_data, + jstring japp_title, + jstring japp_package, + jstring jicon_url); + + // Called when the installation Intent has been handled and focus has been + // returned to Chrome. + void OnInstallIntentReturned(JNIEnv* env, + jobject obj, + jboolean jis_installing); + + // Called when the InstallerDelegate task has finished. + void OnInstallFinished(JNIEnv* env, + jobject obj, + jboolean success); // Fetches the icon at the given URL asynchronously. // Returns |false| if this couldn't be kicked off. @@ -92,6 +114,9 @@ static void InstallManifestApp(const content::Manifest& manifest, const SkBitmap& icon); + // Called when the AppBannerInfoBar's button needs to be updated. + void UpdateInstallState(JNIEnv* env, jobject obj); + // WebContentsObserver overrides. void DidNavigateMainFrame( const content::LoadCommittedDetails& details, @@ -105,7 +130,10 @@ // AppBannerInfoBarDelegate::AppDelegate overrides. void Block() const override; - void Install() const override; + bool OnButtonClicked() const override; + bool OnLinkClicked() const override; + void OnInfoBarDestroyed() override; + base::string16 GetTitle() const override; gfx::Image GetIcon() const override; private: @@ -125,15 +153,40 @@ const std::string& tag_content, const GURL& expected_url); + // Called when the result of the CheckHasServiceWorker query has completed. + void OnDidCheckHasServiceWorker(bool has_service_worker); + + // Record that the banner could be shown at this point, if the triggering + // heuristic allowed. + void RecordCouldShowBanner(const std::string& package_or_start_url); + + // Check if the banner should be shown. + bool CheckIfShouldShow(const std::string& package_or_start_url); + // Fetches the icon for an app. scoped_ptr<chrome::BitmapFetcher> fetcher_; GURL validated_url_; - content::Manifest manifest_; + GURL app_icon_url_; + + base::string16 app_title_; scoped_ptr<SkBitmap> app_icon_; + content::Manifest web_app_data_; + + base::android::ScopedJavaGlobalRef<jobject> native_app_data_; + std::string native_app_package_; + + // Weak pointer to the InfoBar that is being managed. + AppBannerInfoBar* weak_infobar_ptr_; + // AppBannerManager on the Java side. JavaObjectWeakGlobalRef weak_java_banner_view_manager_; + // A weak pointer is used as the lifetime of the ServiceWorkerContext is + // longer than the lifetime of this banner manager. The banner manager + // might be gone when calls sent to the ServiceWorkerContext are completed. + base::WeakPtrFactory<AppBannerManager> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(AppBannerManager); }; // class AppBannerManager
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.cc b/chrome/browser/android/bookmarks/bookmarks_bridge.cc index 5dbf6dd..7712383 100644 --- a/chrome/browser/android/bookmarks/bookmarks_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmarks_bridge.cc
@@ -43,6 +43,8 @@ using bookmarks::android::JavaBookmarkIdGetId; using bookmarks::android::JavaBookmarkIdGetType; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; using bookmarks::BookmarkType; using content::BrowserThread;
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.h b/chrome/browser/android/bookmarks/bookmarks_bridge.h index 8a283e8..cfe94e0 100644 --- a/chrome/browser/android/bookmarks/bookmarks_bridge.h +++ b/chrome/browser/android/bookmarks/bookmarks_bridge.h
@@ -149,27 +149,28 @@ void EndGroupingUndos(JNIEnv* env, jobject obj); - base::string16 GetTitle(const BookmarkNode* node) const; + base::string16 GetTitle(const bookmarks::BookmarkNode* node) const; private: ~BookmarksBridge() override; base::android::ScopedJavaLocalRef<jobject> CreateJavaBookmark( - const BookmarkNode* node); - void ExtractBookmarkNodeInformation( - const BookmarkNode* node, - jobject j_result_obj); - const BookmarkNode* GetNodeByID(long node_id, int type); - const BookmarkNode* GetFolderWithFallback(long folder_id, int type); + const bookmarks::BookmarkNode* node); + void ExtractBookmarkNodeInformation(const bookmarks::BookmarkNode* node, + jobject j_result_obj); + const bookmarks::BookmarkNode* GetNodeByID(long node_id, int type); + const bookmarks::BookmarkNode* GetFolderWithFallback(long folder_id, + int type); // Returns whether |node| can be modified by the user. - bool IsEditable(const BookmarkNode* node) const; + bool IsEditable(const bookmarks::BookmarkNode* node) const; // Returns whether |node| is a managed bookmark. - bool IsManaged(const BookmarkNode* node) const; - const BookmarkNode* GetParentNode(const BookmarkNode* node); - int GetBookmarkType(const BookmarkNode* node); - bool IsReachable(const BookmarkNode* node) const; + bool IsManaged(const bookmarks::BookmarkNode* node) const; + const bookmarks::BookmarkNode* GetParentNode( + const bookmarks::BookmarkNode* node); + int GetBookmarkType(const bookmarks::BookmarkNode* node); + bool IsReachable(const bookmarks::BookmarkNode* node) const; bool IsLoaded() const; - bool IsFolderAvailable(const BookmarkNode* folder) const; + bool IsFolderAvailable(const bookmarks::BookmarkNode* folder) const; void NotifyIfDoneLoading(); // Override bookmarks::BaseBookmarkModelObserver. @@ -181,24 +182,25 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void ExtensiveBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override; void ExtensiveBookmarkChangesEnded(bookmarks::BookmarkModel* model) override;
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc b/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc index 1434b6a..4be9c0ea 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc
@@ -24,6 +24,8 @@ using base::android::AttachCurrentThread; using base::android::CheckException; using base::android::ConvertJavaStringToUTF16; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; using content::BrowserThread; namespace {
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_reader.h b/chrome/browser/android/bookmarks/partner_bookmarks_reader.h index 953f220..66fbe7ba 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_reader.h +++ b/chrome/browser/android/bookmarks/partner_bookmarks_reader.h
@@ -41,7 +41,7 @@ Profile* profile_; // JNI - scoped_ptr<BookmarkNode> wip_partner_bookmarks_root_; + scoped_ptr<bookmarks::BookmarkNode> wip_partner_bookmarks_root_; int64 wip_next_available_id_; DISALLOW_COPY_AND_ASSIGN(PartnerBookmarksReader);
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc index cc395a1..565e723e 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc
@@ -14,6 +14,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +using bookmarks::BookmarkNode; using content::BrowserThread; namespace {
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim.h b/chrome/browser/android/bookmarks/partner_bookmarks_shim.h index cddfb02..6acab0e 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim.h +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim.h
@@ -53,17 +53,18 @@ // Returns true if a given bookmark is reachable (i.e. neither the bookmark, // nor any of its parents were "removed"). - bool IsReachable(const BookmarkNode* node) const; + bool IsReachable(const bookmarks::BookmarkNode* node) const; // Returns true if a given node is editable and if editing is allowed. - bool IsEditable(const BookmarkNode* node) const; + bool IsEditable(const bookmarks::BookmarkNode* node) const; // Removes a given bookmark. // Makes the |node| (and, consequently, all its children) unreachable. - void RemoveBookmark(const BookmarkNode* node); + void RemoveBookmark(const bookmarks::BookmarkNode* node); // Renames a given bookmark. - void RenameBookmark(const BookmarkNode* node, const base::string16& title); + void RenameBookmark(const bookmarks::BookmarkNode* node, + const base::string16& title); // For Loaded/Changed/ShimBeingDeleted notifications class Observer { @@ -82,15 +83,15 @@ void RemoveObserver(Observer* observer); // PartnerBookmarksShim versions of BookmarkModel/BookmarkNode methods - const BookmarkNode* GetNodeByID(int64 id) const; - base::string16 GetTitle(const BookmarkNode* node) const; + const bookmarks::BookmarkNode* GetNodeByID(int64 id) const; + base::string16 GetTitle(const bookmarks::BookmarkNode* node) const; - bool IsPartnerBookmark(const BookmarkNode* node) const; - const BookmarkNode* GetPartnerBookmarksRoot() const; + bool IsPartnerBookmark(const bookmarks::BookmarkNode* node) const; + const bookmarks::BookmarkNode* GetPartnerBookmarksRoot() const; // Sets the root node of the partner bookmarks and notifies any observers that // the shim has now been loaded. Takes ownership of |root_node|. - void SetPartnerBookmarksRoot(BookmarkNode* root_node); + void SetPartnerBookmarksRoot(bookmarks::BookmarkNode* root_node); // Used as a "unique" identifier of the partner bookmark node for the purposes // of node deletion and title editing. Two bookmarks with the same URLs and @@ -123,11 +124,13 @@ explicit PartnerBookmarksShim(PrefService* prefs); ~PartnerBookmarksShim() override; - const BookmarkNode* GetNodeByID(const BookmarkNode* parent, int64 id) const; + const bookmarks::BookmarkNode* GetNodeByID( + const bookmarks::BookmarkNode* parent, + int64 id) const; void ReloadNodeMapping(); void SaveNodeMapping(); - scoped_ptr<BookmarkNode> partner_bookmarks_root_; + scoped_ptr<bookmarks::BookmarkNode> partner_bookmarks_root_; PrefService* prefs_; NodeRenamingMap node_rename_remove_map_;
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc index ecafdbd..26bdb0c 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
@@ -18,6 +18,8 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; using testing::_; class MockObserver : public PartnerBookmarksShim::Observer {
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index 584af842..71cc0065 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/android/dev_tools_server.h" #include "chrome/browser/android/dom_distiller/feedback_reporter_android.h" #include "chrome/browser/android/download/chrome_download_delegate.h" -#include "chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h" #include "chrome/browser/android/favicon_helper.h" #include "chrome/browser/android/feature_utilities.h" #include "chrome/browser/android/find_in_page/find_in_page_bridge.h" @@ -57,6 +56,7 @@ #include "chrome/browser/autofill/android/personal_data_manager_android.h" #include "chrome/browser/dom_distiller/dom_distiller_service_factory_android.h" #include "chrome/browser/dom_distiller/tab_utils_android.h" +#include "chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h" #include "chrome/browser/history/android/sqlite_cursor.h" #include "chrome/browser/invalidation/invalidation_service_factory_android.h" #include "chrome/browser/lifetime/application_lifetime_android.h"
diff --git a/chrome/browser/android/enhanced_bookmarks/OWNERS b/chrome/browser/android/enhanced_bookmarks/OWNERS deleted file mode 100644 index e368087..0000000 --- a/chrome/browser/android/enhanced_bookmarks/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -kkimlabs@chromium.org
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc index ac0351c..ddcb6263 100644 --- a/chrome/browser/android/logo_service.cc +++ b/chrome/browser/android/logo_service.cc
@@ -31,11 +31,8 @@ GURL GetGoogleDoodleURL(Profile* profile) { GURL google_base_url(UIThreadSearchTermsData(profile).GoogleBaseURLValue()); const char kGoogleDoodleURLPath[] = "async/newtab_mobile"; - // The string passed to SetPathStr() must stay alive until after - // ReplaceComponents(), so declare it on the stack here instead of inline. - std::string path(kGoogleDoodleURLPath); GURL::Replacements replacements; - replacements.SetPathStr(path); + replacements.SetPathStr(kGoogleDoodleURLPath); return google_base_url.ReplaceComponents(replacements); }
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.cc b/chrome/browser/android/provider/bookmark_model_observer_task.cc index 94d4edd..2e20366 100644 --- a/chrome/browser/android/provider/bookmark_model_observer_task.cc +++ b/chrome/browser/android/provider/bookmark_model_observer_task.cc
@@ -8,6 +8,7 @@ #include "content/public/browser/browser_thread.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; BookmarkModelTask::BookmarkModelTask(BookmarkModel* model)
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.h b/chrome/browser/android/provider/bookmark_model_observer_task.h index eeb644d..2746d24 100644 --- a/chrome/browser/android/provider/bookmark_model_observer_task.h +++ b/chrome/browser/android/provider/bookmark_model_observer_task.h
@@ -34,26 +34,27 @@ void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; private: DISALLOW_COPY_AND_ASSIGN(BookmarkModelObserverTask);
diff --git a/chrome/browser/android/provider/chrome_browser_provider.cc b/chrome/browser/android/provider/chrome_browser_provider.cc index 6191d63..05667a7 100644 --- a/chrome/browser/android/provider/chrome_browser_provider.cc +++ b/chrome/browser/android/provider/chrome_browser_provider.cc
@@ -58,6 +58,7 @@ using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; // After refactoring the following class hierarchy has been created in order @@ -298,7 +299,9 @@ static void RunOnUIThread(BookmarkModel* model) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + LOG(ERROR) << "begin model->RemoveAllUserBookmarks"; model->RemoveAllUserBookmarks(); + LOG(ERROR) << "after model->RemoveAllUserBookmarks"; } private: @@ -1515,8 +1518,10 @@ } void ChromeBrowserProvider::RemoveAllUserBookmarks(JNIEnv* env, jobject obj) { + LOG(ERROR) << "begin ChromeBrowserProvider::RemoveAllUserBookmarks"; RemoveAllUserBookmarksTask task(bookmark_model_); task.Run(); + LOG(ERROR) << "end ChromeBrowserProvider::RemoveAllUserBookmarks"; } ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetBookmarkNode(
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc index c640492..73824451 100644 --- a/chrome/browser/apps/app_browsertest.cc +++ b/chrome/browser/apps/app_browsertest.cc
@@ -411,8 +411,7 @@ GURL set_cookie_url = embedded_test_server()->GetURL( "/extensions/platform_apps/isolation/set_cookie.html"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); set_cookie_url = set_cookie_url.ReplaceComponents(replace_host); ui_test_utils::NavigateToURL(browser(), set_cookie_url);
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index b875bcc..a7ef8be 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -355,8 +355,7 @@ content::WebContents** persistent_partition_contents2, content::WebContents** persistent_partition_contents3) { GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); navigate_to_url = navigate_to_url.ReplaceComponents(replace_host); @@ -624,8 +623,7 @@ content::WebContents* LoadGuest(const std::string& guest_path, const std::string& app_path) { GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL guest_url = embedded_test_server()->GetURL(guest_path); guest_url = guest_url.ReplaceComponents(replace_host); @@ -1205,8 +1203,7 @@ ASSERT_TRUE(embedder_web_contents); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); std::string guest_path( "/extensions/platform_apps/web_view/shim/empty_guest.html"); @@ -1396,8 +1393,7 @@ "document.cookie = 'guest2=true; path=/; expires=' + expire + ';';"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL set_cookie_url = embedded_test_server()->GetURL( "/extensions/platform_apps/isolation/set_cookie.html");
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc index 69ed5348..427c463 100644 --- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -293,8 +293,7 @@ const std::string& guest_url_spec) { ASSERT_TRUE(StartEmbeddedTestServer()); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL guest_url = embedded_test_server()->GetURL(guest_url_spec); guest_url = guest_url.ReplaceComponents(replace_host);
diff --git a/chrome/browser/autocomplete/bookmark_provider.cc b/chrome/browser/autocomplete/bookmark_provider.cc index c1926ec..297089d 100644 --- a/chrome/browser/autocomplete/bookmark_provider.cc +++ b/chrome/browser/autocomplete/bookmark_provider.cc
@@ -25,6 +25,7 @@ #include "url/url_constants.h" using bookmarks::BookmarkMatch; +using bookmarks::BookmarkNode; typedef std::vector<BookmarkMatch> BookmarkMatches;
diff --git a/chrome/browser/autocomplete/bookmark_provider_unittest.cc b/chrome/browser/autocomplete/bookmark_provider_unittest.cc index e3738fc..4afa6be 100644 --- a/chrome/browser/autocomplete/bookmark_provider_unittest.cc +++ b/chrome/browser/autocomplete/bookmark_provider_unittest.cc
@@ -25,6 +25,7 @@ using bookmarks::BookmarkMatch; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // The bookmark corpus against which we will simulate searches. struct BookmarksTestInfo {
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc index 975d7421..1aa5e686 100644 --- a/chrome/browser/autofill/autofill_browsertest.cc +++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -53,6 +53,8 @@ namespace autofill { +// TODO(bondd): PdmChangeWaiter in autofill_uitest_util.cc is a replacement for +// this class. Remove this class and use helper functions in that file instead. class WindowedPersonalDataManagerObserver : public PersonalDataManagerObserver, public infobars::InfoBarManager::Observer {
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index 379b449..684731e0 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -15,13 +15,12 @@ #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" +#include "chrome/browser/autofill/autofill_uitest_util.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/translate/translate_service.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/render_messages.h" @@ -35,12 +34,8 @@ #include "components/autofill/core/browser/autofill_manager_test_delegate.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" -#include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill/core/browser/validation.h" -#include "components/infobars/core/confirm_infobar_delegate.h" #include "components/infobars/core/infobar.h" -#include "components/infobars/core/infobar_manager.h" #include "components/translate/core/browser/translate_infobar_delegate.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_observer.h" @@ -51,7 +46,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_renderer_host.h" -#include "content/public/test/test_utils.h" #include "net/url_request/test_url_fetcher_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -132,67 +126,6 @@ DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); }; - -// WindowedPersonalDataManagerObserver ---------------------------------------- - -class WindowedPersonalDataManagerObserver - : public PersonalDataManagerObserver, - public infobars::InfoBarManager::Observer { - public: - explicit WindowedPersonalDataManagerObserver(Browser* browser) - : alerted_(false), - has_run_message_loop_(false), - browser_(browser), - infobar_service_(InfoBarService::FromWebContents( - browser_->tab_strip_model()->GetActiveWebContents())) { - PersonalDataManagerFactory::GetForProfile(browser_->profile())-> - AddObserver(this); - infobar_service_->AddObserver(this); - } - - ~WindowedPersonalDataManagerObserver() override { - while (infobar_service_->infobar_count() > 0) { - infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0)); - } - infobar_service_->RemoveObserver(this); - } - - // PersonalDataManagerObserver: - void OnPersonalDataChanged() override { - if (has_run_message_loop_) { - base::MessageLoopForUI::current()->Quit(); - has_run_message_loop_ = false; - } - alerted_ = true; - } - - void OnInsufficientFormData() override { OnPersonalDataChanged(); } - - - void Wait() { - if (!alerted_) { - has_run_message_loop_ = true; - content::RunMessageLoop(); - } - PersonalDataManagerFactory::GetForProfile(browser_->profile())-> - RemoveObserver(this); - } - - private: - // infobars::InfoBarManager::Observer: - void OnInfoBarAdded(infobars::InfoBar* infobar) override { - infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()-> - Accept(); - } - - bool alerted_; - bool has_run_message_loop_; - Browser* browser_; - InfoBarService* infobar_service_; - - DISALLOW_COPY_AND_ASSIGN(WindowedPersonalDataManagerObserver); -}; - // AutofillInteractiveTest ---------------------------------------------------- class AutofillInteractiveTest : public InProcessBrowserTest { @@ -234,10 +167,6 @@ autofill_manager->client()->HideAutofillPopup(); } - PersonalDataManager* GetPersonalDataManager() { - return PersonalDataManagerFactory::GetForProfile(browser()->profile()); - } - content::WebContents* GetWebContents() { return browser()->tab_strip_model()->GetActiveWebContents(); } @@ -253,24 +182,7 @@ "red.swingline@initech.com", "Initech", "4120 Freidrich Lane", "Basement", "Austin", "Texas", "78744", "US", "5125551234"); - WindowedPersonalDataManagerObserver observer(browser()); - GetPersonalDataManager()->AddProfile(profile); - - // AddProfile is asynchronous. Wait for it to finish before continuing the - // tests. - observer.Wait(); - } - - void SetProfiles(std::vector<AutofillProfile>* profiles) { - WindowedPersonalDataManagerObserver observer(browser()); - GetPersonalDataManager()->SetProfiles(profiles); - observer.Wait(); - } - - void SetProfile(const AutofillProfile& profile) { - std::vector<AutofillProfile> profiles; - profiles.push_back(profile); - SetProfiles(&profiles); + AddTestProfile(browser(), profile); } // Populates a webpage form using autofill data and keypress events. @@ -1236,7 +1148,7 @@ profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA")); profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("95110")); profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("1-408-555-4567")); - SetProfile(profile); + SetTestProfile(browser(), profile); GURL url = test_server()->GetURL("files/autofill/form_phones.html"); ui_test_utils::NavigateToURL(browser(), url); @@ -1277,7 +1189,7 @@ profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("95110")); profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Company X")); profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("408-871-4567")); - SetProfile(profile); + SetTestProfile(browser(), profile); GURL url = test_server()->GetURL("files/autofill/read_only_field_test.html"); ui_test_utils::NavigateToURL(browser(), url); @@ -1348,7 +1260,7 @@ profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16(email)); profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("4088714567")); - SetProfile(profile); + SetTestProfile(browser(), profile); GURL url = test_server()->GetURL( "files/autofill/autofill_confirmemail_form.html"); @@ -1407,7 +1319,7 @@ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US")); profiles.push_back(profile); } - SetProfiles(&profiles); + SetTestProfiles(browser(), &profiles); // TODO(isherman): once we're sure this test doesn't timeout on any bots, this // can be removd. LOG(INFO) << "Created " << kNumProfiles << " profiles in " <<
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc index af8a332..108011f 100644 --- a/chrome/browser/autofill/autofill_server_browsertest.cc +++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -26,8 +26,8 @@ namespace autofill { namespace { -// TODO(isherman): Similar classes are defined in a few other Autofill browser -// tests. It would be good to factor out the shared code into a helper file. +// TODO(bondd): PdmChangeWaiter in autofill_uitest_util.cc is a replacement for +// this class. Remove this class and use helper functions in that file instead. class WindowedPersonalDataManagerObserver : public PersonalDataManagerObserver { public: explicit WindowedPersonalDataManagerObserver(Profile* profile)
diff --git a/chrome/browser/autofill/autofill_uitest_util.cc b/chrome/browser/autofill/autofill_uitest_util.cc new file mode 100644 index 0000000..85e560d --- /dev/null +++ b/chrome/browser/autofill/autofill_uitest_util.cc
@@ -0,0 +1,104 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/autofill/autofill_uitest_util.h" +#include "chrome/browser/autofill/personal_data_manager_factory.h" +#include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/personal_data_manager_observer.h" +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_manager.h" +#include "content/public/test/test_utils.h" + +namespace autofill { + +// This class is used to wait for asynchronous updates to PersonalDataManager +// to complete. +class PdmChangeWaiter + : public PersonalDataManagerObserver, + public infobars::InfoBarManager::Observer { + public: + explicit PdmChangeWaiter(Browser* browser) + : alerted_(false), + has_run_message_loop_(false), + browser_(browser), + infobar_service_(InfoBarService::FromWebContents( + browser_->tab_strip_model()->GetActiveWebContents())) { + PersonalDataManagerFactory::GetForProfile(browser_->profile())-> + AddObserver(this); + infobar_service_->AddObserver(this); + } + + ~PdmChangeWaiter() override { + while (infobar_service_->infobar_count() > 0) { + infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0)); + } + infobar_service_->RemoveObserver(this); + } + + // PersonalDataManagerObserver: + void OnPersonalDataChanged() override { + if (has_run_message_loop_) { + base::MessageLoopForUI::current()->Quit(); + has_run_message_loop_ = false; + } + alerted_ = true; + } + + void OnInsufficientFormData() override { OnPersonalDataChanged(); } + + + void Wait() { + if (!alerted_) { + has_run_message_loop_ = true; + content::RunMessageLoop(); + } + PersonalDataManagerFactory::GetForProfile(browser_->profile())-> + RemoveObserver(this); + } + + private: + // infobars::InfoBarManager::Observer: + void OnInfoBarAdded(infobars::InfoBar* infobar) override { + infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()-> + Accept(); + } + + bool alerted_; + bool has_run_message_loop_; + Browser* browser_; + InfoBarService* infobar_service_; + + DISALLOW_COPY_AND_ASSIGN(PdmChangeWaiter); +}; + +static PersonalDataManager* GetPersonalDataManager(Profile* profile) { + return PersonalDataManagerFactory::GetForProfile(profile); +} + +void AddTestProfile(Browser* browser, const AutofillProfile& profile) { + PdmChangeWaiter observer(browser); + GetPersonalDataManager(browser->profile())->AddProfile(profile); + + // AddProfile is asynchronous. Wait for it to finish before continuing the + // tests. + observer.Wait(); +} + +void SetTestProfile(Browser* browser, const AutofillProfile& profile) { + std::vector<AutofillProfile> profiles; + profiles.push_back(profile); + SetTestProfiles(browser, &profiles); +} + +void SetTestProfiles(Browser* browser, std::vector<AutofillProfile>* profiles) { + PdmChangeWaiter observer(browser); + GetPersonalDataManager(browser->profile())->SetProfiles(profiles); + observer.Wait(); +} + +} // namespace autofill
diff --git a/chrome/browser/autofill/autofill_uitest_util.h b/chrome/browser/autofill/autofill_uitest_util.h new file mode 100644 index 0000000..dc4fe6b --- /dev/null +++ b/chrome/browser/autofill/autofill_uitest_util.h
@@ -0,0 +1,22 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_UITEST_UTIL_H_ +#define CHROME_BROWSER_AUTOFILL_AUTOFILL_UITEST_UTIL_H_ + +#include <vector> + +class Browser; + +namespace autofill { + +class AutofillProfile; + +void AddTestProfile(Browser* browser, const AutofillProfile& profile); +void SetTestProfile(Browser* browser, const AutofillProfile& profile); +void SetTestProfiles(Browser* browser, std::vector<AutofillProfile>* profiles); + +} // namespace autofill + +#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_UITEST_UTIL_H_
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc index 361107b..503b422c 100644 --- a/chrome/browser/background/background_contents_service.cc +++ b/chrome/browser/background/background_contents_service.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/strings/string_util.h" @@ -343,10 +344,13 @@ const content::NotificationDetails& details) { switch (type) { case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: { + const base::TimeTicks start_time = base::TimeTicks::Now(); Profile* profile = content::Source<Profile>(source).ptr(); LoadBackgroundContentsFromManifests(profile); LoadBackgroundContentsFromPrefs(profile); SendChangeNotification(profile); + UMA_HISTOGRAM_TIMES("Extensions.BackgroundContentsServiceStartupTime", + base::TimeTicks::Now() - start_time); break; } case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED:
diff --git a/chrome/browser/banners/app_banner_settings_helper.cc b/chrome/browser/banners/app_banner_settings_helper.cc index 40632dc6..1847f50 100644 --- a/chrome/browser/banners/app_banner_settings_helper.cc +++ b/chrome/browser/banners/app_banner_settings_helper.cc
@@ -23,21 +23,28 @@ // Oldest could show banner event we care about, in days. const unsigned int kOldestCouldShowBannerEventInDays = 14; -// Dictionary key to use for the 'could show banner' events. -const char kCouldShowBannerEventsKey[] = "couldShowBannerEvents"; +// Number of times that the banner could have been shown before the banner will +// actually be triggered. +const unsigned int kCouldShowEventsToTrigger = 2; + +// Number of days that showing the banner will prevent it being seen again for. +const unsigned int kMinimumDaysBetweenBannerShows = 60; + +// Number of days that the banner being blocked will prevent it being seen again +// for. +const unsigned int kMinimumBannerBlockedToBannerShown = 90; + +// Dictionary keys to use for the events. +const char* kBannerEventKeys[] = { + "couldShowBannerEvents", + "didShowBannerEvent", + "didBlockBannerEvent", + "didAddToHomescreenEvent", +}; // Dictionary key to use whether the banner has been blocked. const char kHasBlockedKey[] = "hasBlocked"; -base::Time DateFromTime(base::Time time) { - base::Time::Exploded exploded; - time.LocalExplode(&exploded); - exploded.hour = 0; - exploded.minute = 0; - exploded.second = 0; - return base::Time::FromLocalExploded(exploded); -} - scoped_ptr<base::DictionaryValue> GetOriginDict( HostContentSettingsMap* settings, const GURL& origin_url) { @@ -72,10 +79,11 @@ } // namespace -void AppBannerSettingsHelper::RecordCouldShowBannerEvent( +void AppBannerSettingsHelper::RecordBannerEvent( content::WebContents* web_contents, const GURL& origin_url, const std::string& package_name_or_start_url, + AppBannerEvent event, base::Time time) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); @@ -99,50 +107,92 @@ if (!app_dict) return; - base::ListValue* could_show_list = nullptr; - if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) { - could_show_list = new base::ListValue(); - app_dict->Set(kCouldShowBannerEventsKey, make_scoped_ptr(could_show_list)); - } + std::string event_key(kBannerEventKeys[event]); - // Trim any items that are older than we should care about. For comparisons - // the times are converted to local dates. - base::Time date = DateFromTime(time); - base::ValueVector::iterator it = could_show_list->begin(); - while (it != could_show_list->end()) { - if ((*it)->IsType(base::Value::TYPE_DOUBLE)) { - double internal_date; - (*it)->GetAsDouble(&internal_date); - base::Time other_date = - DateFromTime(base::Time::FromInternalValue(internal_date)); - // This date has already been added. Don't add the date again, and don't - // bother trimming values as it will have been done the first time the - // date was added (unless the local date has changed, which we can live - // with). - if (other_date == date) - return; - - base::TimeDelta delta = date - other_date; - if (delta < - base::TimeDelta::FromDays(kOldestCouldShowBannerEventInDays)) { - ++it; - continue; - } + if (event == APP_BANNER_EVENT_COULD_SHOW) { + base::ListValue* could_show_list = nullptr; + if (!app_dict->GetList(event_key, &could_show_list)) { + could_show_list = new base::ListValue(); + app_dict->Set(event_key, make_scoped_ptr(could_show_list)); } - // Either this date is older than we care about, or it isn't a date, so - // remove it; - it = could_show_list->Erase(it, nullptr); - } + // Trim any items that are older than we should care about. For comparisons + // the times are converted to local dates. + base::Time date = time.LocalMidnight(); + base::ValueVector::iterator it = could_show_list->begin(); + while (it != could_show_list->end()) { + if ((*it)->IsType(base::Value::TYPE_DOUBLE)) { + double internal_date; + (*it)->GetAsDouble(&internal_date); + base::Time other_date = + base::Time::FromInternalValue(internal_date).LocalMidnight(); + // This date has already been added. Don't add the date again, and don't + // bother trimming values as it will have been done the first time the + // date was added (unless the local date has changed, which we can live + // with). + if (other_date == date) + return; - // Dates are stored in their raw form (i.e. not local dates) to be resilient - // to time zone changes. - could_show_list->AppendDouble(time.ToInternalValue()); + base::TimeDelta delta = date - other_date; + if (delta < + base::TimeDelta::FromDays(kOldestCouldShowBannerEventInDays)) { + ++it; + continue; + } + } + + // Either this date is older than we care about, or it isn't a date, so + // remove it; + it = could_show_list->Erase(it, nullptr); + } + + // Dates are stored in their raw form (i.e. not local dates) to be resilient + // to time zone changes. + could_show_list->AppendDouble(time.ToInternalValue()); + } else { + app_dict->SetDouble(event_key, time.ToInternalValue()); + } settings->SetWebsiteSetting(pattern, ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_APP_BANNER, std::string(), origin_dict.release()); } +bool AppBannerSettingsHelper::ShouldShowBanner( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + base::Time time) { + // Don't show if it has been added to the homescreen. + base::Time added_time = + GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url, + APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN); + if (!added_time.is_null()) + return false; + + base::Time blocked_time = + GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url, + APP_BANNER_EVENT_DID_BLOCK); + + // Null times are in the distant past, so the delta between real times and + // null events will always be greater than the limits. + if (time - blocked_time < + base::TimeDelta::FromDays(kMinimumBannerBlockedToBannerShown)) { + return false; + } + + base::Time shown_time = + GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url, + APP_BANNER_EVENT_DID_SHOW); + if (time - shown_time < + base::TimeDelta::FromDays(kMinimumDaysBetweenBannerShows)) { + return false; + } + + std::vector<base::Time> could_show_events = GetCouldShowBannerEvents( + web_contents, origin_url, package_name_or_start_url); + return could_show_events.size() >= kCouldShowEventsToTrigger; +} + std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents( content::WebContents* web_contents, const GURL& origin_url, @@ -165,8 +215,9 @@ if (!app_dict) return result; + std::string event_key(kBannerEventKeys[APP_BANNER_EVENT_COULD_SHOW]); base::ListValue* could_show_list = nullptr; - if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) + if (!app_dict->GetList(event_key, &could_show_list)) return result; for (auto value : *could_show_list) { @@ -181,6 +232,39 @@ return result; } +base::Time AppBannerSettingsHelper::GetSingleBannerEvent( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + AppBannerEvent event) { + DCHECK(event != APP_BANNER_EVENT_COULD_SHOW); + DCHECK(event < APP_BANNER_EVENT_NUM_EVENTS); + + if (package_name_or_start_url.empty()) + return base::Time(); + + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + HostContentSettingsMap* settings = profile->GetHostContentSettingsMap(); + scoped_ptr<base::DictionaryValue> origin_dict = + GetOriginDict(settings, origin_url); + + if (!origin_dict) + return base::Time(); + + base::DictionaryValue* app_dict = + GetAppDict(origin_dict.get(), package_name_or_start_url); + if (!app_dict) + return base::Time(); + + std::string event_key(kBannerEventKeys[event]); + double internal_time; + if (!app_dict->GetDouble(event_key, &internal_time)) + return base::Time(); + + return base::Time::FromInternalValue(internal_time); +} + bool AppBannerSettingsHelper::IsAllowed( content::WebContents* web_contents, const GURL& origin_url,
diff --git a/chrome/browser/banners/app_banner_settings_helper.h b/chrome/browser/banners/app_banner_settings_helper.h index 241e592..ee6a7c4f 100644 --- a/chrome/browser/banners/app_banner_settings_helper.h +++ b/chrome/browser/banners/app_banner_settings_helper.h
@@ -17,37 +17,62 @@ class GURL; -// Utility class for reading and updating ContentSettings for app banners. +// Utility class to record banner events for the given package or start url. +// +// These events are used to decide when banners should be shown, using a +// heuristic based on how many different days in a recent period of time (for +// example the past two weeks) the banner could have been shown, when it was +// last shown, when it was last blocked, and when it was last installed (for +// ServiceWorker style apps - native apps can query whether the app was +// installed directly). +// +// The desired effect is to have banners appear once a user has demonstrated +// an ongoing relationship with the app, and not to pester the user too much. +// +// For most events only the last event is recorded. The exception are the +// could show events. For these a list of the events is maintained. At most +// one event is stored per day, and events outside the window the heuristic +// uses are discarded. Local times are used to enforce these rules, to ensure +// what we count as a day matches what the user perceives to be days. class AppBannerSettingsHelper { public: - // TODO(benwells): Use this method to implement smarter triggering logic. - // See http://crbug.com/452825. - // Records that a banner could have been shown for the given package or start - // url. - // - // These events are used to decide when banners should be shown, using a - // heuristic based on how many different days in a recent period of time (for - // example the past two weeks) the banner could have been shown. The desired - // effect is to have banners appear once a user has demonstrated an ongoing - // relationship with the app. - // - // At most one event is stored per day, and events outside the window the - // heuristic uses are discarded. Local times are used to enforce these rules, - // to ensure what we count as a day matches what the user perceives to be - // days. - static void RecordCouldShowBannerEvent( - content::WebContents* web_contents, - const GURL& origin_url, - const std::string& package_name_or_start_url, - base::Time time); + enum AppBannerEvent { + APP_BANNER_EVENT_COULD_SHOW, + APP_BANNER_EVENT_DID_SHOW, + APP_BANNER_EVENT_DID_BLOCK, + APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, + APP_BANNER_EVENT_NUM_EVENTS, + }; + + static void RecordBannerEvent(content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + AppBannerEvent event, + base::Time time); + + // Determine if the banner should be shown, given the recorded events for the + // supplied app. + static bool ShouldShowBanner(content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + base::Time time); // Gets the could have been shown events that are stored for the given package - // or start url. This is only used for testing. + // or start url. This is only exposed for testing. static std::vector<base::Time> GetCouldShowBannerEvents( content::WebContents* web_contents, const GURL& origin_url, const std::string& package_name_or_start_url); + // Get the recorded event for an event type that only records the last event. + // Should not be used with APP_BANNER_EVENT_COULD_SHOW. This is only exposed + // for testing. + static base::Time GetSingleBannerEvent( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + AppBannerEvent event); + // Checks if a URL is allowed to show a banner for the given package or start // url. static bool IsAllowed(content::WebContents* web_contents,
diff --git a/chrome/browser/banners/app_banner_settings_helper_unittest.cc b/chrome/browser/banners/app_banner_settings_helper_unittest.cc index 917dbec3d..2cf2b62 100644 --- a/chrome/browser/banners/app_banner_settings_helper_unittest.cc +++ b/chrome/browser/banners/app_banner_settings_helper_unittest.cc
@@ -12,6 +12,20 @@ const char kTestURL[] = "http://www.google.com"; const char kTestPackageName[] = "test.package"; +base::Time GetReferenceTime() { + base::Time::Exploded exploded_reference_time; + exploded_reference_time.year = 2015; + exploded_reference_time.month = 1; + exploded_reference_time.day_of_month = 30; + exploded_reference_time.day_of_week = 5; + exploded_reference_time.hour = 11; + exploded_reference_time.minute = 0; + exploded_reference_time.second = 0; + exploded_reference_time.millisecond = 0; + + return base::Time::FromLocalExploded(exploded_reference_time); +} + bool IsWithinDay(base::Time time1, base::Time time2) { return time1 - time2 < base::TimeDelta::FromDays(1) || time2 - time1 < base::TimeDelta::FromDays(1); @@ -45,26 +59,16 @@ kTestPackageName); EXPECT_TRUE(events.empty()); - base::Time::Exploded exploded_reference_time; - exploded_reference_time.year = 2015; - exploded_reference_time.month = 1; - exploded_reference_time.day_of_month = 30; - exploded_reference_time.day_of_week = 5; - exploded_reference_time.hour = 11; - exploded_reference_time.minute = 0; - exploded_reference_time.second = 0; - exploded_reference_time.millisecond = 0; - - base::Time reference_time = - base::Time::FromLocalExploded(exploded_reference_time); + base::Time reference_time = GetReferenceTime(); base::Time same_day = reference_time + base::TimeDelta::FromHours(2); base::Time three_days_prior = reference_time - base::TimeDelta::FromDays(3); base::Time previous_fortnight = reference_time - base::TimeDelta::FromDays(14); // Test adding the first date. - AppBannerSettingsHelper::RecordCouldShowBannerEvent( - web_contents(), url, kTestPackageName, previous_fortnight); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, previous_fortnight); // It should be the only date recorded. events = AppBannerSettingsHelper::GetCouldShowBannerEvents( @@ -73,8 +77,9 @@ EXPECT_TRUE(IsWithinDay(events[0], previous_fortnight)); // Now add the next date. - AppBannerSettingsHelper::RecordCouldShowBannerEvent( - web_contents(), url, kTestPackageName, three_days_prior); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, three_days_prior); // Now there should be two days. events = AppBannerSettingsHelper::GetCouldShowBannerEvents( @@ -84,8 +89,9 @@ EXPECT_TRUE(IsWithinDay(events[1], three_days_prior)); // Now add the reference date. - AppBannerSettingsHelper::RecordCouldShowBannerEvent( - web_contents(), url, kTestPackageName, reference_time); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time); // Now there should still be two days, but the first date should have been // removed. @@ -96,8 +102,9 @@ EXPECT_TRUE(IsWithinDay(events[1], reference_time)); // Now add the the other day on the reference date. - AppBannerSettingsHelper::RecordCouldShowBannerEvent( - web_contents(), url, kTestPackageName, same_day); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, same_day); // Now there should still be the same two days. events = AppBannerSettingsHelper::GetCouldShowBannerEvents( @@ -106,3 +113,180 @@ EXPECT_TRUE(IsWithinDay(events[0], three_days_prior)); EXPECT_TRUE(IsWithinDay(events[1], reference_time)); } + +TEST_F(AppBannerSettingsHelperTest, SingleEvents) { + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time other_time = reference_time - base::TimeDelta::FromDays(3); + for (int event = AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW; + event < AppBannerSettingsHelper::APP_BANNER_EVENT_NUM_EVENTS; ++event) { + // Check that by default, there is no event. + base::Time event_time = AppBannerSettingsHelper::GetSingleBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::AppBannerEvent(event)); + EXPECT_TRUE(event_time.is_null()); + + // Check that a time can be recorded. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::AppBannerEvent(event), reference_time); + + event_time = AppBannerSettingsHelper::GetSingleBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::AppBannerEvent(event)); + EXPECT_EQ(reference_time, event_time); + + // Check that another time can be recorded. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::AppBannerEvent(event), other_time); + + event_time = AppBannerSettingsHelper::GetSingleBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::AppBannerEvent(event)); + EXPECT_EQ(other_time, event_time); + } +} + +TEST_F(AppBannerSettingsHelperTest, ShouldShowFromEngagement) { + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1); + base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366); + + // By default the banner should not be shown. + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Visit the site once, it still should not be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_year_ago); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Visit the site again after a long delay, it still should not be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Visit the site again; now it should be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); +} + +TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterBlocking) { + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1); + base::Time two_months_ago = reference_time - base::TimeDelta::FromDays(60); + base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366); + + // By default the banner should not be shown. + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Record events such that the banner should show. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Block the site a long time ago. It should still be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, one_year_ago); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Block the site more recently. Now it should not be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, two_months_ago); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); +} + +TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterShowing) { + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1); + base::Time three_weeks_ago = reference_time - base::TimeDelta::FromDays(21); + base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366); + + // By default the banner should not be shown. + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Record events such that the banner should show. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Show the banner a long time ago. It should still be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, one_year_ago); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Show the site more recently. Now it should not be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, three_weeks_ago); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); +} + +TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterAdding) { + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1); + base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366); + + // By default the banner should not be shown. + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Record events such that the banner should show. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago); + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // Add the site a long time ago. It should not be shown. + AppBannerSettingsHelper::RecordBannerEvent( + web_contents(), url, kTestPackageName, + AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, + one_year_ago); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); +}
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc index 68f9d58..eda8af0 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -30,6 +30,7 @@ #include "ui/gfx/favicon_size.h" using bookmarks::BookmarkCodec; +using bookmarks::BookmarkNode; using content::BrowserThread; namespace {
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.h b/chrome/browser/bookmarks/bookmark_html_writer.h index 7badebb..36330bf6a 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.h +++ b/chrome/browser/bookmarks/bookmark_html_writer.h
@@ -17,9 +17,12 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" -class BookmarkNode; class Profile; +namespace bookmarks { +class BookmarkNode; +} + namespace chrome { struct FaviconRawBitmapResult; } @@ -58,7 +61,7 @@ private: // Recursively extracts URLs from bookmarks. - void ExtractUrls(const BookmarkNode* node); + void ExtractUrls(const bookmarks::BookmarkNode* node); // Executes Writer task that writes bookmarks data to html file. void ExecuteWriter();
diff --git a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc index c4ee5df9..ebd6cf0 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
@@ -31,6 +31,7 @@ #include "ui/gfx/codec/png_codec.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/bookmarks/bookmark_stats.cc b/chrome/browser/bookmarks/bookmark_stats.cc index 5c3f37d..ed238cbf 100644 --- a/chrome/browser/bookmarks/bookmark_stats.cc +++ b/chrome/browser/bookmarks/bookmark_stats.cc
@@ -8,6 +8,8 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "content/public/browser/user_metrics.h" +using bookmarks::BookmarkNode; + void RecordBookmarkLaunch(const BookmarkNode* node, BookmarkLaunchLocation location) { if (location == BOOKMARK_LAUNCH_LOCATION_DETACHED_BAR ||
diff --git a/chrome/browser/bookmarks/bookmark_stats.h b/chrome/browser/bookmarks/bookmark_stats.h index af4d6ac..bcfea72 100644 --- a/chrome/browser/bookmarks/bookmark_stats.h +++ b/chrome/browser/bookmarks/bookmark_stats.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_STATS_H_ #define CHROME_BROWSER_BOOKMARKS_BOOKMARK_STATS_H_ +namespace bookmarks { class BookmarkNode; +} // This enum is used for the Bookmarks.EntryPoint histogram. enum BookmarkEntryPoint { @@ -40,7 +42,7 @@ }; // Records the launch of a bookmark for UMA purposes. -void RecordBookmarkLaunch(const BookmarkNode* node, +void RecordBookmarkLaunch(const bookmarks::BookmarkNode* node, BookmarkLaunchLocation location); // Records the user opening a folder of bookmarks for UMA purposes.
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser/bookmarks/chrome_bookmark_client.cc index e6a145e..5707d4b3 100644 --- a/chrome/browser/bookmarks/chrome_bookmark_client.cc +++ b/chrome/browser/bookmarks/chrome_bookmark_client.cc
@@ -26,6 +26,8 @@ #include "ui/base/l10n/l10n_util.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; namespace {
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.h b/chrome/browser/bookmarks/chrome_bookmark_client.h index 363a58e..8079fe8 100644 --- a/chrome/browser/bookmarks/chrome_bookmark_client.h +++ b/chrome/browser/bookmarks/chrome_bookmark_client.h
@@ -36,14 +36,14 @@ void Shutdown() override; // Returns the managed_node. - const BookmarkNode* managed_node() { return managed_node_; } + const bookmarks::BookmarkNode* managed_node() { return managed_node_; } // Returns true if the given node belongs to the managed bookmarks tree. - bool IsDescendantOfManagedNode(const BookmarkNode* node); + bool IsDescendantOfManagedNode(const bookmarks::BookmarkNode* node); // Returns true if there is at least one managed node in the |list|. bool HasDescendantsOfManagedNode( - const std::vector<const BookmarkNode*>& list); + const std::vector<const bookmarks::BookmarkNode*>& list); // bookmarks::BookmarkClient: bool PreferTouchIcon() override; @@ -56,12 +56,14 @@ void GetTypedCountForNodes( const NodeSet& nodes, NodeTypedCountPairs* node_typed_count_pairs) override; - bool IsPermanentNodeVisible(const BookmarkPermanentNode* node) override; + bool IsPermanentNodeVisible( + const bookmarks::BookmarkPermanentNode* node) override; void RecordAction(const base::UserMetricsAction& action) override; bookmarks::LoadExtraCallback GetLoadExtraNodesCallback() override; - bool CanSetPermanentNodeTitle(const BookmarkNode* permanent_node) override; - bool CanSyncNode(const BookmarkNode* node) override; - bool CanBeEditedByUser(const BookmarkNode* node) override; + bool CanSetPermanentNodeTitle( + const bookmarks::BookmarkNode* permanent_node) override; + bool CanSyncNode(const bookmarks::BookmarkNode* node) override; + bool CanBeEditedByUser(const bookmarks::BookmarkNode* node) override; private: friend class HistoryServiceFactory; @@ -70,9 +72,9 @@ // bookmarks::BaseBookmarkModelObserver: void BookmarkModelChanged() override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; @@ -81,7 +83,7 @@ // Helper for GetLoadExtraNodesCallback(). static bookmarks::BookmarkPermanentNodeList LoadExtraNodes( - scoped_ptr<BookmarkPermanentNode> managed_node, + scoped_ptr<bookmarks::BookmarkPermanentNode> managed_node, scoped_ptr<base::ListValue> initial_managed_bookmarks, int64* next_node_id); @@ -104,7 +106,7 @@ bookmarks::BookmarkModel* model_; scoped_ptr<policy::ManagedBookmarksTracker> managed_bookmarks_tracker_; - BookmarkPermanentNode* managed_node_; + bookmarks::BookmarkPermanentNode* managed_node_; DISALLOW_COPY_AND_ASSIGN(ChromeBookmarkClient); };
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc b/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc index d527f45..d005282 100644 --- a/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc +++ b/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc
@@ -25,6 +25,7 @@ #include "ui/base/l10n/l10n_util.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using testing::Mock; using testing::_;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index c64b40e..6a719e88 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -878,7 +878,7 @@ } CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() { - if (!crl_set_fetcher_.get()) + if (!crl_set_fetcher_) crl_set_fetcher_ = new CRLSetFetcher(); return crl_set_fetcher_.get(); } @@ -886,13 +886,13 @@ component_updater::PnaclComponentInstaller* BrowserProcessImpl::pnacl_component_installer() { #if !defined(DISABLE_NACL) - if (!pnacl_component_installer_.get()) { - pnacl_component_installer_.reset( - new component_updater::PnaclComponentInstaller()); + if (!pnacl_component_installer_) { + pnacl_component_installer_ = + new component_updater::PnaclComponentInstaller(); } return pnacl_component_installer_.get(); #else - return NULL; + return nullptr; #endif }
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 3a7848c..95655db 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h
@@ -277,7 +277,7 @@ scoped_refptr<CRLSetFetcher> crl_set_fetcher_; #if !defined(DISABLE_NACL) - scoped_ptr<component_updater::PnaclComponentInstaller> + scoped_refptr<component_updater::PnaclComponentInstaller> pnacl_component_installer_; #endif
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index 38ecf2b..520ba39 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc
@@ -126,6 +126,9 @@ } void BrowserProcessPlatformPart::StartTearDown() { + // interactive_ui_tests check for memory leaks before this object is + // destroyed. So we need to destroy |timezone_resolver_| here. + timezone_resolver_.reset(); profile_helper_.reset(); }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index b6a47767..498e08a 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -67,7 +67,6 @@ <structure name="IDR_OOBE_ENROLLMENT_CSS" file="resources\chromeos\login\oobe_screen_oauth_enrollment.css" flattenhtml="true" type="chrome_html" /> <structure name="IDR_OOBE_ENROLLMENT_JS" file="resources\chromeos\login\oobe_screen_oauth_enrollment.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_KEYBOARD_UTILS_JS" file="resources\chromeos\keyboard\keyboard_utils.js" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_NETWORK_CONFIG_JS" file="resources\chromeos\network\network_config.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_HTML" file="resources\chromeos\login\custom_elements.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_JS" file="resources\chromeos\login\custom_elements.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_NEW_OOBE_HTML" file="resources\chromeos\login\new\oobe.html" flattenhtml="true" type="chrome_html" variables="OOBE=oobe" expand_variables="true"/> @@ -448,6 +447,7 @@ <include name="IDR_BRAILLE_MANIFEST" file="resources\chromeos\braille_ime\manifest.json" type="BINDATA" /> </if> <include name="IDR_WHISPERNET_PROXY_MANIFEST" file="resources\whispernet_proxy\manifest.json" type="BINDATA" /> + <include name="IDR_MD_SETTINGS_UI_HTML" file="resources\md_settings\md_settings.html" type="BINDATA" /> </includes> </release> </grit>
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc index 189586b..4e3b365 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.cc +++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/history/history_service.h" #include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/media/media_device_id_salt.h" #include "chrome/browser/net/predictor.h" @@ -308,6 +309,7 @@ waiting_for_clear_history_ = true; history_service->ExpireLocalAndRemoteHistoryBetween( + WebHistoryServiceFactory::GetForProfile(profile_), restrict_urls, delete_begin_, delete_end_, base::Bind(&BrowsingDataRemover::OnHistoryDeletionDone, base::Unretained(this)), @@ -487,6 +489,9 @@ } #endif MediaDeviceIDSalt::Reset(profile_->GetPrefs()); + + // TODO(mkwst): If we're not removing passwords, then clear the 'zero-click' + // flag for all credentials in the password store. } // Channel IDs are not separated for protected and unprotected web
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc index ad2345c..5491de7 100644 --- a/chrome/browser/captive_portal/captive_portal_browsertest.cc +++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -2070,10 +2070,19 @@ GetStateOfTabReloaderAt(browser(), 0)); } +// This test is very flaky on Linux and is disabled. +// https://crbug.com/453875 +#if defined(OS_LINUX) +#define MAYBE_InterstitialTimerReloadWhileLoading \ + DISABLED_InterstitialTimerReloadWhileLoading +#else +#define MAYBE_InterstitialTimerReloadWhileLoading \ + InterstitialTimerReloadWhileLoading +#endif // Same as above, but instead of stopping, the loading page is reloaded. The end // result is the same. (i.e. page load stops, no interstitials shown) IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, - InterstitialTimerReloadWhileLoading) { + MAYBE_InterstitialTimerReloadWhileLoading) { net::SpawnedTestServer::SSLOptions https_options; https_options.server_certificate = net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; @@ -2678,8 +2687,7 @@ // in. IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HstsLogin) { GURL::Replacements replacements; - std::string scheme = "http"; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); GURL http_timeout_url = GURL(kMockHttpsUrl).ReplaceComponents(replacements); URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc index 738a17f..8e752cb 100644 --- a/chrome/browser/chrome_browser_field_trials.cc +++ b/chrome/browser/chrome_browser_field_trials.cc
@@ -53,7 +53,6 @@ base::FieldTrialList::FindValue("CLD1VsCLD2"); base::FieldTrialList::FindValue("MouseEventPreconnect"); base::FieldTrialList::FindValue("DisplayList2dCanvas"); - base::FieldTrialList::FindValue("V8ScriptStreaming"); // Activate the autocomplete dynamic field trials. OmniboxFieldTrial::ActivateDynamicTrials(); }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 2b86dc0..75518a2 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -249,9 +249,6 @@ base::SequencedTaskRunner* local_state_task_runner, const base::CommandLine& parsed_command_line) { TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState") - base::FilePath local_state_path; - PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); - bool local_state_file_exists = base::PathExists(local_state_path); // Load local state. This includes the application locale so we know which // locale dll to load. This also causes local state prefs to be registered. @@ -285,23 +282,27 @@ // JSONPrefStore here instead of an entire PrefService. Once this is // addressed, the call to browser_prefs::RegisterLocalState can move // to chrome_prefs::CreateLocalState. - if (!local_state_file_exists && - parsed_command_line.HasSwitch(switches::kParentProfile)) { - base::FilePath parent_profile = - parsed_command_line.GetSwitchValuePath(switches::kParentProfile); - scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple(); - scoped_ptr<PrefService> parent_local_state( - chrome_prefs::CreateLocalState( - parent_profile, - local_state_task_runner, - g_browser_process->policy_service(), - registry, - false)); - registry->RegisterStringPref(prefs::kApplicationLocale, std::string()); - // Right now, we only inherit the locale setting from the parent profile. - local_state->SetString( - prefs::kApplicationLocale, - parent_local_state->GetString(prefs::kApplicationLocale)); + if (parsed_command_line.HasSwitch(switches::kParentProfile)) { + base::FilePath local_state_path; + PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); + bool local_state_file_exists = base::PathExists(local_state_path); + if (!local_state_file_exists) { + base::FilePath parent_profile = + parsed_command_line.GetSwitchValuePath(switches::kParentProfile); + scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple(); + scoped_ptr<PrefService> parent_local_state( + chrome_prefs::CreateLocalState( + parent_profile, + local_state_task_runner, + g_browser_process->policy_service(), + registry, + false)); + registry->RegisterStringPref(prefs::kApplicationLocale, std::string()); + // Right now, we only inherit the locale setting from the parent profile. + local_state->SetString( + prefs::kApplicationLocale, + parent_local_state->GetString(prefs::kApplicationLocale)); + } } #if defined(OS_CHROMEOS) @@ -1514,7 +1515,6 @@ // We are in regular browser boot sequence. Open initial tabs and enter the // main message loop. - int result_code; #if defined(OS_CHROMEOS) // On ChromeOS multiple profiles doesn't apply, and will break if we load // them this early as the cryptohome hasn't yet been mounted (which happens @@ -1526,7 +1526,7 @@ #endif if (browser_creator_->Start(parsed_command_line(), base::FilePath(), - profile_, last_opened_profiles, &result_code)) { + profile_, last_opened_profiles)) { #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) // Initialize autoupdate timer. Timer callback costs basically nothing // when browser is not in persistent mode, so it's OK to let it ride on
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index cf63aa7..83b62c9 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -632,6 +632,7 @@ return DesktopNotificationServiceFactory::GetForProfile(profile); #else NOTIMPLEMENTED(); + break; #endif case content::PERMISSION_GEOLOCATION: return GeolocationPermissionContextFactory::GetForProfile(profile); @@ -652,6 +653,28 @@ return nullptr; } +// Helper method to translate from Permissions to ContentSettings +ContentSettingsType PermissionToContentSetting( + content::PermissionType permission) { + switch (permission) { + case content::PERMISSION_MIDI_SYSEX: + return CONTENT_SETTINGS_TYPE_MIDI_SYSEX; + case content::PERMISSION_PUSH_MESSAGING: + return CONTENT_SETTINGS_TYPE_PUSH_MESSAGING; + case content::PERMISSION_NOTIFICATIONS: + return CONTENT_SETTINGS_TYPE_NOTIFICATIONS; + case content::PERMISSION_GEOLOCATION: + return CONTENT_SETTINGS_TYPE_GEOLOCATION; +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) + case content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER: + return CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER; +#endif + default: + NOTREACHED() << "Unknown content setting for permission " << permission; + return CONTENT_SETTINGS_TYPE_DEFAULT; + } +} + } // namespace namespace chrome { @@ -1430,6 +1453,7 @@ switches::kDisableBundledPpapiFlash, switches::kDisableCastStreamingHWEncoding, switches::kDisableJavaScriptHarmonyShipping, + switches::kDisableNewBookmarkApps, switches::kDisableOutOfProcessPdf, switches::kEnableBenchmarking, switches::kEnableNaCl, @@ -1438,7 +1462,6 @@ switches::kEnableNaClNonSfiMode, #endif switches::kEnableNetBenchmarking, - switches::kEnableNewBookmarkApps, switches::kEnableOutOfProcessPdf, switches::kEnablePluginPlaceholderShadowDom, switches::kEnableShowModalDialog, @@ -1908,67 +1931,19 @@ const base::Callback<void(bool)>& result_callback) { int render_process_id = web_contents->GetRenderProcessHost()->GetID(); int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID(); - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - const PermissionRequestID request_id(render_process_id, render_view_id, bridge_id, requesting_frame); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + PermissionContextBase* context = GetPermissionContext(profile, permission); - switch (permission) { - case content::PERMISSION_MIDI_SYSEX: - MidiPermissionContextFactory::GetForProfile(profile) - ->RequestPermission(web_contents, - request_id, - requesting_frame, - user_gesture, - result_callback); - break; - case content::PERMISSION_NOTIFICATIONS: -#if defined(ENABLE_NOTIFICATIONS) - DesktopNotificationServiceFactory::GetForProfile(profile) - ->RequestNotificationPermission(web_contents, - request_id, - requesting_frame, - user_gesture, - result_callback); -#else - NOTIMPLEMENTED(); -#endif - break; - case content::PERMISSION_GEOLOCATION: - GeolocationPermissionContextFactory::GetForProfile(profile) - ->RequestPermission(web_contents, - request_id, - requesting_frame.GetOrigin(), - user_gesture, - result_callback); - break; - case content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER: -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) - ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile) - ->RequestPermission(web_contents, - request_id, - requesting_frame.GetOrigin(), - user_gesture, - result_callback); -#else - NOTIMPLEMENTED(); -#endif - break; - case content::PERMISSION_PUSH_MESSAGING: - gcm::PushMessagingPermissionContextFactory::GetForProfile(profile) - ->RequestPermission(web_contents, - request_id, - requesting_frame.GetOrigin(), - user_gesture, - result_callback); - break; - case content::PERMISSION_NUM: - NOTREACHED() << "Invalid RequestPermission for " << permission; - break; - } + if (!context) + return; + + context->RequestPermission(web_contents, request_id, requesting_frame, + user_gesture, result_callback); } content::PermissionStatus ChromeContentBrowserClient::GetPermissionStatus( @@ -2011,67 +1986,16 @@ const GURL& requesting_frame) { int render_process_id = web_contents->GetRenderProcessHost()->GetID(); int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID(); - const PermissionRequestID request_id(render_process_id, render_view_id, bridge_id, requesting_frame); Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); - switch (permission) { - case content::PERMISSION_MIDI_SYSEX: - MidiPermissionContextFactory::GetForProfile(profile) - ->CancelPermissionRequest(web_contents, request_id); - break; - case content::PERMISSION_NOTIFICATIONS: -#if defined(ENABLE_NOTIFICATIONS) - DesktopNotificationServiceFactory::GetForProfile(profile) - ->CancelPermissionRequest(web_contents, request_id); -#else - NOTIMPLEMENTED(); -#endif - break; - case content::PERMISSION_GEOLOCATION: - GeolocationPermissionContextFactory::GetForProfile(profile) - ->CancelPermissionRequest(web_contents, request_id); - break; - case content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER: -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) - ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile) - ->CancelPermissionRequest(web_contents, request_id); -#else - NOTIMPLEMENTED(); -#endif - break; - case content::PERMISSION_PUSH_MESSAGING: - NOTIMPLEMENTED() << "CancelPermission not implemented for " << permission; - break; - case content::PERMISSION_NUM: - NOTREACHED() << "Invalid CancelPermission for " << permission; - break; - } -} - -// Helper method to translate from Permissions to ContentSettings -static ContentSettingsType PermissionToContentSetting( - content::PermissionType permission) { - switch (permission) { - case content::PERMISSION_MIDI_SYSEX: - return CONTENT_SETTINGS_TYPE_MIDI_SYSEX; - case content::PERMISSION_PUSH_MESSAGING: - return CONTENT_SETTINGS_TYPE_PUSH_MESSAGING; - case content::PERMISSION_NOTIFICATIONS: - return CONTENT_SETTINGS_TYPE_NOTIFICATIONS; - case content::PERMISSION_GEOLOCATION: - return CONTENT_SETTINGS_TYPE_GEOLOCATION; -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) - case content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER: - return CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER; -#endif - default: - NOTREACHED() << "Unknown content setting for permission " << permission; - return CONTENT_SETTINGS_TYPE_DEFAULT; - } + PermissionContextBase* context = GetPermissionContext(profile, permission); + if (!context) + return; + context->CancelPermissionRequest(web_contents, request_id); } void ChromeContentBrowserClient::RegisterPermissionUsage( @@ -2585,6 +2509,27 @@ browser_context, security_origin, type); } +content::WebContents* ChromeContentBrowserClient::OpenURL( + content::BrowserContext* browser_context, + const content::OpenURLParams& params) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + +#if !defined(OS_ANDROID) && !defined(OS_IOS) + NavigateParams nav_params(Profile::FromBrowserContext(browser_context), + params.url, + params.transition); + FillNavigateParamsFromOpenURLParams(&nav_params, params); + nav_params.user_gesture = params.user_gesture; + + Navigate(&nav_params); + return nav_params.target_contents; +#else + // TODO(mlamouri): write a chrome::Navigate() method for Android and iOS. + // See https://crbug.com/448409. + return nullptr; +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) +} + content::DevToolsManagerDelegate* ChromeContentBrowserClient::GetDevToolsManagerDelegate() { #if defined(OS_ANDROID)
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 3c2bf14..40e700f 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -281,6 +281,9 @@ const GURL& security_origin, content::MediaStreamType type) override; + content::WebContents* OpenURL(content::BrowserContext* browser_context, + const content::OpenURLParams& params) override; + private: friend class DisableWebRtcEncryptionFlagTest;
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index fd29ffc5..42c45c5f 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -23,7 +23,7 @@ namespace chrome { -typedef testing::Test ChromeContentBrowserClientTest; +using ChromeContentBrowserClientTest = testing::Test; TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) { ChromeContentBrowserClient client; @@ -32,6 +32,43 @@ EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com"))); } +using ChromeContentBrowserClientWindowTest = BrowserWithTestWindowTest; + +// BrowserWithTestWindowTest doesn't work on iOS and Android. +#if !defined(OS_ANDROID) && !defined(OS_IOS) + +// This test opens two URLs using ContentBrowserClient::OpenURL. It expects the +// URLs to be opened in new tabs and activated, changing the active tabs after +// each call and increasing the tab count by 2. +TEST_F(ChromeContentBrowserClientWindowTest, OpenURL) { + ChromeContentBrowserClient client; + + int previous_count = browser()->tab_strip_model()->count(); + + GURL urls[] = { GURL("https://www.google.com"), + GURL("https://www.chromium.org") }; + + for (const GURL& url : urls) { + content::OpenURLParams params(url, + content::Referrer(), + NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, + false); + content::WebContents* contents = + client.OpenURL(browser()->profile(), params); + EXPECT_TRUE(contents); + + content::WebContents* active_contents = browser()->tab_strip_model()-> + GetActiveWebContents(); + EXPECT_EQ(contents, active_contents); + EXPECT_EQ(url, active_contents->GetVisibleURL()); + } + + EXPECT_EQ(previous_count + 2, browser()->tab_strip_model()->count()); +} + +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + #if defined(ENABLE_WEBRTC) // NOTE: Any updates to the expectations in these tests should also be done in
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc index 3778614..2537a1c 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/preferences.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc index 2e05a873..970973c 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/chromeos/app_mode/fake_cws.cc b/chrome/browser/chromeos/app_mode/fake_cws.cc index f4f343d..b72c1d5 100644 --- a/chrome/browser/chromeos/app_mode/fake_cws.cc +++ b/chrome/browser/chromeos/app_mode/fake_cws.cc
@@ -104,9 +104,8 @@ } void FakeCWS::SetupWebStoreURL(const GURL& test_server_url) { - std::string webstore_host(kWebstoreDomain); GURL::Replacements replace_webstore_host; - replace_webstore_host.SetHostStr(webstore_host); + replace_webstore_host.SetHostStr(kWebstoreDomain); web_store_url_ = test_server_url.ReplaceComponents(replace_webstore_host); }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index 86affa2..e84dff2 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -100,15 +100,21 @@ registry->RegisterDictionaryPref(kKioskDictionaryName); } -KioskAppManager::App::App(const KioskAppData& data, bool is_extension_pending) +KioskAppManager::App::App( + const KioskAppData& data, + bool is_extension_pending, + bool auto_launched_with_zero_delay) : app_id(data.app_id()), user_id(data.user_id()), name(data.name()), icon(data.icon()), - is_loading(data.IsLoading() || is_extension_pending) { + is_loading(data.IsLoading() || is_extension_pending), + was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) { } -KioskAppManager::App::App() : is_loading(false) {} +KioskAppManager::App::App() : is_loading(false), + was_auto_launched_with_zero_delay(false) {} + KioskAppManager::App::~App() {} std::string KioskAppManager::GetAutoLaunchApp() const { @@ -131,6 +137,12 @@ kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0); } +void KioskAppManager::SetAppWasAutoLaunchedWithZeroDelay( + const std::string& app_id) { + DCHECK_EQ(auto_launch_app_id_, app_id); + currently_auto_launched_with_zero_delay_app_ = app_id; +} + void KioskAppManager::EnableConsumerKioskAutoLaunch( const KioskAppManager::EnableKioskAutoLaunchCallback& callback) { policy::BrowserPolicyConnectorChromeOS* connector = @@ -311,9 +323,11 @@ apps->reserve(apps_.size()); for (size_t i = 0; i < apps_.size(); ++i) { const KioskAppData& app_data = *apps_[i]; - if (app_data.status() != KioskAppData::STATUS_ERROR) + if (app_data.status() != KioskAppData::STATUS_ERROR) { apps->push_back(App( - app_data, external_cache_->IsExtensionPending(app_data.app_id()))); + app_data, external_cache_->IsExtensionPending(app_data.app_id()), + app_data.app_id() == currently_auto_launched_with_zero_delay_app_)); + } } } @@ -322,7 +336,8 @@ if (!data) return false; - *app = App(*data, external_cache_->IsExtensionPending(app_id)); + *app = App(*data, external_cache_->IsExtensionPending(app_id), + app_id == currently_auto_launched_with_zero_delay_app_); return true; }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h index 0084d54..4d4944d 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -59,7 +59,9 @@ // Struct to hold app info returned from GetApps() call. struct App { - App(const KioskAppData& data, bool is_extension_pending); + App(const KioskAppData& data, + bool is_extension_pending, + bool was_auto_launched_with_zero_delay); App(); ~App(); @@ -68,6 +70,7 @@ std::string name; gfx::ImageSkia icon; bool is_loading; + bool was_auto_launched_with_zero_delay; }; typedef std::vector<App> Apps; @@ -123,6 +126,9 @@ // Returns true if owner/policy enabled auto launch. bool IsAutoLaunchEnabled() const; + // Returns true if current app was auto launched with zero delay. + bool IsCurrentAppAutoLaunchedWithZeroDelay() const; + // Enable auto launch setter. void SetEnableAutoLaunch(bool value); @@ -195,6 +201,12 @@ bool external_loader_created() const { return external_loader_created_; } + // Notifies the KioskAppManager that a given app was auto-launched + // automatically with no delay on startup. Certain privacy-sensitive + // kiosk-mode behavior (such as network reporting) is only enabled for + // kiosk apps that are immediately auto-launched on startup. + void SetAppWasAutoLaunchedWithZeroDelay(const std::string& app_id); + private: friend struct base::DefaultLazyInstanceTraits<KioskAppManager>; friend struct base::DefaultDeleter<KioskAppManager>; @@ -261,6 +273,7 @@ bool ownership_established_; ScopedVector<KioskAppData> apps_; std::string auto_launch_app_id_; + std::string currently_auto_launched_with_zero_delay_app_; ObserverList<KioskAppManagerObserver, true> observers_; scoped_ptr<CrosSettings::ObserverSubscription>
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc index b90f73b5..48498b6 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -361,11 +361,26 @@ manager()->SetAutoLaunchApp("fake_app_1"); EXPECT_EQ("fake_app_1", manager()->GetAutoLaunchApp()); + // Make sure that if an app was auto launched with zero delay, it is reflected + // in the app data. + KioskAppManager::App app; + manager()->GetApp("fake_app_1", &app); + EXPECT_FALSE(app.was_auto_launched_with_zero_delay); + + manager()->SetAppWasAutoLaunchedWithZeroDelay("fake_app_1"); + manager()->GetApp("fake_app_1", &app); + EXPECT_TRUE(app.was_auto_launched_with_zero_delay); + // Clear the auto launch app. manager()->SetAutoLaunchApp(""); EXPECT_EQ("", manager()->GetAutoLaunchApp()); EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); + // App should still report it was auto launched with zero delay, even though + // it is no longer set to auto launch in the future. + manager()->GetApp("fake_app_1", &app); + EXPECT_TRUE(app.was_auto_launched_with_zero_delay); + // Set another auto launch app. manager()->SetAutoLaunchApp("fake_app_2"); EXPECT_EQ("fake_app_2", manager()->GetAutoLaunchApp());
diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc index 689ab68..2bfe2e275b 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h" #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -160,10 +159,11 @@ UserContext context = user_context; if (context.GetUserID() == chromeos::login::kGuestUserName) context.SetUserID(DemoAppLauncher::kDemoUserName); - LoginUtils::Get()->PrepareProfile(context, - false, // has_auth_cookies - false, // has_active_session - this); + UserSessionManager::GetInstance()->StartSession( + context, UserSessionManager::PRIMARY_USER_SESSION, + false, // has_auth_cookies + false, // Start session for user. + this); } void KioskProfileLoader::OnAuthFailure(const AuthFailure& error) { @@ -186,8 +186,8 @@ void KioskProfileLoader::OnProfilePrepared(Profile* profile, bool browser_launched) { // This object could be deleted any time after successfully reporting - // a profile load, so invalidate the LoginUtils delegate now. - LoginUtils::Get()->DelegateDeleted(this); + // a profile load, so invalidate the delegate now. + UserSessionManager::GetInstance()->DelegateDeleted(this); delegate_->OnProfileLoaded(profile); ReportLaunchResult(KioskAppLaunchError::NONE);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h index 9dee387..42796e3 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h +++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h
@@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" -#include "chrome/browser/chromeos/login/login_utils.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chromeos/login/auth/login_performer.h" class Profile; @@ -22,7 +22,7 @@ // attempts to login for the app's generated user id. If the login is // successful, it prepares app profile then calls the delegate. class KioskProfileLoader : public LoginPerformer::Delegate, - public LoginUtils::Delegate { + public UserSessionManagerDelegate { public: class Delegate { public: @@ -55,7 +55,7 @@ void PolicyLoadFailed() override; void OnOnlineChecked(const std::string& email, bool success) override; - // LoginUtils::Delegate implementation: + // UserSessionManagerDelegate implementation: void OnProfilePrepared(Profile* profile, bool browser_launched) override; std::string user_id_;
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc index a7652a3..d43781d 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -90,6 +90,8 @@ // through a user bailout shortcut. ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) ->RemoveObserver(this); + extensions::InstallTrackerFactory::GetForBrowserContext(profile_) + ->RemoveObserver(this); } void StartupAppLauncher::Initialize() {
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc index d3cb6b9..a4c3fab 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
@@ -37,16 +37,20 @@ } // namespace // static -void PlatformVerificationDialog::ShowDialog( +views::Widget* PlatformVerificationDialog::ShowDialog( content::WebContents* web_contents, + const GURL& requesting_origin, const PlatformVerificationFlow::Delegate::ConsentCallback& callback) { - GURL url = web_contents->GetLastCommittedURL(); // In the case of an extension or hosted app, the origin of the request is // best described by the extension / app name. const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(web_contents->GetBrowserContext())-> - enabled_extensions().GetExtensionOrAppByURL(url); - std::string origin = extension ? extension->name() : url.GetOrigin().spec(); + extensions::ExtensionRegistry::Get(web_contents->GetBrowserContext()) + ->enabled_extensions() + .GetExtensionOrAppByURL(web_contents->GetLastCommittedURL()); + + // TODO(xhwang): We should only show the name if the request if from the + // extension's true frame. See http://crbug.com/455821 + std::string origin = extension ? extension->name() : requesting_origin.spec(); PlatformVerificationDialog* dialog = new PlatformVerificationDialog( web_contents, @@ -60,6 +64,8 @@ views::Widget* widget = views::DialogDelegate::CreateDialogWidget( dialog, NULL, popup_manager->GetHostView()); popup_manager->ShowModalDialog(widget->GetNativeView(), web_contents); + + return widget; } PlatformVerificationDialog::~PlatformVerificationDialog() {
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.h b/chrome/browser/chromeos/attestation/platform_verification_dialog.h index e33ebd0e..50aef91b 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_dialog.h +++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.h
@@ -25,9 +25,13 @@ public views::StyledLabelListener, public content::WebContentsObserver { public: - // Initializes a tab-modal dialog for |web_contents| and shows it. - static void ShowDialog( + // Initializes a tab-modal dialog for |web_contents| and |requesting_origin| + // and shows it. Returns a non-owning pointer to the widget so that caller can + // close the dialog and cancel the request. The returned widget is only + // guaranteed to be valid before |callback| is called. + static views::Widget* ShowDialog( content::WebContents* web_contents, + const GURL& requesting_origin, const PlatformVerificationFlow::Delegate::ConsentCallback& callback); protected:
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc index 69765ae..1b95c98 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
@@ -79,9 +79,11 @@ void ShowConsentPrompt( content::WebContents* web_contents, + const GURL& requesting_origin, const PlatformVerificationFlow::Delegate::ConsentCallback& callback) override { - PlatformVerificationDialog::ShowDialog(web_contents, callback); + PlatformVerificationDialog::ShowDialog(web_contents, requesting_origin, + callback); } PrefService* GetPrefs(content::WebContents* web_contents) override { @@ -235,10 +237,16 @@ this, context, consent_required); - if (consent_required) - delegate_->ShowConsentPrompt(context.web_contents, consent_callback); - else + if (consent_required) { + // TODO(xhwang): Using delegate_->GetURL() here is not right. The consent + // may be requested by a frame from a different origin. This will be solved + // when http://crbug.com/454847 is fixed. + delegate_->ShowConsentPrompt( + context.web_contents, + delegate_->GetURL(context.web_contents).GetOrigin(), consent_callback); + } else { consent_callback.Run(CONSENT_RESPONSE_NONE); + } } void PlatformVerificationFlow::RegisterProfilePrefs(
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.h b/chrome/browser/chromeos/attestation/platform_verification_flow.h index a48b11c..48b5de5 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow.h +++ b/chrome/browser/chromeos/attestation/platform_verification_flow.h
@@ -92,9 +92,10 @@ // Invokes consent UI within the context of |web_contents| and calls // |callback| when the user responds. - // Precondition: The last committed URL for |web_contents| has a valid - // origin. + // |requesting_origin| or the extension/app name will be shown on the prompt + // if the request comes from a web page or an extension/app, respectively. virtual void ShowConsentPrompt(content::WebContents* web_contents, + const GURL& requesting_origin, const ConsentCallback& callback) = 0; // Gets prefs associated with the given |web_contents|. If no prefs are
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc index 5c5708d3..36a81819 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
@@ -75,6 +75,7 @@ void ShowConsentPrompt( content::WebContents* web_contents, + const GURL& requesting_origin, const PlatformVerificationFlow::Delegate::ConsentCallback& callback) override { num_consent_calls_++;
diff --git a/chrome/browser/chromeos/extensions/file_manager/device_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/device_event_router.cc index 3de49b3..e269073c 100644 --- a/chrome/browser/chromeos/extensions/file_manager/device_event_router.cc +++ b/chrome/browser/chromeos/extensions/file_manager/device_event_router.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/bind.h" -#include "base/metrics/histogram_macros.h" #include "base/thread_task_runner_handle.h" #include "chrome/browser/chromeos/extensions/file_manager/device_event_router.h" #include "chrome/browser/chromeos/file_manager/volume_manager.h" @@ -81,13 +80,6 @@ const std::string& device_path = disk.system_path_prefix(); if (!disk.mount_path().empty() && GetDeviceState(device_path) != DEVICE_HARD_UNPLUGGED_AND_REPORTED) { - // TODO(hirono): Remove the temporary UMA. crbug.com/433734 - if (!last_suspend_done_.is_null()) { - UMA_HISTOGRAM_MEDIUM_TIMES( - "FileBrowser.HardUnpluggedAroundSuspend.TimeSinceResume", - base::Time::Now() - last_suspend_done_); - } - last_hard_unplugged_ = base::Time::Now(); OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_HARD_UNPLUGGED, device_path); SetDeviceState(device_path, DEVICE_HARD_UNPLUGGED_AND_REPORTED); @@ -132,18 +124,11 @@ void DeviceEventRouter::SuspendImminent() { DCHECK(thread_checker_.CalledOnValidThread()); - // TODO(hirono): Remove the temporary UMA. crbug.com/433734 - if (!last_hard_unplugged_.is_null()) { - UMA_HISTOGRAM_MEDIUM_TIMES( - "FileBrowser.HardUnpluggedAroundSuspend.TimeUntilSuspend", - base::Time::Now() - last_hard_unplugged_); - } is_resuming_ = true; } void DeviceEventRouter::SuspendDone(const base::TimeDelta& sleep_duration) { DCHECK(thread_checker_.CalledOnValidThread()); - last_suspend_done_ = base::Time::Now(); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::Bind(&DeviceEventRouter::SuspendDoneDelayed,
diff --git a/chrome/browser/chromeos/extensions/file_manager/device_event_router.h b/chrome/browser/chromeos/extensions/file_manager/device_event_router.h index e9390ee..8c851140 100644 --- a/chrome/browser/chromeos/extensions/file_manager/device_event_router.h +++ b/chrome/browser/chromeos/extensions/file_manager/device_event_router.h
@@ -96,11 +96,6 @@ // Thread checker. base::ThreadChecker thread_checker_; - // Last event time for UMA. - // TODO(hirono): Remove the temporarily UMA. crbug.com/433734 - base::Time last_hard_unplugged_; - base::Time last_suspend_done_; - // Note: This should remain the last member so it'll be destroyed and // invalidate the weak pointers before any other members are destroyed. base::WeakPtrFactory<DeviceEventRouter> weak_factory_;
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc index f1ceb0f..9f76f51 100644 --- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc +++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -154,6 +154,17 @@ make_scoped_ptr(new extensions::Event(event_name, event_args.Pass()))); } +// Sends an event named |event_name| with arguments |event_args| to an extension +// of |extention_id|. +void DispatchEventToExtension(Profile* profile, + const std::string& extension_id, + const std::string& event_name, + scoped_ptr<base::ListValue> event_args) { + extensions::EventRouter::Get(profile)->DispatchEventToExtension( + extension_id, + make_scoped_ptr(new extensions::Event(event_name, event_args.Pass()))); +} + file_manager_private::MountCompletedStatus MountErrorToMountCompletedStatus(chromeos::MountError error) { switch (error) { @@ -940,9 +951,11 @@ event.entry.additional_properties.SetBoolean("fileIsDirectory", entry_definition.is_directory); - BroadcastEvent(profile_, - file_manager_private::OnDirectoryChanged::kEventName, - file_manager_private::OnDirectoryChanged::Create(event)); + DispatchEventToExtension( + profile_, + *extension_id, + file_manager_private::OnDirectoryChanged::kEventName, + file_manager_private::OnDirectoryChanged::Create(event)); } void EventRouter::OnDiskAdded(
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index f7f19dde..a6ca099f 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -457,6 +457,8 @@ IDS_FILE_BROWSER_SEARCH_NO_MATCHING_FILES_HTML); SET_STRING("SEARCH_TEXT_LABEL", IDS_FILE_BROWSER_SEARCH_TEXT_LABEL); SET_STRING("SHARE_BUTTON_LABEL", IDS_FILE_BROWSER_SHARE_BUTTON_LABEL); + SET_STRING("CANCEL_SELECTION_BUTTON_LABEL", + IDS_FILE_BROWSER_CANCEL_SELECTION_BUTTON_LABEL); SET_STRING("SHARE_ERROR", IDS_FILE_BROWSER_SHARE_ERROR); // Shortcut key names: used from cr.ui.MenuItem.updateShortcut_.
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc index a3320511..a6d87af3 100644 --- a/chrome/browser/chromeos/extensions/input_method_api.cc +++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -39,9 +39,9 @@ output->SetBoolean("isVoiceInputEnabled", !base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kDisableVoiceInput)); - output->SetBoolean("isNewQPInputViewEnabled", + output->SetBoolean("isNewMDInputViewEnabled", base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableNewQPInputView)); + chromeos::switches::kEnableNewMDInputView)); return RespondNow(OneArgument(output)); #endif }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 8c7ae1b..77456c9a 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -1083,18 +1083,6 @@ FileManagerBrowserTest, ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "searchBoxFocus"))); -// Slow tests are disabled on debug build. http://crbug.com/327719 -#if !defined(NDEBUG) -#define MAYBE_Thumbnails DISABLED_Thumbnails -#else -#define MAYBE_Thumbnails Thumbnails -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_Thumbnails, - FileManagerBrowserTest, - ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "thumbnailsDownloads"), - TestParameter(IN_GUEST_MODE, "thumbnailsDownloads"))); - // Fails on official build. http://crbug.com/429294 #if !defined(NDEBUG) || defined(OFFICIAL_BUILD) #define MAYBE_OpenFileDialog DISABLED_OpenFileDialog
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index addd0ef..ef77ab4 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -105,16 +105,6 @@ FILE_PATH_LITERAL("foreground/js/file_tasks_unittest.html"))); } -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, PreviewPanel) { - RunTest(base::FilePath( - FILE_PATH_LITERAL("foreground/js/ui/preview_panel_unittest.html"))); -} - -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, PreviewPanelModelTest) { - RunTest(base::FilePath( - FILE_PATH_LITERAL("foreground/js/preview_panel_model_unittest.html"))); -} - IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ThumbnailLoader) { RunTest(base::FilePath( FILE_PATH_LITERAL("foreground/js/thumbnail_loader_unittest.html"))); @@ -159,3 +149,8 @@ RunTest(base::FilePath(FILE_PATH_LITERAL( "foreground/js/metadata/content_metadata_provider_unittest.html"))); } + +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileSystemMetadata) { + RunTest(base::FilePath(FILE_PATH_LITERAL( + "foreground/js/metadata/file_system_metadata_unittest.html"))); +}
diff --git a/chrome/browser/chromeos/file_system_provider/throttled_file_system.cc b/chrome/browser/chromeos/file_system_provider/throttled_file_system.cc index 1f41dae..66e3965 100644 --- a/chrome/browser/chromeos/file_system_provider/throttled_file_system.cc +++ b/chrome/browser/chromeos/file_system_provider/throttled_file_system.cc
@@ -195,7 +195,8 @@ const OpenFileCallback& callback, int file_handle, base::File::Error result) { - open_queue_->Complete(queue_token); + if (result != base::File::FILE_ERROR_ABORT) + open_queue_->Complete(queue_token); // If the file is opened successfully then hold the queue token until the file // is closed.
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index 004ac85..0f55999 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" +#include "chromeos/settings/cros_settings_names.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/notification_service.h" #include "extensions/browser/app_window/app_window.h" @@ -126,7 +127,7 @@ app_launch_splash_screen_actor_->SetDelegate(NULL); } -void AppLaunchController::StartAppLaunch() { +void AppLaunchController::StartAppLaunch(bool is_auto_launch) { DVLOG(1) << "Starting kiosk mode..."; webui_visible_ = host_->GetWebUILoginView()->webui_visible(); @@ -143,6 +144,20 @@ KioskAppManager::App app; CHECK(KioskAppManager::Get()); CHECK(KioskAppManager::Get()->GetApp(app_id_, &app)); + + if (is_auto_launch) { + int delay; + if (!CrosSettings::Get()->GetInteger( + kAccountsPrefDeviceLocalAccountAutoLoginDelay, &delay)) { + delay = 0; + } + DCHECK_EQ(0, delay) << "Kiosks do not support non-zero auto-login delays"; + + // If we are launching a kiosk app with zero delay, mark it appropriately. + if (delay == 0) + KioskAppManager::Get()->SetAppWasAutoLaunchedWithZeroDelay(app_id_); + } + kiosk_profile_loader_.reset( new KioskProfileLoader(app.user_id, false, this)); kiosk_profile_loader_->Start();
diff --git a/chrome/browser/chromeos/login/app_launch_controller.h b/chrome/browser/chromeos/login/app_launch_controller.h index a8d1af8..fd320bd 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.h +++ b/chrome/browser/chromeos/login/app_launch_controller.h
@@ -45,7 +45,9 @@ ~AppLaunchController() override; - void StartAppLaunch(); + // Starts launching an app - set |auto_launch| to true if the app is being + // auto-launched with zero delay. + void StartAppLaunch(bool auto_launch); bool waiting_for_network() { return waiting_for_network_; } bool network_wait_timedout() { return network_wait_timedout_; }
diff --git a/chrome/browser/chromeos/login/app_launch_signin_screen.cc b/chrome/browser/chromeos/login/app_launch_signin_screen.cc index 983ca77..f6c87f7 100644 --- a/chrome/browser/chromeos/login/app_launch_signin_screen.cc +++ b/chrome/browser/chromeos/login/app_launch_signin_screen.cc
@@ -6,8 +6,8 @@ #include "base/values.h" #include "chrome/browser/chromeos/login/help_app_launcher.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/screens/user_selection_screen.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/signin/screenlock_bridge.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/grit/generated_resources.h" @@ -85,9 +85,9 @@ void AppLaunchSigninScreen::Login(const UserContext& user_context, const SigninSpecifics& specifics) { - // Note: LoginUtils::CreateAuthenticator doesn't necessarily create + // Note: CreateAuthenticator doesn't necessarily create // a new Authenticator object, and could reuse an existing one. - authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); + authenticator_ = UserSessionManager::GetInstance()->CreateAuthenticator(this); content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, base::Bind(&Authenticator::AuthenticateToUnlock,
diff --git a/chrome/browser/chromeos/login/auth/chrome_login_performer.cc b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc index 0d1bc62..b8ba6b4e 100644 --- a/chrome/browser/chromeos/login/auth/chrome_login_performer.cc +++ b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
@@ -8,7 +8,7 @@ #include "base/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h" -#include "chrome/browser/chromeos/login/login_utils.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h" @@ -85,7 +85,7 @@ bool ChromeLoginPerformer::IsUserWhitelisted(const std::string& user_id, bool* wildcard_match) { - return LoginUtils::IsWhitelisted(user_id, wildcard_match); + return CrosSettings::IsWhitelisted(user_id, wildcard_match); } void ChromeLoginPerformer::RunOnlineWhitelistCheck( @@ -111,7 +111,7 @@ } scoped_refptr<Authenticator> ChromeLoginPerformer::CreateAuthenticator() { - return LoginUtils::Get()->CreateAuthenticator(this); + return UserSessionManager::GetInstance()->CreateAuthenticator(this); } bool ChromeLoginPerformer::AreSupervisedUsersAllowed() {
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 85d7be0f..6dabbc81 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -72,6 +72,7 @@ ::switches::kDisableAccelerated2dCanvas, ::switches::kDisableAcceleratedJpegDecoding, ::switches::kDisableAcceleratedVideoDecode, + ::switches::kDisableBlinkFeatures, ::switches::kDisableCastStreamingHWEncoding, ::switches::kDisableDelegatedRenderer, ::switches::kDisableDistanceFieldText, @@ -95,6 +96,7 @@ ::switches::kDisableTouchDragDrop, ::switches::kDisableTouchEditing, ::switches::kEnableBeginFrameScheduling, + ::switches::kEnableBlinkFeatures, ::switches::kEnablePreferCompositingToLCDText, ::switches::kEnableDelegatedRenderer, ::switches::kDisableDisplayList2dCanvas,
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 70f0d5a..4a5c0adf 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -26,11 +26,11 @@ #include "chrome/browser/chromeos/customization/customization_document.h" #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/signin_specifics.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" #include "chrome/browser/chromeos/login/user_flow.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -224,7 +224,7 @@ (*it)->GetType() != user_manager::USER_TYPE_SUPERVISED || user_manager::UserManager::Get()->AreSupervisedUsersAllowed(); bool meets_whitelist_requirements = - LoginUtils::IsWhitelisted((*it)->email(), NULL) || + CrosSettings::IsWhitelisted((*it)->email(), NULL) || !(*it)->HasGaiaAccount(); // Public session accounts are always shown on login screen. @@ -302,7 +302,7 @@ // ExistingUserController, private: ExistingUserController::~ExistingUserController() { - LoginUtils::Get()->DelegateDeleted(this); + UserSessionManager::GetInstance()->DelegateDeleted(this); if (current_controller_ == this) { current_controller_ = NULL; @@ -690,11 +690,14 @@ login_performer_->set_delegate(NULL); ignore_result(login_performer_.release()); - // Will call OnProfilePrepared() in the end. - LoginUtils::Get()->PrepareProfile(user_context, - has_auth_cookies, - false, // Start session for user. - this); + UserSessionManager::StartSessionType start_session_type = + UserAddingScreen::Get()->IsRunning() + ? UserSessionManager::SECONDARY_USER_SESSION + : UserSessionManager::PRIMARY_USER_SESSION; + UserSessionManager::GetInstance()->StartSession( + user_context, start_session_type, has_auth_cookies, + false, // Start session for user. + this); // Update user's displayed email. if (!display_email_.empty()) { @@ -923,7 +926,8 @@ void ExistingUserController::LoginAsKioskApp(const std::string& app_id, bool diagnostic_mode) { - host_->StartAppLaunch(app_id, diagnostic_mode); + const bool auto_start = false; + host_->StartAppLaunch(app_id, diagnostic_mode, auto_start); } void ExistingUserController::ConfigurePublicSessionAutoLogin() {
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h index 6db8746..a699fdc 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.h +++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -16,7 +16,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" -#include "chrome/browser/chromeos/login/login_utils.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/ui/login_display.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -51,7 +51,7 @@ class ExistingUserController : public LoginDisplay::Delegate, public content::NotificationObserver, public LoginPerformer::Delegate, - public LoginUtils::Delegate { + public UserSessionManagerDelegate { public: // All UI initialization is deferred till Init() call. explicit ExistingUserController(LoginDisplayHost* host); @@ -146,7 +146,7 @@ void PolicyLoadFailed() override; void OnOnlineChecked(const std::string& username, bool success) override; - // LoginUtils::Delegate implementation: + // UserSessionManagerDelegate implementation: void OnProfilePrepared(Profile* profile, bool browser_launched) override; // Called when device settings change.
diff --git a/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc b/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc index 638aa0d..f59b399 100644 --- a/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc +++ b/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc
@@ -7,7 +7,6 @@ #include "base/message_loop/message_loop.h" #include "base/values.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" -#include "chrome/browser/chromeos/login/mock_login_utils.h" #include "chrome/browser/chromeos/login/ui/mock_login_display.h" #include "chrome/browser/chromeos/login/ui/mock_login_display_host.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" @@ -54,15 +53,11 @@ void SetUp() override { mock_login_display_host_.reset(new MockLoginDisplayHost); mock_login_display_ = new MockLoginDisplay(); - mock_login_utils_ = new MockLoginUtils(); - LoginUtils::Set(mock_login_utils_); EXPECT_CALL(*mock_login_display_host_.get(), CreateLoginDisplay(_)) .Times(1) .WillOnce(Return(mock_login_display_)); - EXPECT_CALL(*mock_login_utils_, DelegateDeleted(_)).Times(AnyNumber()); - EXPECT_CALL(*mock_user_manager_, Shutdown()).Times(AnyNumber()); EXPECT_CALL(*mock_user_manager_, FindUser(_)) .WillRepeatedly(ReturnNull()); @@ -141,9 +136,6 @@ const std::string auto_login_user_id_; private: - // Owned by LoginUtilsWrapper. - MockLoginUtils* mock_login_utils_; - // |mock_login_display_| is owned by the ExistingUserController, which calls // CreateLoginDisplay() on the |mock_login_display_host_| to get it. MockLoginDisplay* mock_login_display_;
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc index 3be3904..406fd03ef 100644 --- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -11,19 +11,19 @@ #include "base/command_line.h" #include "base/location.h" #include "base/memory/ref_counted.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/scoped_user_pref_update.h" #include "base/run_loop.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/help_app_launcher.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/mock_login_utils.h" #include "chrome/browser/chromeos/login/screens/mock_base_screen_delegate.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" +#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h" #include "chrome/browser/chromeos/login/ui/mock_login_display.h" #include "chrome/browser/chromeos/login/ui/mock_login_display_host.h" -#include "chrome/browser/chromeos/login/user_flow.h" -#include "chrome/browser/chromeos/login/users/mock_user_manager.h" -#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" @@ -34,12 +34,9 @@ #include "chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/fake_session_manager_client.h" -#include "chromeos/login/auth/authenticator.h" #include "chromeos/login/auth/key.h" -#include "chromeos/login/auth/mock_authenticator.h" #include "chromeos/login/auth/mock_url_fetchers.h" #include "chromeos/login/auth/user_context.h" #include "chromeos/login/user_names.h" @@ -75,7 +72,6 @@ namespace { const char kUsername[] = "test_user@gmail.com"; -const char kNewUsername[] = "test_new_user@gmail.com"; const char kSupervisedUserID[] = "supervised_user@locally-managed.localhost"; const char kPassword[] = "test_password"; @@ -84,14 +80,6 @@ const int kAutoLoginShortDelay = 1; const int kAutoLoginLongDelay = 10000; -ACTION_P(CreateAuthenticator, user_context) { - return new MockAuthenticator(arg0, user_context); -} - -void DeleteUserFlow(UserFlow* user_flow) { - delete user_flow; -} - // Wait for cros settings to become permanently untrusted and run |callback|. void WaitForPermanentlyUntrustedStatusAndRun(const base::Closure& callback) { while (true) { @@ -116,8 +104,7 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest { protected: - ExistingUserControllerTest() - : mock_login_display_(NULL), mock_user_manager_(NULL) {} + ExistingUserControllerTest() : mock_login_display_(NULL) {} ExistingUserController* existing_user_controller() { return ExistingUserController::current_controller(); @@ -132,11 +119,6 @@ DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); - mock_login_utils_ = new MockLoginUtils(); - LoginUtils::Set(mock_login_utils_); - EXPECT_CALL(*mock_login_utils_, DelegateDeleted(_)) - .Times(1); - mock_login_display_host_.reset(new MockLoginDisplayHost()); mock_login_display_ = new MockLoginDisplay(); SetUpLoginDisplay(); @@ -160,53 +142,14 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch(switches::kLoginManager); - } - - virtual void SetUpUserManager() { - // Replace the UserManager singleton with a mock. - mock_user_manager_ = new MockUserManager; - user_manager_enabler_.reset( - new ScopedUserManagerEnabler(mock_user_manager_)); - EXPECT_CALL(*mock_user_manager_, IsKnownUser(kUsername)) - .Times(AnyNumber()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_user_manager_, IsKnownUser(kNewUsername)) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, IsLoggedInAsGuest()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, IsLoggedInAsPublicAccount()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, IsSessionStarted()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, IsCurrentUserNew()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_user_manager_, Shutdown()) - .Times(1); - EXPECT_CALL(*mock_user_manager_, FindUser(_)) - .Times(AnyNumber()) - .WillRepeatedly(ReturnNull()); + command_line->AppendSwitch(switches::kForceLoginManagerInTests); } void SetUpOnMainThread() override { - testing_profile_.reset(new TestingProfile()); - SetUpUserManager(); existing_user_controller_.reset( new ExistingUserController(mock_login_display_host_.get())); ASSERT_EQ(existing_user_controller(), existing_user_controller_.get()); existing_user_controller_->Init(user_manager::UserList()); - profile_prepared_cb_ = - base::Bind(&ExistingUserController::OnProfilePrepared, - base::Unretained(existing_user_controller()), - testing_profile_.get(), - false); } void TearDownOnMainThread() override { @@ -217,8 +160,14 @@ // be deleted on the UI thread. existing_user_controller_.reset(); DevicePolicyCrosBrowserTest::InProcessBrowserTest::TearDownOnMainThread(); - testing_profile_.reset(NULL); - user_manager_enabler_.reset(); + + // Test case may be configured with the real user manager but empty user + // list initially. So network OOBE screen is initialized. + // Need to reset it manually so that we don't end up with CrosSettings + // observer that wasn't removed. + WizardController* controller = WizardController::default_controller(); + if (controller && controller->current_screen()) + controller->current_screen()->Hide(); } void ExpectLoginFailure() { @@ -233,6 +182,12 @@ .Times(1); } + void RegisterUser(const std::string& user_id) { + ListPrefUpdate users_pref(g_browser_process->local_state(), + "LoggedInUsers"); + users_pref->AppendIfNotPresent(new base::StringValue(user_id)); + } + // ExistingUserController private member accessors. base::OneShotTimer<ExistingUserController>* auto_login_timer() { return existing_user_controller()->auto_login_timer_.get(); @@ -257,45 +212,38 @@ MockLoginDisplay* mock_login_display_; scoped_ptr<MockLoginDisplayHost> mock_login_display_host_; - // Owned by LoginUtilsWrapper. - MockLoginUtils* mock_login_utils_; - - MockUserManager* mock_user_manager_; // Not owned. - scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_; - - scoped_ptr<TestingProfile> testing_profile_; - // Mock URLFetcher. MockURLFetcherFactory<SuccessFetcher> factory_; - base::Callback<void(void)> profile_prepared_cb_; - private: DISALLOW_COPY_AND_ASSIGN(ExistingUserControllerTest); }; +IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, PRE_ExistingUserLogin) { + RegisterUser(kUsername); +} + IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) { EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) .Times(2); UserContext user_context(kUsername); user_context.SetKey(Key(kPassword)); user_context.SetUserIDHash(kUsername); - EXPECT_CALL(*mock_login_utils_, CreateAuthenticator(_)) - .Times(1) - .WillOnce(WithArg<0>(CreateAuthenticator(user_context))); - EXPECT_CALL(*mock_login_utils_, PrepareProfile(user_context, _, _, _)) - .Times(1) - .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_, - &base::Callback<void(void)>::Run)); + test::UserSessionManagerTestApi session_manager_test_api( + UserSessionManager::GetInstance()); + session_manager_test_api.InjectStubUserContext(user_context); EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) .Times(1); EXPECT_CALL(*mock_login_display_host_, StartWizard(WizardController::kTermsOfServiceScreenName)) .Times(0); - EXPECT_CALL(*mock_user_manager_, IsCurrentUserNew()) - .Times(AnyNumber()) - .WillRepeatedly(Return(false)); + + content::WindowedNotificationObserver profile_prepared_observer( + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); existing_user_controller()->Login(user_context, SigninSpecifics()); + + profile_prepared_observer.Wait(); content::RunAllPendingInMessageLoop(); } @@ -361,9 +309,6 @@ SupervisedUserCreationScreen supervised_user_creation_screen( &mock_base_screen_delegate, &supervised_user_creation_screen_handler); - EXPECT_CALL(*mock_user_manager_, SetUserFlow(kUsername, _)) - .Times(1) - .WillOnce(WithArg<1>(Invoke(DeleteUserFlow))); supervised_user_creation_screen.AuthenticateManager(kUsername, kPassword); } @@ -454,23 +399,27 @@ .Times(AnyNumber()); } - void SetUpUserManager() override {} + void TearDownOnMainThread() override { + ExistingUserControllerTest::TearDownOnMainThread(); + + // Test case may be configured with the real user manager but empty user + // list initially. So network OOBE screen is initialized. + // Need to reset it manually so that we don't end up with CrosSettings + // observer that wasn't removed. + WizardController* controller = WizardController::default_controller(); + if (controller && controller->current_screen()) + controller->current_screen()->Hide(); + } void ExpectSuccessfulLogin(const UserContext& user_context) { - EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) - .Times(AnyNumber()); - EXPECT_CALL(*mock_login_utils_, CreateAuthenticator(_)) - .Times(1) - .WillOnce(WithArg<0>(CreateAuthenticator(user_context))); - EXPECT_CALL(*mock_login_utils_, PrepareProfile(user_context, _, _, _)) - .Times(1) - .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_, - &base::Callback<void(void)>::Run)); - EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) - .Times(1); + test::UserSessionManagerTestApi session_manager_test_api( + UserSessionManager::GetInstance()); + session_manager_test_api.InjectStubUserContext(user_context); EXPECT_CALL(*mock_login_display_host_, StartWizard(WizardController::kTermsOfServiceScreenName)) .Times(0); + EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)).Times(AnyNumber()); + EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)).Times(AnyNumber()); } void SetAutoLoginPolicy(const std::string& username, int delay) { @@ -583,6 +532,11 @@ user_context.SetUserIDHash(user_context.GetUserID()); ExpectSuccessfulLogin(user_context); existing_user_controller()->OnSigninScreenReady(); + + content::WindowedNotificationObserver profile_prepared_observer( + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); + SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginShortDelay); ASSERT_TRUE(auto_login_timer()); // Don't assert that timer is running: with the short delay sometimes @@ -597,6 +551,8 @@ runner.QuitClosure()); runner.Run(); + profile_prepared_observer.Wait(); + // Wait for login tasks to complete. content::RunAllPendingInMessageLoop(); } @@ -613,12 +569,18 @@ SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay); EXPECT_TRUE(auto_login_timer()); + content::WindowedNotificationObserver profile_prepared_observer( + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); + // Log in and check that it stopped the timer. existing_user_controller()->Login(user_context, SigninSpecifics()); EXPECT_TRUE(is_login_in_progress()); ASSERT_TRUE(auto_login_timer()); EXPECT_FALSE(auto_login_timer()->IsRunning()); + profile_prepared_observer.Wait(); + // Wait for login tasks to complete. content::RunAllPendingInMessageLoop(); @@ -633,9 +595,9 @@ .Times(2); UserContext user_context(kUsername); user_context.SetKey(Key(kPassword)); - EXPECT_CALL(*mock_login_utils_, CreateAuthenticator(_)) - .Times(1) - .WillOnce(WithArg<0>(CreateAuthenticator(user_context))); + test::UserSessionManagerTestApi session_manager_test_api( + UserSessionManager::GetInstance()); + session_manager_test_api.InjectStubUserContext(user_context); existing_user_controller()->OnSigninScreenReady(); SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay); @@ -671,11 +633,17 @@ SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay); EXPECT_TRUE(auto_login_timer()); + content::WindowedNotificationObserver profile_prepared_observer( + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); + // Check that login completes and stops the timer. existing_user_controller()->CompleteLogin(user_context); ASSERT_TRUE(auto_login_timer()); EXPECT_FALSE(auto_login_timer()->IsRunning()); + profile_prepared_observer.Wait(); + // Wait for login tasks to complete. content::RunAllPendingInMessageLoop(); @@ -695,6 +663,10 @@ SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay); EXPECT_TRUE(auto_login_timer()); + content::WindowedNotificationObserver profile_prepared_observer( + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); + // Login and check that it stopped the timer. existing_user_controller()->Login( UserContext(user_manager::USER_TYPE_PUBLIC_ACCOUNT, @@ -705,6 +677,8 @@ ASSERT_TRUE(auto_login_timer()); EXPECT_FALSE(auto_login_timer()->IsRunning()); + profile_prepared_observer.Wait(); + // Wait for login tasks to complete. content::RunAllPendingInMessageLoop();
diff --git a/chrome/browser/chromeos/login/fake_login_utils.cc b/chrome/browser/chromeos/login/fake_login_utils.cc deleted file mode 100644 index 21df5b0..0000000 --- a/chrome/browser/chromeos/login/fake_login_utils.cc +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/fake_login_utils.h" - -#include "base/callback.h" -#include "base/command_line.h" -#include "base/prefs/pref_service.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/ui/login_display_host.h" -#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" -#include "chrome/browser/chromeos/login/user_flow.h" -#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" -#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/first_run/first_run.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_profile.h" -#include "chromeos/login/auth/mock_authenticator.h" -#include "chromeos/login/auth/user_context.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/user_manager/user.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -FakeLoginUtils::FakeLoginUtils() : should_launch_browser_(false) {} - -FakeLoginUtils::~FakeLoginUtils() {} - -void FakeLoginUtils::DoBrowserLaunch(Profile* profile, - LoginDisplayHost* login_host) { - if (!ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) { - ChromeUserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile); - return; - } - login_host->BeforeSessionStart(); - if (should_launch_browser_) { - StartupBrowserCreator browser_creator; - chrome::startup::IsFirstRun first_run = - first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN - : chrome::startup::IS_NOT_FIRST_RUN; - ASSERT_TRUE(browser_creator.LaunchBrowser( - *base::CommandLine::ForCurrentProcess(), profile, base::FilePath(), - chrome::startup::IS_PROCESS_STARTUP, first_run, NULL)); - } - if (login_host) - login_host->Finalize(); - user_manager::UserManager::Get()->SessionStarted(); -} - -void FakeLoginUtils::PrepareProfile(const UserContext& user_context, - bool has_cookies, - bool has_active_session, - LoginUtils::Delegate* delegate) { - user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - user_manager->UserLoggedIn( - user_context.GetUserID(), user_context.GetUserIDHash(), false); - user_manager::User* user = - user_manager->FindUserAndModify(user_context.GetUserID()); - DCHECK(user); - - // Make sure that we get the real Profile instead of the login Profile. - user->set_profile_is_created(); - Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user); - SigninManagerFactory::GetForProfile(profile)->SetAuthenticatedUsername( - user_context.GetUserID()); - - if (user_manager->IsLoggedInAsSupervisedUser()) { - user_manager::User* active_user = user_manager->GetActiveUser(); - std::string supervised_user_sync_id = - ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId( - active_user->email()); - if (supervised_user_sync_id.empty()) - supervised_user_sync_id = "DUMMY ID"; - profile->GetPrefs()->SetString(prefs::kSupervisedUserId, - supervised_user_sync_id); - } - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, - content::NotificationService::AllSources(), - content::Details<Profile>(profile)); - - // Emulate UserSessionManager::InitializeUserSession() for now till - // FakeLoginUtils are deprecated. - bool browser_launched = false; - if (!user_manager->IsLoggedInAsKioskApp()) { - if (user_manager->IsCurrentUserNew()) { - NOTREACHED() << "Method not implemented."; - } else { - browser_launched = true; - LoginUtils::Get()->DoBrowserLaunch(profile, - LoginDisplayHostImpl::default_host()); - } - } - - if (delegate) - delegate->OnProfilePrepared(profile, browser_launched); -} - -void FakeLoginUtils::DelegateDeleted(LoginUtils::Delegate* delegate) { - NOTREACHED() << "Method not implemented."; -} - -scoped_refptr<Authenticator> FakeLoginUtils::CreateAuthenticator( - AuthStatusConsumer* consumer) { - authenticator_ = new MockAuthenticator(consumer, expected_user_context_); - return authenticator_; -} - -void FakeLoginUtils::SetExpectedCredentials(const UserContext& user_context) { - expected_user_context_ = user_context; - if (authenticator_.get()) { - static_cast<MockAuthenticator*>(authenticator_.get())-> - SetExpectedCredentials(user_context); - } -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/fake_login_utils.h b/chrome/browser/chromeos/login/fake_login_utils.h deleted file mode 100644 index 0696faf..0000000 --- a/chrome/browser/chromeos/login/fake_login_utils.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_FAKE_LOGIN_UTILS_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_FAKE_LOGIN_UTILS_H_ - -#include "chrome/browser/chromeos/login/login_utils.h" -#include "chromeos/login/auth/user_context.h" - -namespace chromeos { - -// This class emulates behavior of LoginUtils for browser tests. -// It provides: -// * Fake authentication. You can configure expected usernames and password for -// next auth attempt. -// * Preparing of profiles for authenticated users. -// * Launching browser for user, if |should_launch_browser_| set. -// * Correct communication with LoginDisplayHost and UserManager. -class FakeLoginUtils : public LoginUtils { - public: - FakeLoginUtils(); - ~FakeLoginUtils() override; - void DoBrowserLaunch(Profile* profile, LoginDisplayHost* login_host) override; - void PrepareProfile(const UserContext& user_context, - bool has_cookies, - bool has_active_session, - LoginUtils::Delegate* delegate) override; - void DelegateDeleted(LoginUtils::Delegate* delegate) override; - scoped_refptr<Authenticator> CreateAuthenticator( - AuthStatusConsumer* consumer) override; - - void SetExpectedCredentials(const UserContext& user_context); - void set_should_launch_browser(bool should_launch_browser) { - should_launch_browser_ = should_launch_browser; - } - - private: - scoped_refptr<Authenticator> authenticator_; - UserContext expected_user_context_; - bool should_launch_browser_; - - DISALLOW_COPY_AND_ASSIGN(FakeLoginUtils); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_FAKE_LOGIN_UTILS_H_
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 340dff9..890a1b7 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -807,6 +807,9 @@ IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) { StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure()); WaitForAppLaunchSuccess(); + KioskAppManager::App app; + ASSERT_TRUE(KioskAppManager::Get()->GetApp(test_app_id(), &app)); + EXPECT_FALSE(app.was_auto_launched_with_zero_delay); } IN_PROC_BROWSER_TEST_F(KioskTest, ZoomSupport) { @@ -1082,6 +1085,10 @@ EXPECT_TRUE(KioskAppManager::Get()->IsAutoLaunchEnabled()); WaitForAppLaunchSuccess(); + + KioskAppManager::App app; + ASSERT_TRUE(KioskAppManager::Get()->GetApp(test_app_id(), &app)); + EXPECT_TRUE(app.was_auto_launched_with_zero_delay); } IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) { @@ -1256,10 +1263,10 @@ // Trigger the code that handles auto-launch on enterprise devices. This would // normally be called from ShowLoginWizard(), which runs so early that it is - // not to inject an auto-launch policy before it runs. + // not possible to inject an auto-launch policy before it runs. LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host(); ASSERT_TRUE(login_display_host); - login_display_host->StartAppLaunch(test_app_id(), false); + login_display_host->StartAppLaunch(test_app_id(), false, true); // Check that no launch has started. EXPECT_FALSE(login_display_host->GetAppLaunchController());
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index 3f3b08ce..5fceb28 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -25,7 +25,6 @@ #include "base/strings/string_util.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" @@ -157,7 +156,7 @@ saved_ime_state_ = imm->GetActiveIMEState(); imm->SetState(saved_ime_state_->Clone()); - authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); + authenticator_ = UserSessionManager::GetInstance()->CreateAuthenticator(this); extended_authenticator_ = ExtendedAuthenticator::Create(this); delegate_.reset(new WebUIScreenLocker(this)); delegate_->LockScreen();
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc index 8de336e..d4c218cc0 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -21,7 +21,7 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/login/auth/key.h" -#include "chromeos/login/auth/mock_authenticator.h" +#include "chromeos/login/auth/stub_authenticator.h" #include "chromeos/login/auth/user_context.h" #include "chromeos/login/user_names.h" #include "content/public/browser/notification_service.h" @@ -156,7 +156,7 @@ UserContext user_context(chromeos::login::kStubUser); user_context.SetKey(Key("pass")); - tester->InjectMockAuthenticator(user_context); + tester->InjectStubUserContext(user_context); EXPECT_TRUE(tester->IsLocked()); tester->EnterPassword("fail"); content::RunAllPendingInMessageLoop(); @@ -205,7 +205,7 @@ } UserContext user_context(chromeos::login::kStubUser); user_context.SetKey(Key("pass")); - tester->InjectMockAuthenticator(user_context); + tester->InjectStubUserContext(user_context); tester->EnterPassword("pass"); content::RunAllPendingInMessageLoop(); EXPECT_FALSE(tester->IsLocked());
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc index f51d88cd..bdbe613 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc
@@ -14,12 +14,13 @@ #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chromeos/login/auth/auth_status_consumer.h" #include "chromeos/login/auth/fake_extended_authenticator.h" -#include "chromeos/login/auth/mock_authenticator.h" +#include "chromeos/login/auth/stub_authenticator.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/test/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/label.h" #include "ui/views/controls/textfield/textfield.h" @@ -199,11 +200,11 @@ ScreenLocker::screen_locker_->locked_; } -void ScreenLockerTester::InjectMockAuthenticator( +void ScreenLockerTester::InjectStubUserContext( const UserContext& user_context) { DCHECK(ScreenLocker::screen_locker_); ScreenLocker::screen_locker_->SetAuthenticator( - new MockAuthenticator(ScreenLocker::screen_locker_, user_context)); + new StubAuthenticator(ScreenLocker::screen_locker_, user_context)); ScreenLocker::screen_locker_->extended_authenticator_ = new FakeExtendedAuthenticator(ScreenLocker::screen_locker_, user_context); }
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.h b/chrome/browser/chromeos/login/lock/screen_locker_tester.h index 868a14c..a6e4014a 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.h +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.h
@@ -29,8 +29,8 @@ // Returns true if the screen is locked. virtual bool IsLocked(); - // Injects MockAuthenticator that uses the credentials in |user_context|. - virtual void InjectMockAuthenticator(const UserContext& user_context); + // Injects StubAuthenticator that uses the credentials in |user_context|. + virtual void InjectStubUserContext(const UserContext& user_context); // Sets the password text. virtual void SetPassword(const std::string& password) = 0;
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc index add5d60..64ea06a 100644 --- a/chrome/browser/chromeos/login/login_manager_test.cc +++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -8,6 +8,8 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" +#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" #include "chrome/browser/chromeos/login/ui/webui_login_view.h" #include "chromeos/chromeos_switches.h" @@ -44,11 +46,6 @@ void LoginManagerTest::SetUpInProcessBrowserTestFixture() { MixinBasedBrowserTest::SetUpInProcessBrowserTestFixture(); - mock_login_utils_ = new testing::NiceMock<MockLoginUtils>(); - mock_login_utils_->DelegateToFake(); - mock_login_utils_->GetFakeLoginUtils()->set_should_launch_browser( - should_launch_browser_); - LoginUtils::Set(mock_login_utils_); } void LoginManagerTest::SetUpOnMainThread() { @@ -57,6 +54,10 @@ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, content::NotificationService::AllSources()).Wait(); InitializeWebContents(); + test::UserSessionManagerTestApi session_manager_test_api( + UserSessionManager::GetInstance()); + session_manager_test_api.SetShouldLaunchBrowserInTests( + should_launch_browser_); } void LoginManagerTest::RegisterUser(const std::string& user_id) { @@ -65,7 +66,9 @@ } void LoginManagerTest::SetExpectedCredentials(const UserContext& user_context) { - login_utils().GetFakeLoginUtils()->SetExpectedCredentials(user_context); + test::UserSessionManagerTestApi session_manager_test_api( + UserSessionManager::GetInstance()); + session_manager_test_api.InjectStubUserContext(user_context); } bool LoginManagerTest::TryToLogin(const UserContext& user_context) {
diff --git a/chrome/browser/chromeos/login/login_manager_test.h b/chrome/browser/chromeos/login/login_manager_test.h index 3fc51031..e2b6921b 100644 --- a/chrome/browser/chromeos/login/login_manager_test.h +++ b/chrome/browser/chromeos/login/login_manager_test.h
@@ -8,7 +8,6 @@ #include <string> #include "chrome/browser/chromeos/login/mixin_based_browser_test.h" -#include "chrome/browser/chromeos/login/mock_login_utils.h" #include "chrome/browser/chromeos/login/test/js_checker.h" namespace content { @@ -63,8 +62,6 @@ // that it is true. void JSExpect(const std::string& expression); - MockLoginUtils& login_utils() { return *mock_login_utils_; } - content::WebContents* web_contents() { return web_contents_; } test::JSChecker& js_checker() { return js_checker_; } @@ -76,7 +73,6 @@ web_contents_ = web_contents; } - MockLoginUtils* mock_login_utils_; bool should_launch_browser_; content::WebContents* web_contents_; test::JSChecker js_checker_;
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc deleted file mode 100644 index 4ab088a..0000000 --- a/chrome/browser/chromeos/login/login_utils.cc +++ /dev/null
@@ -1,170 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/login_utils.h" - -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/singleton.h" -#include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" -#include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/session/user_session_manager.h" -#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/settings/cros_settings_names.h" - -namespace chromeos { - -class LoginUtilsImpl : public LoginUtils, - public UserSessionManagerDelegate { - public: - LoginUtilsImpl() - : delegate_(NULL) { - } - - ~LoginUtilsImpl() override {} - - // LoginUtils implementation: - void DoBrowserLaunch(Profile* profile, LoginDisplayHost* login_host) override; - void PrepareProfile(const UserContext& user_context, - bool has_auth_cookies, - bool has_active_session, - LoginUtils::Delegate* delegate) override; - void DelegateDeleted(LoginUtils::Delegate* delegate) override; - scoped_refptr<Authenticator> CreateAuthenticator( - AuthStatusConsumer* consumer) override; - - // UserSessionManager::Delegate implementation: - void OnProfilePrepared(Profile* profile, bool browser_launched) override; - - private: - // Has to be scoped_refptr, see comment for CreateAuthenticator(...). - scoped_refptr<Authenticator> authenticator_; - - // Delegate to be fired when the profile will be prepared. - LoginUtils::Delegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl); -}; - -class LoginUtilsWrapper { - public: - static LoginUtilsWrapper* GetInstance() { - return Singleton<LoginUtilsWrapper>::get(); - } - - LoginUtils* get() { - base::AutoLock create(create_lock_); - if (!ptr_.get()) - reset(new LoginUtilsImpl); - return ptr_.get(); - } - - void reset(LoginUtils* ptr) { - ptr_.reset(ptr); - } - - private: - friend struct DefaultSingletonTraits<LoginUtilsWrapper>; - - LoginUtilsWrapper() {} - - base::Lock create_lock_; - scoped_ptr<LoginUtils> ptr_; - - DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper); -}; - -void LoginUtilsImpl::DoBrowserLaunch(Profile* profile, - LoginDisplayHost* login_host) { - UserSessionManager::GetInstance()->DoBrowserLaunch(profile, login_host); -} - -void LoginUtilsImpl::PrepareProfile( - const UserContext& user_context, - bool has_auth_cookies, - bool has_active_session, - LoginUtils::Delegate* delegate) { - // TODO(nkostylev): We have to initialize LoginUtils delegate as long - // as it coexist with SessionManager. - delegate_ = delegate; - - UserSessionManager::StartSessionType start_session_type = - UserAddingScreen::Get()->IsRunning() ? - UserSessionManager::SECONDARY_USER_SESSION : - UserSessionManager::PRIMARY_USER_SESSION; - - // For the transition part LoginUtils will just delegate profile - // creation and initialization to SessionManager. Later LoginUtils will be - // removed and all LoginUtils clients will just work with SessionManager - // directly. - UserSessionManager::GetInstance()->StartSession(user_context, - start_session_type, - authenticator_, - has_auth_cookies, - has_active_session, - this); -} - -void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) { - if (delegate_ == delegate) - delegate_ = NULL; -} - -scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator( - AuthStatusConsumer* consumer) { - // Screen locker needs new Authenticator instance each time. - if (ScreenLocker::default_screen_locker()) { - if (authenticator_.get()) - authenticator_->SetConsumer(NULL); - authenticator_ = NULL; - } - - if (authenticator_.get() == NULL) { - authenticator_ = new ChromeCryptohomeAuthenticator(consumer); - } else { - // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. - authenticator_->SetConsumer(consumer); - } - return authenticator_; -} - -void LoginUtilsImpl::OnProfilePrepared(Profile* profile, - bool browser_launched) { - if (delegate_) - delegate_->OnProfilePrepared(profile, browser_launched); -} - -// static -LoginUtils* LoginUtils::Get() { - return LoginUtilsWrapper::GetInstance()->get(); -} - -// static -void LoginUtils::Set(LoginUtils* mock) { - LoginUtilsWrapper::GetInstance()->reset(mock); -} - -// static -bool LoginUtils::IsWhitelisted(const std::string& username, - bool* wildcard_match) { - // Skip whitelist check for tests. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kOobeSkipPostLogin)) { - return true; - } - - CrosSettings* cros_settings = CrosSettings::Get(); - bool allow_new_user = false; - cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); - if (allow_new_user) - return true; - return cros_settings->FindEmailInList( - kAccountsPrefUsers, username, wildcard_match); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_utils.h b/chrome/browser/chromeos/login/login_utils.h deleted file mode 100644 index e532d0f..0000000 --- a/chrome/browser/chromeos/login/login_utils.h +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_UTILS_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_UTILS_H_ - -#include <string> - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" - -class PrefService; -class Profile; - -namespace base { -class CommandLine; -} - -namespace chromeos { - -class Authenticator; -class LoginDisplayHost; -class AuthStatusConsumer; -class UserContext; - -class LoginUtils { - public: - class Delegate { - public: - // Called after profile is loaded and prepared for the session. - // |browser_launched| will be true is browser has been launched, otherwise - // it will return false and client is responsible on launching browser. - virtual void OnProfilePrepared(Profile* profile, - bool browser_launched) = 0; - - protected: - virtual ~Delegate() {} - }; - - // Get LoginUtils singleton object. If it was not set before, new default - // instance will be created. - static LoginUtils* Get(); - - // Set LoginUtils singleton object for test purpose only! - static void Set(LoginUtils* ptr); - - // Checks if the given username is whitelisted and allowed to sign-in to - // this device. |wildcard_match| may be NULL. If it's present, it'll be set to - // true if the whitelist check was satisfied via a wildcard. - static bool IsWhitelisted(const std::string& username, bool* wildcard_match); - - virtual ~LoginUtils() {} - - // Thin wrapper around StartupBrowserCreator::LaunchBrowser(). Meant to be - // used in a Task posted to the UI thread. Once the browser is launched the - // login host is deleted. - virtual void DoBrowserLaunch(Profile* profile, - LoginDisplayHost* login_host) = 0; - - // Loads and prepares profile for the session. Fires |delegate| in the end. - // |user_context.username_hash| defines when user homedir is mounted. - // Also see DelegateDeleted method. - // If |has_active_session| is true than this is a case of restoring user - // session after browser crash so no need to start new session. - virtual void PrepareProfile( - const UserContext& user_context, - bool has_auth_cookies, - bool has_active_session, - Delegate* delegate) = 0; - - // Invalidates |delegate|, which was passed to PrepareProfile method call. - virtual void DelegateDeleted(Delegate* delegate) = 0; - - // Creates and returns the authenticator to use. - // Before WebUI login (Up to R14) the caller owned the returned - // Authenticator instance and had to delete it when done. - // New instance was created on each new login attempt. - // Starting with WebUI login (R15) single Authenticator instance is used for - // entire login process, even for multiple retries. Authenticator instance - // holds reference to login profile and is later used during fetching of - // OAuth tokens. - // TODO(nkostylev): Cleanup after WebUI login migration is complete. - virtual scoped_refptr<Authenticator> CreateAuthenticator( - AuthStatusConsumer* consumer) = 0; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_UTILS_H_
diff --git a/chrome/browser/chromeos/login/mock_login_utils.cc b/chrome/browser/chromeos/login/mock_login_utils.cc deleted file mode 100644 index 23e6a95..0000000 --- a/chrome/browser/chromeos/login/mock_login_utils.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/mock_login_utils.h" - -#include "chromeos/login/auth/user_context.h" - -using namespace testing; - -namespace chromeos { - -MockLoginUtils::MockLoginUtils() {} - -MockLoginUtils::~MockLoginUtils() {} - -void MockLoginUtils::DelegateToFake() { - if (fake_login_utils_.get()) - return; - fake_login_utils_.reset(new FakeLoginUtils()); - FakeLoginUtils* fake = fake_login_utils_.get(); - ON_CALL(*this, DoBrowserLaunch(_, _)) - .WillByDefault(Invoke(fake, &FakeLoginUtils::DoBrowserLaunch)); - ON_CALL(*this, PrepareProfile(_, _, _, _)) - .WillByDefault(Invoke(fake, &FakeLoginUtils::PrepareProfile)); - ON_CALL(*this, CreateAuthenticator(_)) - .WillByDefault(Invoke(fake, &FakeLoginUtils::CreateAuthenticator)); -} - -FakeLoginUtils* MockLoginUtils::GetFakeLoginUtils() { - return fake_login_utils_.get(); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/mock_login_utils.h b/chrome/browser/chromeos/login/mock_login_utils.h deleted file mode 100644 index 5c6dd88f..0000000 --- a/chrome/browser/chromeos/login/mock_login_utils.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_MOCK_LOGIN_UTILS_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_MOCK_LOGIN_UTILS_H_ - -#include <string> - -#include "base/command_line.h" -#include "base/memory/ref_counted.h" -#include "chrome/browser/chromeos/login/fake_login_utils.h" -#include "chrome/browser/chromeos/login/login_utils.h" -#include "chrome/browser/chromeos/login/ui/login_display_host.h" -#include "chromeos/login/auth/authenticator.h" -#include "google_apis/gaia/gaia_auth_consumer.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "url/gurl.h" - -class Profile; - -namespace chromeos { - -class AuthStatusConsumer; -class UserContext; - -class MockLoginUtils : public LoginUtils { - public: - MockLoginUtils(); - virtual ~MockLoginUtils(); - - MOCK_METHOD2(DoBrowserLaunch, void(Profile*, LoginDisplayHost*)); - MOCK_METHOD4(PrepareProfile, - void(const UserContext&, - bool, bool, LoginUtils::Delegate*)); - MOCK_METHOD1(DelegateDeleted, void(LoginUtils::Delegate*)); - MOCK_METHOD1(CreateAuthenticator, - scoped_refptr<Authenticator>(AuthStatusConsumer*)); - - void DelegateToFake(); - FakeLoginUtils* GetFakeLoginUtils(); - - private: - scoped_ptr<FakeLoginUtils> fake_login_utils_; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_MOCK_LOGIN_UTILS_H_
diff --git a/chrome/browser/chromeos/login/screens/network_screen.cc b/chrome/browser/chromeos/login/screens/network_screen.cc index 5c65da6f..f451b52 100644 --- a/chrome/browser/chromeos/login/screens/network_screen.cc +++ b/chrome/browser/chromeos/login/screens/network_screen.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/chromeos/customization/customization_document.h" #include "chrome/browser/chromeos/login/help_app_launcher.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/screen_manager.h" #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" #include "chrome/browser/chromeos/login/screens/network_view.h" @@ -61,7 +60,10 @@ view_->Bind(*this); input_method::InputMethodManager::Get()->AddObserver(this); + InitializeTimezoneObserver(); +} +void NetworkScreen::InitializeTimezoneObserver() { timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( kSystemTimezone, base::Bind(&NetworkScreen::OnSystemTimezoneChanged, base::Unretained(this))); @@ -96,11 +98,15 @@ SetApplicationLocale(startup_manifest->initial_locale_default()); } + if (!timezone_subscription_) + InitializeTimezoneObserver(); + if (view_) view_->Show(); } void NetworkScreen::Hide() { + timezone_subscription_.reset(); if (view_) view_->Hide(); }
diff --git a/chrome/browser/chromeos/login/screens/network_screen.h b/chrome/browser/chromeos/login/screens/network_screen.h index 8350d06..5c8cc2d 100644 --- a/chrome/browser/chromeos/login/screens/network_screen.h +++ b/chrome/browser/chromeos/login/screens/network_screen.h
@@ -96,6 +96,9 @@ FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, Timeout); FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, CanConnect); + // Subscribe to timezone changes. + void InitializeTimezoneObserver(); + // Subscribes NetworkScreen to the network change notification, // forces refresh of current network state. void Refresh();
diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc index 5d968b2..5ca1b54 100644 --- a/chrome/browser/chromeos/login/screens/user_image_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/camera_presence_notifier.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/screen_manager.h" #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" #include "chrome/browser/chromeos/login/screens/user_image_view.h" @@ -300,6 +299,10 @@ void UserImageScreen::Hide() { CameraPresenceNotifier::GetInstance()->RemoveObserver(this); notification_registrar_.RemoveAll(); + policy_registrar_.reset(); + sync_timer_.reset(); + if (UserImageSyncObserver* sync_observer = GetSyncObserver()) + sync_observer->RemoveObserver(this); if (view_) view_->Hide(); }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index e04283061..7b7dfd1 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -30,9 +30,11 @@ #include "chrome/browser/chromeos/boot_times_recorder.h" #include "chrome/browser/chromeos/first_run/first_run.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" +#include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" #include "chrome/browser/chromeos/login/chrome_restart_request.h" #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" +#include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/login/profile_auth_data.h" #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h" @@ -75,6 +77,7 @@ #include "chromeos/dbus/cryptohome_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" +#include "chromeos/login/auth/stub_authenticator.h" #include "chromeos/login/user_names.h" #include "chromeos/network/portal_detector/network_portal_detector.h" #include "chromeos/network/portal_detector/network_portal_detector_strategy.h" @@ -313,14 +316,16 @@ } UserSessionManager::UserSessionManager() - : delegate_(NULL), + : delegate_(nullptr), + authenticator_(nullptr), has_auth_cookies_(false), user_sessions_restored_(false), user_sessions_restore_in_progress_(false), exit_after_session_restore_(false), session_restore_strategy_( OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN), - running_easy_unlock_key_ops_(false) { + running_easy_unlock_key_ops_(false), + should_launch_browser_(true) { net::NetworkChangeNotifier::AddConnectionTypeObserver(this); user_manager::UserManager::Get()->AddSessionStateObserver(this); } @@ -365,14 +370,35 @@ RestartChrome(cmd_line_str); } +scoped_refptr<Authenticator> UserSessionManager::CreateAuthenticator( + AuthStatusConsumer* consumer) { + // Screen locker needs new Authenticator instance each time. + if (ScreenLocker::default_screen_locker()) { + if (authenticator_.get()) + authenticator_->SetConsumer(NULL); + authenticator_ = NULL; + } + + if (authenticator_.get() == NULL) { + if (injected_user_context_) { + authenticator_ = + new StubAuthenticator(consumer, *injected_user_context_.get()); + } else { + authenticator_ = new ChromeCryptohomeAuthenticator(consumer); + } + } else { + // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. + authenticator_->SetConsumer(consumer); + } + return authenticator_; +} + void UserSessionManager::StartSession( const UserContext& user_context, StartSessionType start_session_type, - scoped_refptr<Authenticator> authenticator, bool has_auth_cookies, bool has_active_session, UserSessionManagerDelegate* delegate) { - authenticator_ = authenticator; delegate_ = delegate; start_session_type_ = start_session_type; @@ -390,6 +416,11 @@ PrepareProfile(); } +void UserSessionManager::DelegateDeleted(UserSessionManagerDelegate* delegate) { + if (delegate_ == delegate) + delegate_ = nullptr; +} + void UserSessionManager::PerformPostUserLoggedInActions() { user_manager::UserManager* user_manager = user_manager::UserManager::Get(); if (user_manager->GetLoggedInUsers().size() == 1) { @@ -989,7 +1020,7 @@ bool browser_launched = InitializeUserSession(profile); // TODO(nkostylev): This pointer should probably never be NULL, but it looks - // like LoginUtilsImpl::OnProfileCreated() may be getting called before + // like OnProfileCreated() may be getting called before // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is // killed during shutdown in tests -- see http://crosbug.com/18269. Replace // this 'if' statement with a CHECK(delegate_) once the underlying issue is @@ -1074,8 +1105,7 @@ } } - LoginUtils::Get()->DoBrowserLaunch(profile, - LoginDisplayHostImpl::default_host()); + DoBrowserLaunch(profile, LoginDisplayHostImpl::default_host()); return true; } @@ -1288,7 +1318,6 @@ // (and session) has been loaded on Chrome startup. StartSession(user_context, SECONDARY_USER_SESSION_AFTER_CRASH, - NULL, // authenticator false, // has_auth_cookies true, // has_active_session, this is restart after crash this); @@ -1451,18 +1480,22 @@ VLOG(1) << "Launching browser..."; TRACE_EVENT0("login", "LaunchBrowser"); - StartupBrowserCreator browser_creator; - int return_code; - chrome::startup::IsFirstRun first_run = - ::first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN - : chrome::startup::IS_NOT_FIRST_RUN; + if (should_launch_browser_) { + StartupBrowserCreator browser_creator; + chrome::startup::IsFirstRun first_run = + ::first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN + : chrome::startup::IS_NOT_FIRST_RUN; - browser_creator.LaunchBrowser( - *base::CommandLine::ForCurrentProcess(), profile, base::FilePath(), - chrome::startup::IS_PROCESS_STARTUP, first_run, &return_code); + browser_creator.LaunchBrowser( + *base::CommandLine::ForCurrentProcess(), profile, base::FilePath(), + chrome::startup::IS_PROCESS_STARTUP, first_run); - // Triggers app launcher start page service to load start page web contents. - app_list::StartPageService::Get(profile); + // Triggers app launcher start page service to load start page web contents. + app_list::StartPageService::Get(profile); + } else { + LOG(WARNING) << "Browser hasn't been launched, should_launch_browser_" + << " is false. This is normal in some tests."; + } // Mark login host for deletion after browser starts. This // guarantees that the message loop will be referenced by the @@ -1503,4 +1536,10 @@ default_ime_states_.erase(profile); } +void UserSessionManager::InjectStubUserContext( + const UserContext& user_context) { + injected_user_context_.reset(new UserContext(user_context)); + authenticator_ = NULL; +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h index 3d47ce53..88f9118 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.h +++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -29,13 +29,15 @@ class Profile; namespace user_manager { - class User; - } // namespace user_manager namespace chromeos { +namespace test { +class UserSessionManagerTestApi; +} // namespace test + class EasyUnlockKeyManager; class InputEventsBlocker; class LoginDisplayHost; @@ -104,15 +106,24 @@ // |start_url| is an optional URL to be opened in Guest session browser. void CompleteGuestSessionLogin(const GURL& start_url); - // Start user session given |user_context| and |authenticator| which holds - // authentication context (profile). + // Creates and returns the authenticator to use. + // Single Authenticator instance is used for entire login process, + // even for multiple retries. Authenticator instance holds reference to + // login profile and is later used during fetching of OAuth tokens. + scoped_refptr<Authenticator> CreateAuthenticator( + AuthStatusConsumer* consumer); + + // Start user session given |user_context|. + // OnProfilePrepared() will be called on |delegate| once Profile is ready. void StartSession(const UserContext& user_context, StartSessionType start_session_type, - scoped_refptr<Authenticator> authenticator, bool has_auth_cookies, bool has_active_session, UserSessionManagerDelegate* delegate); + // Invalidates |delegate|, which was passed to StartSession method call. + void DelegateDeleted(UserSessionManagerDelegate* delegate); + // Perform additional actions once system wide notification // "UserLoggedIn" has been sent. void PerformPostUserLoggedInActions(); @@ -213,6 +224,7 @@ void RemoveProfileForTesting(Profile* profile); private: + friend class test::UserSessionManagerTestApi; friend struct DefaultSingletonTraits<UserSessionManager>; typedef std::set<std::string> SigninSessionRestoreStateSet; @@ -328,6 +340,18 @@ InputEventsBlocker* input_events_blocker, const locale_util::LanguageSwitchResult& result); + // Test API methods. + + // Injects |user_context| that will be used to create StubAuthenticator + // instance when CreateAuthenticator() is called. + void InjectStubUserContext(const UserContext& user_context); + + // Controls whether browser instance should be launched after sign in + // (used in tests). + void set_should_launch_browser_in_tests(bool should_launch_browser) { + should_launch_browser_ = should_launch_browser; + } + UserSessionManagerDelegate* delegate_; // Authentication/user context. @@ -335,6 +359,9 @@ scoped_refptr<Authenticator> authenticator_; StartSessionType start_session_type_; + // Injected user context for stub authenticator. + scoped_ptr<UserContext> injected_user_context_; + // True if the authentication context's cookie jar contains authentication // cookies from the authentication extension login flow. bool has_auth_cookies_; @@ -383,6 +410,9 @@ bool running_easy_unlock_key_ops_; base::Closure easy_unlock_key_ops_finished_callback_; + // Whether should launch browser, tests may override this value. + bool should_launch_browser_; + DISALLOW_COPY_AND_ASSIGN(UserSessionManager); };
diff --git a/chrome/browser/chromeos/login/session/user_session_manager_test_api.cc b/chrome/browser/chromeos/login/session/user_session_manager_test_api.cc new file mode 100644 index 0000000..6f5ae21 --- /dev/null +++ b/chrome/browser/chromeos/login/session/user_session_manager_test_api.cc
@@ -0,0 +1,26 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" + +namespace chromeos { +namespace test { + +UserSessionManagerTestApi::UserSessionManagerTestApi( + UserSessionManager* session_manager) + : session_manager_(session_manager) { +} + +void UserSessionManagerTestApi::InjectStubUserContext( + const UserContext& user_context) { + session_manager_->InjectStubUserContext(user_context); +} + +void UserSessionManagerTestApi::SetShouldLaunchBrowserInTests( + bool should_launch_browser) { + session_manager_->set_should_launch_browser_in_tests(should_launch_browser); +} + +} // namespace test +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/user_session_manager_test_api.h b/chrome/browser/chromeos/login/session/user_session_manager_test_api.h new file mode 100644 index 0000000..d811470 --- /dev/null +++ b/chrome/browser/chromeos/login/session/user_session_manager_test_api.h
@@ -0,0 +1,36 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SESSION_USER_SESSION_MANAGER_TEST_API_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SESSION_USER_SESSION_MANAGER_TEST_API_H_ + +#include "base/basictypes.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" + +namespace chromeos { +namespace test { + +// Accesses private data from a UserSessionManager for testing. +class UserSessionManagerTestApi { + public: + explicit UserSessionManagerTestApi(UserSessionManager* session_manager); + + // Injects |user_context| that will be used to create StubAuthenticator + // instance when UserSessionManager::CreateAuthenticator() is called. + void InjectStubUserContext(const UserContext& user_context); + + // Controls whether browser instance should be launched after sign in + // (used in tests). + void SetShouldLaunchBrowserInTests(bool should_launch_browser); + + private: + UserSessionManager* session_manager_; // not owned + + DISALLOW_COPY_AND_ASSIGN(UserSessionManagerTestApi); +}; + +} // namespace test +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SESSION_USER_SESSION_MANAGER_TEST_API_H_
diff --git a/chrome/browser/chromeos/login/session_login_browsertest.cc b/chrome/browser/chromeos/login/session_login_browsertest.cc index e04c0dd..bdfdb1c 100644 --- a/chrome/browser/chromeos/login/session_login_browsertest.cc +++ b/chrome/browser/chromeos/login/session_login_browsertest.cc
@@ -4,6 +4,7 @@ #include "ash/session/session_state_delegate.h" #include "ash/shell.h" +#include "base/command_line.h" #include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc index d474bf43..48bdb7b6 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -621,15 +621,13 @@ // Get fake URL for fake google.com. const GURL& server_url = embedded_test_server()->base_url(); - std::string google_host("www.google.com"); GURL::Replacements replace_google_host; - replace_google_host.SetHostStr(google_host); + replace_google_host.SetHostStr("www.google.com"); GURL google_url = server_url.ReplaceComponents(replace_google_host); fake_google_page_url_ = google_url.Resolve(kHelloPagePath); - std::string non_google_host("www.somethingelse.org"); GURL::Replacements replace_non_google_host; - replace_non_google_host.SetHostStr(non_google_host); + replace_non_google_host.SetHostStr("www.somethingelse.org"); GURL non_google_url = server_url.ReplaceComponents(replace_non_google_host); non_google_page_url_ = non_google_url.Resolve(kRandomPagePath); }
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc index 39d5e41e..cbbbc6e 100644 --- a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc +++ b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc
@@ -11,7 +11,7 @@ #include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" #include "base/values.h" -#include "chrome/browser/chromeos/login/login_utils.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h" @@ -252,7 +252,7 @@ } void SupervisedUserLoginFlow::Finish() { - LoginUtils::Get()->DoBrowserLaunch(profile_, host()); + UserSessionManager::GetInstance()->DoBrowserLaunch(profile_, host()); profile_ = NULL; UnregisterFlowSoon(); }
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc index c5efa20..64bec8af0 100644 --- a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc +++ b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
@@ -368,7 +368,6 @@ user_manager::UserManager::Get()->GetUsers().at(user_index); ASSERT_EQ(base::UTF8ToUTF16(expected_display_name), user->display_name()); - // Currently FakeLoginUtils do not support first-run use cases. // Clean first run flag before logging in. static_cast<SupervisedUserManagerImpl*>( ChromeUserManager::Get()->GetSupervisedUserManager())
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index ea0d3f0d..14819b7 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -93,9 +93,8 @@ // webstore in chrome_resource_dispatcher_host_delegate.cc. const GURL& server_url = embedded_test_server()->base_url(); - std::string gaia_host("gaia"); GURL::Replacements replace_gaia_host; - replace_gaia_host.SetHostStr(gaia_host); + replace_gaia_host.SetHostStr("gaia"); GURL gaia_url = server_url.ReplaceComponents(replace_gaia_host); command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec()); command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec());
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.h b/chrome/browser/chromeos/login/ui/login_display_host.h index 18032e6..d0f06bf 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host.h +++ b/chrome/browser/chromeos/login/ui/login_display_host.h
@@ -89,9 +89,11 @@ // Initiates authentication network prewarming. virtual void PrewarmAuthentication() = 0; - // Starts app launch splash screen. + // Starts app launch splash screen. If |is_auto_launch| is true, the app is + // being auto-launched with no delay. virtual void StartAppLaunch(const std::string& app_id, - bool diagnostic_mode) = 0; + bool diagnostic_mode, + bool is_auto_launch) = 0; // Starts the demo app launch. virtual void StartDemoAppLaunch() = 0;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc index b1634642..7e843cc8 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" #include "chrome/browser/chromeos/login/startup_utils.h" @@ -668,7 +667,8 @@ } void LoginDisplayHostImpl::StartAppLaunch(const std::string& app_id, - bool diagnostic_mode) { + bool diagnostic_mode, + bool auto_launch) { VLOG(1) << "Login WebUI >> start app launch."; SetStatusAreaVisible(false); @@ -679,7 +679,8 @@ &LoginDisplayHostImpl::StartAppLaunch, pointer_factory_.GetWeakPtr(), app_id, - diagnostic_mode)); + diagnostic_mode, + auto_launch)); if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED) return; @@ -709,7 +710,7 @@ app_launch_controller_.reset(new AppLaunchController( app_id, diagnostic_mode, this, GetOobeUI())); - app_launch_controller_->StartAppLaunch(); + app_launch_controller_->StartAppLaunch(auto_launch); } //////////////////////////////////////////////////////////////////////////////// @@ -1190,8 +1191,11 @@ if (show_app_launch_splash_screen) { const std::string& auto_launch_app_id = KioskAppManager::Get()->GetAutoLaunchApp(); + const bool diagnostic_mode = false; + const bool auto_launch = true; display_host->StartAppLaunch(auto_launch_app_id, - false /* diagnostic_mode */); + diagnostic_mode, + auto_launch); return; }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.h b/chrome/browser/chromeos/login/ui/login_display_host_impl.h index 619e1d1..9d31b2f 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.h +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.h
@@ -83,7 +83,10 @@ void StartSignInScreen(const LoginScreenContext& context) override; void OnPreferencesChanged() override; void PrewarmAuthentication() override; - void StartAppLaunch(const std::string& app_id, bool diagnostic_mode) override; + void StartAppLaunch( + const std::string& app_id, + bool diagnostic_mode, + bool auto_launch) override; void StartDemoAppLaunch() override; // Creates WizardController instance.
diff --git a/chrome/browser/chromeos/login/ui/mock_login_display_host.h b/chrome/browser/chromeos/login/ui/mock_login_display_host.h index 357c9da..9ac83d2 100644 --- a/chrome/browser/chromeos/login/ui/mock_login_display_host.h +++ b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
@@ -35,7 +35,7 @@ MOCK_METHOD0(ResumeSignInScreen, void(void)); MOCK_METHOD0(OnPreferencesChanged, void(void)); MOCK_METHOD0(PrewarmAuthentication, void(void)); - MOCK_METHOD2(StartAppLaunch, void(const std::string&, bool)); + MOCK_METHOD3(StartAppLaunch, void(const std::string&, bool, bool)); MOCK_METHOD0(StartDemoAppLaunch, void(void)); private:
diff --git a/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc b/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc index 39a1ebc2..e406267 100644 --- a/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc
@@ -91,7 +91,6 @@ } IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, CancelAdding) { - EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(1); EXPECT_EQ(3u, user_manager::UserManager::Get()->GetUsers().size()); EXPECT_EQ(0u, user_manager::UserManager::Get()->GetLoggedInUsers().size()); @@ -136,7 +135,6 @@ EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_PRIMARY, ash::Shell::GetInstance()->session_state_delegate()-> GetSessionState()); - EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(3); LoginUser(kTestUsers[0]); EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE, ash::Shell::GetInstance()->session_state_delegate()->
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc index 48309e4..e0213a6 100644 --- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -81,17 +81,29 @@ void FakeChromeUserManager::SetUserFlow(const std::string& email, UserFlow* flow) { + ResetUserFlow(email); + specific_flows_[email] = flow; } UserFlow* FakeChromeUserManager::GetCurrentUserFlow() const { - return nullptr; + if (!IsUserLoggedIn()) + return GetDefaultUserFlow(); + return GetUserFlow(GetLoggedInUser()->email()); } UserFlow* FakeChromeUserManager::GetUserFlow(const std::string& email) const { - return nullptr; + FlowMap::const_iterator it = specific_flows_.find(email); + if (it != specific_flows_.end()) + return it->second; + return GetDefaultUserFlow(); } void FakeChromeUserManager::ResetUserFlow(const std::string& email) { + FlowMap::iterator it = specific_flows_.find(email); + if (it != specific_flows_.end()) { + delete it->second; + specific_flows_.erase(it); + } } void FakeChromeUserManager::SwitchActiveUser(const std::string& email) { @@ -150,4 +162,10 @@ return result; } +UserFlow* FakeChromeUserManager::GetDefaultUserFlow() const { + if (!default_flow_.get()) + default_flow_.reset(new DefaultUserFlow()); + return default_flow_.get(); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h index 3a51cf4..d43ae334 100644 --- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -69,11 +69,23 @@ } private: + // Lazily creates default user flow. + UserFlow* GetDefaultUserFlow() const; + scoped_ptr<FakeSupervisedUserManager> supervised_user_manager_; std::string owner_email_; MultiProfileUserController* multi_profile_user_controller_; + typedef std::map<std::string, UserFlow*> FlowMap; + + // Lazy-initialized default flow. + mutable scoped_ptr<UserFlow> default_flow_; + + // Specific flows by user e-mail. + // Keys should be canonicalized before access. + FlowMap specific_flows_; + DISALLOW_COPY_AND_ASSIGN(FakeChromeUserManager); };
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index b48c7d80..8ec067b1 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/hwid_checker.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/screens/device_disabled_screen.h" #include "chrome/browser/chromeos/login/screens/enable_debugging_screen.h" #include "chrome/browser/chromeos/login/screens/error_screen.h" @@ -44,6 +43,7 @@ #include "chrome/browser/chromeos/login/screens/update_screen.h" #include "chrome/browser/chromeos/login/screens/user_image_screen.h" #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h" +#include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" @@ -647,8 +647,8 @@ // Launch browser and delete login host controller. BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&LoginUtils::DoBrowserLaunch, - base::Unretained(LoginUtils::Get()), + base::Bind(&UserSessionManager::DoBrowserLaunch, + base::Unretained(UserSessionManager::GetInstance()), ProfileManager::GetActiveUserProfile(), host_)); host_ = NULL; } @@ -1111,7 +1111,9 @@ return; } - host_->StartAppLaunch(app_id, false /* diagnostic_mode */); + const bool diagnostic_mode = false; + const bool auto_launch = true; + host_->StartAppLaunch(app_id, diagnostic_mode, auto_launch); } // static
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc index 491b80a1..a33dd88 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc +++ b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
@@ -19,6 +19,7 @@ #include "components/captive_portal/captive_portal_testing_utils.h" #include "content/public/test/test_utils.h" #include "dbus/object_path.h" +#include "net/base/net_errors.h" #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_observer.h"
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys.cc b/chrome/browser/chromeos/platform_keys/platform_keys.cc index db5c4bec..e14fc58 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys.cc
@@ -11,6 +11,12 @@ const char kTokenIdUser[] = "user"; const char kTokenIdSystem[] = "system"; +ClientCertificateRequest::ClientCertificateRequest() { +} + +ClientCertificateRequest::~ClientCertificateRequest() { +} + } // namespace platform_keys } // namespace chromeos
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys.h b/chrome/browser/chromeos/platform_keys/platform_keys.h index b16504e9..05d0deff 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "net/ssl/ssl_client_cert_type.h" namespace content { class BrowserContext; @@ -43,6 +44,19 @@ HASH_ALGORITHM_SHA512 }; +struct ClientCertificateRequest { + ClientCertificateRequest(); + ~ClientCertificateRequest(); + + // The list of the types of certificates requested, sorted in order of the + // server's preference. + std::vector<net::SSLClientCertType> certificate_key_types; + + // List of distinguished names of certificate authorities allowed by the + // server. Each entry must be a DER-encoded X.509 DistinguishedName. + std::vector<std::string> certificate_authorities; +}; + namespace subtle { // Functions of this namespace shouldn't be called directly from the context of // an extension. Instead use PlatformKeysService which enforces restrictions @@ -77,6 +91,20 @@ const SignCallback& callback, content::BrowserContext* browser_context); +// If the certificate request could be processed successfully, |matches| will +// contain the list of matching certificates (which may be empty) and +// |error_message| will be empty. If an error occurred, |matches| will be null +// and |error_message| contain an error message. +typedef base::Callback<void(scoped_ptr<net::CertificateList> matches, + const std::string& error_message)> + SelectCertificatesCallback; + +// Returns the list of all certificates that match |request|. |callback| will be +// invoked with these matches or an error message. +void SelectClientCertificates(const ClientCertificateRequest& request, + const SelectCertificatesCallback& callback, + content::BrowserContext* browser_context); + } // namespace subtle // If the list of certificates could be successfully retrieved, |certs| will
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc index cb0752b..e9e3255 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -16,8 +16,15 @@ #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" #include "base/threading/worker_pool.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" #include "chrome/browser/net/nss_context.h" +#include "chrome/browser/profiles/profile.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "crypto/rsa_private_key.h" @@ -26,6 +33,8 @@ #include "net/cert/cert_database.h" #include "net/cert/nss_cert_database.h" #include "net/cert/x509_certificate.h" +#include "net/ssl/client_cert_store_chromeos.h" +#include "net/ssl/ssl_cert_request_info.h" using content::BrowserContext; using content::BrowserThread; @@ -188,6 +197,39 @@ subtle::SignCallback callback_; }; +class SelectCertificatesState : public NSSOperationState { + public: + explicit SelectCertificatesState( + const std::string& username_hash, + const bool use_system_key_slot, + scoped_refptr<net::SSLCertRequestInfo> request, + const subtle::SelectCertificatesCallback& callback); + ~SelectCertificatesState() override {} + + void OnError(const tracked_objects::Location& from, + const std::string& error_message) override { + CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, + error_message); + } + + void CallBack(const tracked_objects::Location& from, + scoped_ptr<net::CertificateList> matches, + const std::string& error_message) { + origin_task_runner_->PostTask( + from, base::Bind(callback_, base::Passed(&matches), error_message)); + } + + const std::string username_hash_; + const bool use_system_key_slot_; + scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; + scoped_ptr<net::ClientCertStore> cert_store_; + scoped_ptr<net::CertificateList> certs_; + + private: + // Must be called on origin thread, therefore use CallBack(). + subtle::SelectCertificatesCallback callback_; +}; + class GetCertificatesState : public NSSOperationState { public: explicit GetCertificatesState(const GetCertificatesCallback& callback); @@ -304,6 +346,17 @@ callback_(callback) { } +SelectCertificatesState::SelectCertificatesState( + const std::string& username_hash, + const bool use_system_key_slot, + scoped_refptr<net::SSLCertRequestInfo> cert_request_info, + const subtle::SelectCertificatesCallback& callback) + : username_hash_(username_hash), + use_system_key_slot_(use_system_key_slot), + cert_request_info_(cert_request_info), + callback_(callback) { +} + GetCertificatesState::GetCertificatesState( const GetCertificatesCallback& callback) : callback_(callback) { @@ -419,6 +472,33 @@ true /*task is slow*/); } +// Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list +// of net::CertificateList and calls back. Used by +// SelectCertificatesOnIOThread(). +void DidSelectCertificatesOnIOThread( + scoped_ptr<SelectCertificatesState> state) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + state->CallBack(FROM_HERE, state->certs_.Pass(), + std::string() /* no error */); +} + +// Continues selecting certificates on the IO thread. Used by +// SelectClientCertificates(). +void SelectCertificatesOnIOThread(scoped_ptr<SelectCertificatesState> state) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + state->cert_store_.reset(new net::ClientCertStoreChromeOS( + make_scoped_ptr(new chromeos::ClientCertFilterChromeOS( + state->use_system_key_slot_, state->username_hash_)), + net::ClientCertStoreChromeOS::PasswordDelegateFactory())); + + state->certs_.reset(new net::CertificateList); + + SelectCertificatesState* state_ptr = state.get(); + state_ptr->cert_store_->GetClientCerts( + *state_ptr->cert_request_info_, state_ptr->certs_.get(), + base::Bind(&DidSelectCertificatesOnIOThread, base::Passed(&state))); +} + // Filters the obtained certificates on a worker thread. Used by // DidGetCertificates(). void FilterCertificatesOnWorkerThread(scoped_ptr<GetCertificatesState> state) { @@ -596,6 +676,34 @@ state_ptr); } +void SelectClientCertificates(const ClientCertificateRequest& request, + const SelectCertificatesCallback& callback, + content::BrowserContext* browser_context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + scoped_refptr<net::SSLCertRequestInfo> cert_request_info( + new net::SSLCertRequestInfo); + cert_request_info->cert_key_types = request.certificate_key_types; + cert_request_info->cert_authorities = request.certificate_authorities; + + user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile( + Profile::FromBrowserContext(browser_context)); + + // Use the device-wide system key slot only if the user is of the same + // domain as the device is registered to. + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + bool use_system_key_slot = connector->GetUserAffiliation(user->email()) == + policy::USER_AFFILIATION_MANAGED; + + scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( + user->username_hash(), use_system_key_slot, cert_request_info, callback)); + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); +} + } // namespace subtle void GetCertificates(const std::string& token_id,
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc index b4bdd1c..95dbff81 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/chromeos/platform_keys/platform_keys.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/state_store.h" +#include "net/cert/x509_certificate.h" using content::BrowserThread; @@ -74,6 +75,10 @@ PlatformKeysService::~PlatformKeysService() { } +void PlatformKeysService::DisablePermissionCheckForTesting() { + permission_check_enabled_ = false; +} + void PlatformKeysService::GenerateRSAKey(const std::string& token_id, unsigned int modulus_length, const std::string& extension_id, @@ -108,6 +113,19 @@ browser_context_)); } +void PlatformKeysService::SelectClientCertificates( + const platform_keys::ClientCertificateRequest& request, + const std::string& extension_id, + const SelectCertificatesCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + platform_keys::subtle::SelectClientCertificates( + request, + base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, + weak_factory_.GetWeakPtr(), extension_id, callback), + browser_context_); +} + void PlatformKeysService::RegisterPublicKey( const std::string& extension_id, const std::string& public_key_spki_der, @@ -163,6 +181,18 @@ RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback); } +void PlatformKeysService::SelectClientCertificatesCallback( + const std::string& extension_id, + const SelectCertificatesCallback& callback, + scoped_ptr<net::CertificateList> matches, + const std::string& error_message) { + if (permission_check_enabled_) + matches->clear(); + + // TODO(pneubeck): Remove all certs that the extension doesn't have access to. + callback.Run(matches.Pass(), error_message); +} + void PlatformKeysService::RegisterPublicKeyGotPlatformKeys( const std::string& extension_id, const std::string& public_key_spki_der,
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.h b/chrome/browser/chromeos/platform_keys/platform_keys_service.h index 79342d7..c7def45 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_ #include <string> +#include <vector> #include "base/callback_forward.h" #include "base/macros.h" @@ -27,6 +28,11 @@ class StateStore; } +namespace net { +class X509Certificate; +typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; +} + namespace chromeos { class PlatformKeysService : public KeyedService { @@ -42,6 +48,11 @@ extensions::StateStore* state_store); ~PlatformKeysService() override; + // Disables the checks whether an extension is allowed to read client + // certificates. + // TODO(pneubeck): Remove this once a permissions are implemented. + void DisablePermissionCheckForTesting(); + // If the generation was successful, |public_key_spki_der| will contain the // DER encoding of the SubjectPublicKeyInfo of the generated key and // |error_message| will be empty. If it failed, |public_key_spki_der| will be @@ -84,6 +95,24 @@ const std::string& extension_id, const SignCallback& callback); + // If the certificate request could be processed successfully, |matches| will + // contain the list of matching certificates (maybe empty) and |error_message| + // will be empty. If an error occurred, |matches| will be null and + // |error_message| contain an error message. + typedef base::Callback<void(scoped_ptr<net::CertificateList> matches, + const std::string& error_message)> + SelectCertificatesCallback; + + // Returns the list of all certificates that match |request|. |callback| will + // be invoked with these matches or an error message. + // Will only call back during the lifetime of this object. + // TODO(pneubeck): Add the interactive option and integrate the select + // certificate dialog. + void SelectClientCertificates( + const platform_keys::ClientCertificateRequest& request, + const std::string& extension_id, + const SelectCertificatesCallback& callback); + private: using GetPlatformKeysCallback = base::Callback<void(scoped_ptr<base::ListValue> platform_keys)>; @@ -124,6 +153,17 @@ const std::string& public_key_spki_der, const std::string& error_message); + // Calback used by |SelectClientCertificates|. + // If the certificate request could be processed successfully, |matches| will + // contain the list of matching certificates (maybe empty) and |error_message| + // will be empty. If an error occurred, |matches| will be null and + // |error_message| contain an error message. + void SelectClientCertificatesCallback( + const std::string& extension_id, + const SelectCertificatesCallback& callback, + scoped_ptr<net::CertificateList> matches, + const std::string& error_message); + // Callback used by |RegisterPublicKey|. // Updates the old |platform_keys| read from the StateStore and writes the // updated value back to the StateStore. @@ -151,6 +191,7 @@ content::BrowserContext* browser_context_; extensions::StateStore* state_store_; + bool permission_check_enabled_ = true; base::WeakPtrFactory<PlatformKeysService> weak_factory_; DISALLOW_COPY_AND_ASSIGN(PlatformKeysService);
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc index 353662c..ad052be4 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
@@ -242,15 +242,18 @@ return; } - if (invalidation_service != device_invalidation_service_.get()) { - // If an invalidation service other than the device-global one connected, - // destroy the device-global service. - invalidation_service_ = nullptr; + // Make the invalidation service that just connected available to consumers. + invalidation_service_ = nullptr; + SetInvalidationService(invalidation_service); + + if (invalidation_service_ && + device_invalidation_service_ && + invalidation_service_ != device_invalidation_service_.get()) { + // If a different invalidation service is being made available to consumers + // now, destroy the device-global one. DestroyDeviceInvalidationService(); } - // Make the invalidation service that just connected available to consumers. - SetInvalidationService(invalidation_service); } void
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc index 370d4a7..071658f 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -20,6 +20,7 @@ #include "chrome/test/base/testing_profile_manager.h" #include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "components/invalidation/fake_invalidation_handler.h" #include "components/invalidation/invalidation_service.h" #include "components/invalidation/invalidator_state.h" #include "components/invalidation/profile_invalidation_provider.h" @@ -30,12 +31,8 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using testing::Mock; -using testing::StrictMock; - namespace policy { namespace { @@ -56,16 +53,29 @@ } // namespace -class MockConsumer : public AffiliatedInvalidationServiceProvider::Consumer { +// A simple AffiliatedInvalidationServiceProvider::Consumer that registers a +// syncer::FakeInvalidationHandler with the invalidation::InvalidationService +// that is currently being made available. +class FakeConsumer : public AffiliatedInvalidationServiceProvider::Consumer { public: - MockConsumer(); - ~MockConsumer() override; + explicit FakeConsumer(AffiliatedInvalidationServiceProviderImpl* provider); + ~FakeConsumer() override; - MOCK_METHOD1(OnInvalidationServiceSet, - void(invalidation::InvalidationService*)); + // AffiliatedInvalidationServiceProvider::Consumer: + void OnInvalidationServiceSet( + invalidation::InvalidationService* invalidation_service) override; + + int GetAndClearInvalidationServiceSetCount(); + const invalidation::InvalidationService* GetInvalidationService() const; private: - DISALLOW_COPY_AND_ASSIGN(MockConsumer); + AffiliatedInvalidationServiceProviderImpl* provider_; + syncer::FakeInvalidationHandler invalidation_handler_; + + int invalidation_service_set_count_ = 0; + invalidation::InvalidationService* invalidation_service_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(FakeConsumer); }; class AffiliatedInvalidationServiceProviderImplTest : public testing::Test { @@ -73,8 +83,8 @@ AffiliatedInvalidationServiceProviderImplTest(); // testing::Test: - virtual void SetUp() override; - virtual void TearDown() override; + void SetUp() override; + void TearDown() override; // Ownership is not passed. The Profile is owned by the global ProfileManager. Profile* LogInAndReturnProfile(const std::string& user_id); @@ -106,7 +116,7 @@ protected: scoped_ptr<AffiliatedInvalidationServiceProviderImpl> provider_; - StrictMock<MockConsumer> consumer_; + scoped_ptr<FakeConsumer> consumer_; invalidation::TiclInvalidationService* device_invalidation_service_; invalidation::FakeInvalidationService* profile_invalidation_service_; @@ -121,10 +131,51 @@ TestingProfileManager profile_manager_; }; -MockConsumer::MockConsumer() { +FakeConsumer::FakeConsumer(AffiliatedInvalidationServiceProviderImpl* provider) + : provider_(provider) { + provider_->RegisterConsumer(this); } -MockConsumer::~MockConsumer() { +FakeConsumer::~FakeConsumer() { + if (invalidation_service_) { + invalidation_service_->UnregisterInvalidationHandler( + &invalidation_handler_); + } + provider_->UnregisterConsumer(this); + + EXPECT_EQ(0, invalidation_service_set_count_); +} + +void FakeConsumer::OnInvalidationServiceSet( + invalidation::InvalidationService* invalidation_service) { + ++invalidation_service_set_count_; + + if (invalidation_service_) { + invalidation_service_->UnregisterInvalidationHandler( + &invalidation_handler_); + } + + invalidation_service_ = invalidation_service; + + if (invalidation_service_) { + // Regression test for http://crbug.com/455504: The |invalidation_service| + // was sometimes destroyed without notifying consumers and giving them a + // chance to unregister their invalidation handlers. Register an + // invalidation handler so that |invalidation_service| CHECK()s in its + // destructor if this regresses. + invalidation_service_->RegisterInvalidationHandler(&invalidation_handler_); + } +} + +int FakeConsumer::GetAndClearInvalidationServiceSetCount() { + const int invalidation_service_set_count = invalidation_service_set_count_; + invalidation_service_set_count_ = 0; + return invalidation_service_set_count; +} + +const invalidation::InvalidationService* +FakeConsumer::GetInvalidationService() const { + return invalidation_service_; } AffiliatedInvalidationServiceProviderImplTest:: @@ -157,6 +208,7 @@ } void AffiliatedInvalidationServiceProviderImplTest::TearDown() { + consumer_.reset(); provider_->Shutdown(); provider_.reset(); @@ -180,12 +232,9 @@ void AffiliatedInvalidationServiceProviderImplTest:: LogInAsAffiliatedUserAndConnectInvalidationService() { - Mock::VerifyAndClearExpectations(&consumer_); - // Log in as an affiliated user. Profile* profile = LogInAndReturnProfile(kAffiliatedUserID1); EXPECT_TRUE(profile); - Mock::VerifyAndClearExpectations(&consumer_); // Verify that a per-profile invalidation service has been created. profile_invalidation_service_ = @@ -197,22 +246,18 @@ // Indicate that the per-profile invalidation service has connected. Verify // that the consumer is informed about this. - EXPECT_CALL(consumer_, - OnInvalidationServiceSet(profile_invalidation_service_)).Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); profile_invalidation_service_->SetInvalidatorState( syncer::INVALIDATIONS_ENABLED); - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(profile_invalidation_service_, consumer_->GetInvalidationService()); // Verify that the device-global invalidation service has been destroyed. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); - - Mock::VerifyAndClearExpectations(&consumer_); } void AffiliatedInvalidationServiceProviderImplTest:: LogInAsUnaffiliatedUserAndConnectInvalidationService() { - Mock::VerifyAndClearExpectations(&consumer_); - // Log in as an unaffiliated user. Profile* profile = LogInAndReturnProfile(kUnaffiliatedUserID); EXPECT_TRUE(profile); @@ -229,17 +274,14 @@ // that the consumer is not called back. profile_invalidation_service_->SetInvalidatorState( syncer::INVALIDATIONS_ENABLED); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); // Verify that the device-global invalidation service still exists. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); - - Mock::VerifyAndClearExpectations(&consumer_); } void AffiliatedInvalidationServiceProviderImplTest:: ConnectDeviceGlobalInvalidationService() { - Mock::VerifyAndClearExpectations(&consumer_); - // Verify that a device-global invalidation service has been created. device_invalidation_service_ = provider_->GetDeviceInvalidationServiceForTest(); @@ -247,30 +289,27 @@ // Indicate that the device-global invalidation service has connected. Verify // that the consumer is informed about this. - EXPECT_CALL(consumer_, OnInvalidationServiceSet(device_invalidation_service_)) - .Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); device_invalidation_service_->OnInvalidatorStateChange( syncer::INVALIDATIONS_ENABLED); - - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(device_invalidation_service_, consumer_->GetInvalidationService()); } void AffiliatedInvalidationServiceProviderImplTest:: DisconnectPerProfileInvalidationService() { - Mock::VerifyAndClearExpectations(&consumer_); - ASSERT_TRUE(profile_invalidation_service_); // Indicate that the per-profile invalidation service has disconnected. Verify // that the consumer is informed about this. - EXPECT_CALL(consumer_, OnInvalidationServiceSet(nullptr)).Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); profile_invalidation_service_->SetInvalidatorState( syncer::INVALIDATION_CREDENTIALS_REJECTED); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(nullptr, consumer_->GetInvalidationService()); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); - - Mock::VerifyAndClearExpectations(&consumer_); } invalidation::FakeInvalidationService* @@ -301,6 +340,16 @@ EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); } +// Verifies that when no connected invalidation service is available for use, +// none is made available to consumers. +TEST_F(AffiliatedInvalidationServiceProviderImplTest, + NoInvalidationServiceAvailable) { + // Register a consumer. Verify that the consumer is not called back + // immediately as no connected invalidation service exists yet. + consumer_.reset(new FakeConsumer(provider_.get())); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); +} + // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. // Verifies that when no per-profile invalidation service belonging to an // affiliated user is available, a device-global invalidation service is @@ -308,9 +357,7 @@ // connects, it is made available to the consumer. TEST_F(AffiliatedInvalidationServiceProviderImplTest, UseDeviceInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Indicate that the device-global invalidation service connected. Verify that // that the consumer is informed about this. @@ -318,17 +365,14 @@ // Indicate that the device-global invalidation service has disconnected. // Verify that the consumer is informed about this. - EXPECT_CALL(consumer_, OnInvalidationServiceSet(nullptr)).Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); device_invalidation_service_->OnInvalidatorStateChange( syncer::INVALIDATION_CREDENTIALS_REJECTED); - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(nullptr, consumer_->GetInvalidationService()); // Verify that the device-global invalidation service still exists. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -336,9 +380,7 @@ // affiliated user connects, it is made available to the consumer. TEST_F(AffiliatedInvalidationServiceProviderImplTest, UseAffiliatedProfileInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); @@ -353,10 +395,6 @@ // disconnected. Verify that the consumer is informed about this and a // device-global invalidation service is created. DisconnectPerProfileInvalidationService(); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -364,9 +402,7 @@ // unaffiliated user connects, it is ignored. TEST_F(AffiliatedInvalidationServiceProviderImplTest, DoNotUseUnaffiliatedProfileInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); @@ -376,10 +412,6 @@ // service is ignored and the device-global invalidation service is not // destroyed. LogInAsUnaffiliatedUserAndConnectInvalidationService(); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -389,9 +421,7 @@ // consumer instead and the device-global invalidation service is destroyed. TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchToAffiliatedProfileInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Indicate that the device-global invalidation service connected. Verify that // that the consumer is informed about this. @@ -402,10 +432,6 @@ // made available to the |consumer_| and the device-global invalidation // service is destroyed. LogInAsAffiliatedUserAndConnectInvalidationService(); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -416,9 +442,7 @@ // consumer. TEST_F(AffiliatedInvalidationServiceProviderImplTest, DoNotSwitchToUnaffiliatedProfileInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Indicate that the device-global invalidation service connected. Verify that // that the consumer is informed about this. @@ -429,10 +453,6 @@ // service is ignored and the device-global invalidation service is not // destroyed. LogInAsUnaffiliatedUserAndConnectInvalidationService(); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -443,9 +463,7 @@ // service connects, it is made available to the consumer. TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchToDeviceInvalidationService) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); @@ -464,10 +482,6 @@ // Indicate that the device-global invalidation service connected. Verify that // that the consumer is informed about this. ConnectDeviceGlobalInvalidationService(); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -479,9 +493,7 @@ // to the second user is made available to the consumer instead. TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchBetweenAffiliatedProfileInvalidationServices) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); @@ -509,25 +521,21 @@ // connected. Verify that the consumer is not called back. second_profile_invalidation_service->SetInvalidatorState( syncer::INVALIDATIONS_ENABLED); - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); // Indicate that the first user's per-profile invalidation service has // disconnected. Verify that the consumer is informed that the second user's // per-profile invalidation service should be used instead of the first // user's. - EXPECT_CALL(consumer_, - OnInvalidationServiceSet(second_profile_invalidation_service)) - .Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); profile_invalidation_service_->SetInvalidatorState( syncer::INVALIDATION_CREDENTIALS_REJECTED); - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(second_profile_invalidation_service, + consumer_->GetInvalidationService()); // Verify that the device-global invalidation service still does not exist. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -539,9 +547,7 @@ // consumer. Further verifies that when the second consumer also unregisters, // the device-global invalidation service is destroyed. TEST_F(AffiliatedInvalidationServiceProviderImplTest, MultipleConsumers) { - // Register a first consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Indicate that the device-global invalidation service connected. Verify that // that the consumer is informed about this. @@ -549,25 +555,22 @@ // Register a second consumer. Verify that the consumer is called back // immediately as a connected invalidation service is available. - StrictMock<MockConsumer> second_consumer; - EXPECT_CALL(second_consumer, - OnInvalidationServiceSet(device_invalidation_service_)).Times(1); - provider_->RegisterConsumer(&second_consumer); - Mock::VerifyAndClearExpectations(&second_consumer); + scoped_ptr<FakeConsumer> second_consumer(new FakeConsumer(provider_.get())); + EXPECT_EQ(1, second_consumer->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(device_invalidation_service_, + second_consumer->GetInvalidationService()); // Unregister the first consumer. - provider_->UnregisterConsumer(&consumer_); + consumer_.reset(); // Verify that the device-global invalidation service still exists. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); // Unregister the second consumer. - provider_->UnregisterConsumer(&second_consumer); + second_consumer.reset(); // Verify that the device-global invalidation service has been destroyed. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); - Mock::VerifyAndClearExpectations(&consumer_); - Mock::VerifyAndClearExpectations(&second_consumer); } // A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. @@ -579,9 +582,7 @@ // service belonging to a second affiliated user that subsequently connects is // ignored. TEST_F(AffiliatedInvalidationServiceProviderImplTest, NoServiceAfterShutdown) { - // Register a consumer. Verify that the consumer is not called back - // immediately as no connected invalidation service exists yet. - provider_->RegisterConsumer(&consumer_); + consumer_.reset(new FakeConsumer(provider_.get())); // Verify that a device-global invalidation service has been created. EXPECT_TRUE(provider_->GetDeviceInvalidationServiceForTest()); @@ -594,9 +595,10 @@ // Shut down the |provider_|. Verify that the |consumer_| is informed that no // invalidation service is available for use anymore. - EXPECT_CALL(consumer_, OnInvalidationServiceSet(nullptr)).Times(1); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); provider_->Shutdown(); - Mock::VerifyAndClearExpectations(&consumer_); + EXPECT_EQ(1, consumer_->GetAndClearInvalidationServiceSetCount()); + EXPECT_EQ(nullptr, consumer_->GetInvalidationService()); // Verify that the device-global invalidation service still does not exist. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); @@ -617,13 +619,10 @@ // connected. Verify that the consumer is not called back. second_profile_invalidation_service->SetInvalidatorState( syncer::INVALIDATIONS_ENABLED); + EXPECT_EQ(0, consumer_->GetAndClearInvalidationServiceSetCount()); // Verify that the device-global invalidation service still does not exist. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); - - // Unregister the consumer. - provider_->UnregisterConsumer(&consumer_); - Mock::VerifyAndClearExpectations(&consumer_); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc index e2a7a4c7..d3bd114 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -17,7 +17,7 @@ #include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" -#include "base/process/process_handle.h" +#include "base/process/process.h" #include "base/process/process_iterator.h" #include "base/process/process_metrics.h" #include "base/strings/string_number_conversions.h" @@ -437,16 +437,15 @@ const int num_processors = base::SysInfo::NumberOfProcessors(); while (const base::ProcessEntry* process_entry = process_iter.NextProcessEntry()) { - base::ProcessHandle process; - if (!base::OpenProcessHandle(process_entry->pid(), &process)) { + base::Process process = base::Process::Open(process_entry->pid()); + if (!process.IsValid()) { LOG(ERROR) << "Could not create process handle for process " << process_entry->pid(); continue; } scoped_ptr<base::ProcessMetrics> metrics( - base::ProcessMetrics::CreateProcessMetrics(process)); + base::ProcessMetrics::CreateProcessMetrics(process.Handle())); const double usage = metrics->GetPlatformIndependentCPUUsage(); - base::CloseProcessHandle(process); DCHECK_LE(0, usage); if (usage > 0) { // Convert CPU usage from "percentage of a single core" to "percentage of
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc index a1875852..264692d 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc
@@ -15,12 +15,12 @@ #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/user_cloud_external_data_manager.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/policy/schema_registry_service.h" #include "chrome/browser/policy/schema_registry_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -212,9 +212,8 @@ bool wildcard_match = false; if (connector->IsEnterpriseManaged() && - chromeos::LoginUtils::IsWhitelisted(username, &wildcard_match) && - wildcard_match && - !connector->IsNonEnterpriseUser(username)) { + chromeos::CrosSettings::IsWhitelisted(username, &wildcard_match) && + wildcard_match && !connector->IsNonEnterpriseUser(username)) { manager->EnableWildcardLoginCheck(username); }
diff --git a/chrome/browser/chromeos/preferences_browsertest.cc b/chrome/browser/chromeos/preferences_browsertest.cc index b68b2be..ef44d88 100644 --- a/chrome/browser/chromeos/preferences_browsertest.cc +++ b/chrome/browser/chromeos/preferences_browsertest.cc
@@ -5,6 +5,7 @@ #include <sys/types.h> #include "ash/shell.h" +#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/prefs/pref_service.h"
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h index cac7855..e15475fc 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.h +++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -123,8 +123,11 @@ const std::string& user_id); private: + // TODO(nkostylev): Create a test API class that will be the only one allowed + // to access private test methods. friend class CryptohomeAuthenticatorTest; friend class DeviceSettingsTestBase; + friend class ExistingUserControllerTest; friend class extensions::ExtensionGarbageCollectorChromeOSUnitTest; friend class FakeChromeUserManager; friend class KioskTest;
diff --git a/chrome/browser/chromeos/settings/cros_settings.cc b/chrome/browser/chromeos/settings/cros_settings.cc index 96427d2..016b33a 100644 --- a/chrome/browser/chromeos/settings/cros_settings.cc +++ b/chrome/browser/chromeos/settings/cros_settings.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" #include "chrome/browser/chromeos/settings/system_settings_provider.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/settings/cros_settings_names.h" #include "google_apis/gaia/gaia_auth_util.h" namespace chromeos { @@ -45,6 +46,24 @@ return g_cros_settings; } +// static +bool CrosSettings::IsWhitelisted(const std::string& username, + bool* wildcard_match) { + // Skip whitelist check for tests. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kOobeSkipPostLogin)) { + return true; + } + + CrosSettings* cros_settings = CrosSettings::Get(); + bool allow_new_user = false; + cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); + if (allow_new_user) + return true; + return cros_settings->FindEmailInList(kAccountsPrefUsers, username, + wildcard_match); +} + CrosSettings::CrosSettings(DeviceSettingsService* device_settings_service) { CrosSettingsProvider::NotifyObserversCallback notify_cb( base::Bind(&CrosSettings::FireObservers,
diff --git a/chrome/browser/chromeos/settings/cros_settings.h b/chrome/browser/chromeos/settings/cros_settings.h index f7becbe4..366e15c 100644 --- a/chrome/browser/chromeos/settings/cros_settings.h +++ b/chrome/browser/chromeos/settings/cros_settings.h
@@ -35,6 +35,11 @@ static void Shutdown(); static CrosSettings* Get(); + // Checks if the given username is whitelisted and allowed to sign-in to + // this device. |wildcard_match| may be NULL. If it's present, it'll be set to + // true if the whitelist check was satisfied via a wildcard. + static bool IsWhitelisted(const std::string& username, bool* wildcard_match); + // Creates a device settings service instance. This is meant for unit tests, // production code uses the singleton returned by Get() above. explicit CrosSettings(DeviceSettingsService* device_settings_service);
diff --git a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc index 5944a9f..3181d35 100644 --- a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc +++ b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" #include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/extensions/api/braille_display_private/mock_braille_controller.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc index fc9b092..485a758 100644 --- a/chrome/browser/component_updater/pepper_flash_component_installer.cc +++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -335,8 +335,7 @@ public: explicit PepperFlashComponentInstaller(const Version& version); - ~PepperFlashComponentInstaller() override {} - + // ComponentInstaller implementation: void OnUpdateError(int error) override; bool Install(const base::DictionaryValue& manifest, @@ -345,7 +344,11 @@ bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; + bool Uninstall() override; + private: + ~PepperFlashComponentInstaller() override {} + Version current_version_; }; @@ -394,6 +397,10 @@ return false; } +bool PepperFlashComponentInstaller::Uninstall() { + return false; +} + bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, Version* version_out) { std::string name;
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc index 6667dc8..9a0c708 100644 --- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc +++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
@@ -92,7 +92,7 @@ PathService::Override(chrome::DIR_PNACL_COMPONENT, GetPlatformDir(base_path)); } -bool GetLatestPnaclDirectory(PnaclComponentInstaller* pci, +bool GetLatestPnaclDirectory(const scoped_refptr<PnaclComponentInstaller>& pci, base::FilePath* latest_dir, Version* latest_version, std::vector<base::FilePath>* older_dirs) { @@ -280,6 +280,10 @@ return true; } +bool PnaclComponentInstaller::Uninstall() { + return false; +} + CrxComponent PnaclComponentInstaller::GetCrxComponent() { CrxComponent pnacl_component; pnacl_component.version = current_version(); @@ -293,9 +297,10 @@ namespace { -void FinishPnaclUpdateRegistration(const Version& current_version, - const std::string& current_fingerprint, - PnaclComponentInstaller* pci) { +void FinishPnaclUpdateRegistration( + const Version& current_version, + const std::string& current_fingerprint, + const scoped_refptr<PnaclComponentInstaller>& pci) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); pci->set_current_version(current_version); CheckVersionCompatiblity(current_version); @@ -312,7 +317,8 @@ // Check if there is an existing version on disk first to know when // a hosted version is actually newer. -void StartPnaclUpdateRegistration(PnaclComponentInstaller* pci) { +void StartPnaclUpdateRegistration( + const scoped_refptr<PnaclComponentInstaller>& pci) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); base::FilePath path = pci->GetPnaclBaseDirectory(); if (!base::PathExists(path)) { @@ -365,9 +371,9 @@ void PnaclComponentInstaller::RegisterPnaclComponent( ComponentUpdateService* cus) { cus_ = cus; - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - base::Bind(&StartPnaclUpdateRegistration, this)); + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + base::Bind(&StartPnaclUpdateRegistration, make_scoped_refptr(this))); } } // namespace component_updater
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.h b/chrome/browser/component_updater/pnacl/pnacl_component_installer.h index a5683bb..3674377 100644 --- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.h +++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.h
@@ -41,15 +41,13 @@ public: PnaclComponentInstaller(); - ~PnaclComponentInstaller() override; - + // ComponentInstaller implementation: void OnUpdateError(int error) override; - bool Install(const base::DictionaryValue& manifest, const base::FilePath& unpack_path) override; - bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; + bool Uninstall() override; // Register a PNaCl component for the first time. void RegisterPnaclComponent(ComponentUpdateService* cus); @@ -74,9 +72,12 @@ ComponentUpdateService* cus() const { return cus_; } private: + ~PnaclComponentInstaller() override; + base::Version current_version_; std::string current_fingerprint_; ComponentUpdateService* cus_; + DISALLOW_COPY_AND_ASSIGN(PnaclComponentInstaller); };
diff --git a/chrome/browser/component_updater/ppapi_utils.cc b/chrome/browser/component_updater/ppapi_utils.cc index 59e2969..a9c097e4 100644 --- a/chrome/browser/component_updater/ppapi_utils.cc +++ b/chrome/browser/component_updater/ppapi_utils.cc
@@ -71,6 +71,7 @@ #include "ppapi/c/ppb_var_array_buffer.h" #include "ppapi/c/ppb_var_dictionary.h" #include "ppapi/c/ppb_video_decoder.h" +#include "ppapi/c/ppb_video_encoder.h" #include "ppapi/c/ppb_video_frame.h" #include "ppapi/c/ppb_view.h" #include "ppapi/c/ppb_websocket.h"
diff --git a/chrome/browser/component_updater/recovery_component_installer.cc b/chrome/browser/component_updater/recovery_component_installer.cc index 2173f05f..20898059 100644 --- a/chrome/browser/component_updater/recovery_component_installer.cc +++ b/chrome/browser/component_updater/recovery_component_installer.cc
@@ -176,8 +176,8 @@ class RecoveryComponentInstaller : public update_client::ComponentInstaller { public: RecoveryComponentInstaller(const Version& version, PrefService* prefs); - ~RecoveryComponentInstaller() override {} + // ComponentInstaller implementation: void OnUpdateError(int error) override; bool Install(const base::DictionaryValue& manifest, @@ -186,7 +186,11 @@ bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; + bool Uninstall() override; + private: + ~RecoveryComponentInstaller() override {} + bool RunInstallCommand(const base::CommandLine& cmdline, const base::FilePath& installer_folder) const; @@ -358,6 +362,10 @@ return false; } +bool RecoveryComponentInstaller::Uninstall() { + return false; +} + void RegisterRecoveryComponent(ComponentUpdateService* cus, PrefService* prefs) { #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc index 603242f..c308330 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -121,7 +121,7 @@ const std::string& name, bool newly_added, const WhitelistReadyCallback& callback) override; - void UnregisterWhitelist(const std::string& crx_id) override; + void UninstallWhitelist(const std::string& crx_id) override; ComponentUpdateService* cus_; }; @@ -139,20 +139,19 @@ scoped_ptr<ComponentInstallerTraits> traits( new SupervisedUserWhitelistComponentInstallerTraits(crx_id, name, callback)); - DefaultComponentInstaller* installer = - new DefaultComponentInstaller(traits.Pass()); - - // Takes ownership of |installer|. + scoped_refptr<DefaultComponentInstaller> installer( + new DefaultComponentInstaller(traits.Pass())); installer->Register(cus_); if (newly_added) TriggerComponentUpdate(&cus_->GetOnDemandUpdater(), crx_id); } -void SupervisedUserWhitelistInstallerImpl::UnregisterWhitelist( - const std::string& id) { - // TODO(bauerb): Implement! - NOTIMPLEMENTED(); +void SupervisedUserWhitelistInstallerImpl::UninstallWhitelist( + const std::string& crx_id) { + const ComponentUpdateService::Status status = + cus_->UnregisterComponent(crx_id); + DCHECK_EQ(ComponentUpdateService::kOk, status); } } // namespace
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.h b/chrome/browser/component_updater/supervised_user_whitelist_installer.h index 796e8333..6aa3e76f8 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.h +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.h
@@ -47,8 +47,8 @@ bool new_installation, const WhitelistReadyCallback& callback) = 0; - // Unregisters a whitelist. - virtual void UnregisterWhitelist(const std::string& crx_id) = 0; + // Uninstalls a whitelist. + virtual void UninstallWhitelist(const std::string& crx_id) = 0; protected: // Triggers an update for a whitelist to be installed. Protected so it can be
diff --git a/chrome/browser/component_updater/swiftshader_component_installer.cc b/chrome/browser/component_updater/swiftshader_component_installer.cc index bea146a5..f0a59f1 100644 --- a/chrome/browser/component_updater/swiftshader_component_installer.cc +++ b/chrome/browser/component_updater/swiftshader_component_installer.cc
@@ -100,8 +100,7 @@ public: explicit SwiftShaderComponentInstaller(const Version& version); - ~SwiftShaderComponentInstaller() override {} - + // ComponentInstaller implementation: void OnUpdateError(int error) override; bool Install(const base::DictionaryValue& manifest, @@ -110,7 +109,11 @@ bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; + bool Uninstall() override; + private: + ~SwiftShaderComponentInstaller() override {} + Version current_version_; }; @@ -162,6 +165,10 @@ return false; } +bool SwiftShaderComponentInstaller::Uninstall() { + return false; +} + void FinishSwiftShaderUpdateRegistration(ComponentUpdateService* cus, const Version& version) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc index 7957c74..9e65310 100644 --- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc +++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
@@ -116,16 +116,23 @@ CrxComponent* com, TestComponents component, const Version& version, - TestInstaller* installer) { - if (component == kTestComponent_abag) { - com->name = "test_abag"; - com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); - } else if (component == kTestComponent_jebg) { - com->name = "test_jebg"; - com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); - } else { - com->name = "test_ihfo"; - com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash)); + const scoped_refptr<TestInstaller>& installer) { + switch (component) { + case kTestComponent_abag: { + com->name = "test_abag"; + com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); + break; + } + case kTestComponent_jebg: { + com->name = "test_jebg"; + com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); + break; + } + case kTestComponent_ihfo: { + com->name = "test_ihfo"; + com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash)); + break; + } } com->version = version; com->installer = installer; @@ -190,20 +197,20 @@ EXPECT_TRUE(post_interceptor_->ExpectRequest( new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; component_updater()->AddObserver(&observer); EXPECT_EQ( ComponentUpdateService::kOk, - RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); + RegisterComponent(&com, kTestComponent_abag, Version("1.1"), installer)); // We loop twice, but there are no updates so we expect two sleep messages. test_configurator()->SetLoopCount(2); component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); // Expect to see the two update check requests and no other requests, // including pings. @@ -248,8 +255,8 @@ component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); EXPECT_EQ(2, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -335,21 +342,21 @@ component_updater()->AddObserver(&observer); - TestInstaller installer1; + scoped_refptr<TestInstaller> installer1(new TestInstaller); CrxComponent com1; - RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); - TestInstaller installer2; + RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), installer1); + scoped_refptr<TestInstaller> installer2(new TestInstaller); CrxComponent com2; - RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); + RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), installer2); test_configurator()->SetLoopCount(2); component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); - EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); + EXPECT_EQ(0, installer1->error()); + EXPECT_EQ(1, installer1->install_count()); + EXPECT_EQ(0, installer2->error()); + EXPECT_EQ(0, installer2->install_count()); // Expect three request in total: two update checks and one ping. EXPECT_EQ(3, post_interceptor_->GetHitCount()) @@ -440,9 +447,9 @@ GURL(expected_crx_url), test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; - RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); + RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), installer); test_configurator()->SetLoopCount(1); component_updater()->Start(); @@ -457,8 +464,8 @@ // Expect no download to occur. EXPECT_EQ(0, get_interceptor_->GetHitCount()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); component_updater()->Stop(); } @@ -530,12 +537,12 @@ component_updater()->AddObserver(&observer); - TestInstaller installer1; + scoped_refptr<TestInstaller> installer1(new TestInstaller); CrxComponent com1; - RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1); - TestInstaller installer2; + RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), installer1); + scoped_refptr<TestInstaller> installer2(new TestInstaller); CrxComponent com2; - RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2); + RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), installer2); // No update normally. test_configurator()->SetLoopCount(1); @@ -563,10 +570,10 @@ component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); - EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count()); + EXPECT_EQ(0, installer1->error()); + EXPECT_EQ(0, installer1->install_count()); + EXPECT_EQ(0, installer2->error()); + EXPECT_EQ(1, installer2->install_count()); EXPECT_EQ(2, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -742,12 +749,12 @@ component_updater()->AddObserver(&observer); - TestInstaller installer1; + scoped_refptr<TestInstaller> installer1(new TestInstaller); CrxComponent com1; - RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); - TestInstaller installer2; + RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), installer1); + scoped_refptr<TestInstaller> installer2(new TestInstaller); CrxComponent com2; - RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); + RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), installer2); // Loop twice to issue two checks: (1) with original 0.9 version, update to // 1.0, and do the second check (2) with the updated 1.0 version. @@ -755,10 +762,10 @@ component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); - EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); + EXPECT_EQ(0, installer1->error()); + EXPECT_EQ(1, installer1->install_count()); + EXPECT_EQ(0, installer2->error()); + EXPECT_EQ(0, installer2->install_count()); EXPECT_EQ(3, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -810,10 +817,10 @@ EXPECT_TRUE(post_interceptor_->ExpectRequest( new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); - TestInstaller installer3; + scoped_refptr<TestInstaller> installer3(new TestInstaller); EXPECT_EQ(ComponentUpdateService::kReplaced, - RegisterComponent( - &com1, kTestComponent_jebg, Version("2.2"), &installer3)); + RegisterComponent(&com1, kTestComponent_jebg, Version("2.2"), + installer3)); // Loop once just to notice the check happening with the re-register version. test_configurator()->SetLoopCount(1); @@ -821,10 +828,10 @@ RunThreads(); // We created a new installer, so the counts go back to 0. - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); + EXPECT_EQ(0, installer3->error()); + EXPECT_EQ(0, installer3->install_count()); + EXPECT_EQ(0, installer2->error()); + EXPECT_EQ(0, installer2->install_count()); // One update check and no additional pings are expected. EXPECT_EQ(1, post_interceptor_->GetHitCount()) @@ -873,16 +880,16 @@ "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); - VersionedTestInstaller installer; + scoped_refptr<TestInstaller> installer(new VersionedTestInstaller); CrxComponent com; - RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); + RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), installer); test_configurator()->SetLoopCount(3); component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(2, installer->install_count()); EXPECT_EQ(5, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -962,17 +969,17 @@ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; - RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); + RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), installer); test_configurator()->SetLoopCount(2); component_updater()->Start(); RunThreads(); // A failed differential update does not count as a failed install. - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(1, installer->install_count()); EXPECT_EQ(3, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -1013,14 +1020,17 @@ // Verify that a failed installation causes an install failure ping. TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) { // This test installer reports installation failure. - class : public TestInstaller { + class FailingTestInstaller : public TestInstaller { bool Install(const base::DictionaryValue& manifest, const base::FilePath& unpack_path) override { ++install_count_; base::DeleteFile(unpack_path, true); return false; } - } installer; + private: + ~FailingTestInstaller() override {} + }; + scoped_refptr<FailingTestInstaller> installer(new FailingTestInstaller); EXPECT_TRUE(post_interceptor_->ExpectRequest( new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); @@ -1036,7 +1046,7 @@ // Loop twice to issue two checks: (1) with original 0.9 version // and (2), which should retry with 0.9. CrxComponent com; - RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); + RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), installer); test_configurator()->SetLoopCount(2); component_updater()->Start(); @@ -1087,8 +1097,8 @@ component_updater()->Start(); RunThreads(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(2, installer->install_count()); EXPECT_EQ(1, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -1136,17 +1146,17 @@ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); - VersionedTestInstaller installer; + scoped_refptr<TestInstaller> installer(new VersionedTestInstaller); CrxComponent com; - RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); + RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), installer); test_configurator()->SetLoopCount(3); component_updater()->Start(); RunThreads(); component_updater()->Stop(); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(2, installer->install_count()); EXPECT_EQ(5, post_interceptor_->GetHitCount()) << post_interceptor_->GetRequestsAsString(); @@ -1249,12 +1259,12 @@ EXPECT_TRUE(post_interceptor_->ExpectRequest( new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; component_updater()->AddObserver(&observer); EXPECT_EQ( ComponentUpdateService::kOk, - RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); + RegisterComponent(&com, kTestComponent_abag, Version("1.1"), installer)); // The following two calls ensure that we don't do an update check via the // timer, so the only update check should be the on-demand one. test_configurator()->SetInitialDelay(1000000); @@ -1275,8 +1285,8 @@ RunThreads(); EXPECT_EQ(1, post_interceptor_->GetHitCount()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); component_updater()->Stop(); } @@ -1349,12 +1359,12 @@ EXPECT_TRUE(post_interceptor_->ExpectRequest( new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; component_updater()->AddObserver(&observer); - EXPECT_EQ( - ComponentUpdateService::kOk, - RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); + EXPECT_EQ(ComponentUpdateService::kOk, + RegisterComponent(&com, kTestComponent_abag, Version("1.1"), + installer)); // The following two calls ensure that we don't do an update check via the // timer, so the only update check should be the on-demand one. test_configurator()->SetInitialDelay(1000000); @@ -1381,8 +1391,8 @@ RunThreads(); EXPECT_EQ(1, post_interceptor_->GetHitCount()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); component_updater()->Stop(); } @@ -1407,8 +1417,8 @@ RunThreads(); EXPECT_EQ(1, post_interceptor_->GetHitCount()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); - EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); + EXPECT_EQ(0, installer->error()); + EXPECT_EQ(0, installer->install_count()); component_updater()->Stop(); } @@ -1466,11 +1476,11 @@ component_updater()->AddObserver(&observer1); component_updater()->AddObserver(&observer2); - TestInstaller installer; + scoped_refptr<TestInstaller> installer(new TestInstaller); CrxComponent com; EXPECT_EQ( ComponentUpdateService::kOk, - RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); + RegisterComponent(&com, kTestComponent_abag, Version("1.1"), installer)); test_configurator()->SetLoopCount(1); component_updater()->Start(); RunThreads();
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.h b/chrome/browser/component_updater/test/component_updater_service_unittest.h index 49550414..bb035ce 100644 --- a/chrome/browser/component_updater/test/component_updater_service_unittest.h +++ b/chrome/browser/component_updater/test/component_updater_service_unittest.h
@@ -60,7 +60,7 @@ update_client::CrxComponent* com, TestComponents component, const Version& version, - update_client::TestInstaller* installer); + const scoped_refptr<update_client::TestInstaller>& installer); protected: void RunThreads();
diff --git a/chrome/browser/component_updater/test/supervised_user_whitelist_installer_unittest.cc b/chrome/browser/component_updater/test/supervised_user_whitelist_installer_unittest.cc index 1f0ef1f..c568c04 100644 --- a/chrome/browser/component_updater/test/supervised_user_whitelist_installer_unittest.cc +++ b/chrome/browser/component_updater/test/supervised_user_whitelist_installer_unittest.cc
@@ -58,10 +58,7 @@ const scoped_refptr<base::SequencedTaskRunner>& task_runner) : task_runner_(task_runner) {} - ~MockComponentUpdateService() override { - if (component_) - delete component_->installer; - } + ~MockComponentUpdateService() override {} MockOnDemandUpdater& on_demand_updater() { return on_demand_updater_; } @@ -99,6 +96,22 @@ return kOk; } + Status UnregisterComponent(const std::string& crx_id) override { + if (!component_) { + ADD_FAILURE(); + return kError; + } + + EXPECT_EQ(GetCrxComponentID(*component_), crx_id); + if (!component_->installer->Uninstall()) { + ADD_FAILURE(); + return kError; + } + + component_.reset(); + return kOk; + } + OnDemandUpdater& GetOnDemandUpdater() override { return on_demand_updater_; } void MaybeThrottle(const std::string& kCrxId, @@ -244,16 +257,27 @@ EXPECT_EQ(kWhitelistContents, whitelist_contents); } -TEST_F(SupervisedUserWhitelistInstallerTest, RegisterExistingWhitelist) { +TEST_F(SupervisedUserWhitelistInstallerTest, + RegisterAndUninstallExistingWhitelist) { ASSERT_TRUE(base::CreateDirectory(whitelist_directory_)); ASSERT_NO_FATAL_FAILURE(PrepareWhitelistDirectory(whitelist_directory_)); - base::RunLoop run_loop; - bool new_installation = false; - LoadWhitelist(new_installation, run_loop.QuitClosure()); - run_loop.Run(); + { + base::RunLoop run_loop; + bool new_installation = false; + LoadWhitelist(new_installation, run_loop.QuitClosure()); + run_loop.Run(); + } ASSERT_NO_FATAL_FAILURE(CheckRegisteredComponent(kVersion)); + + { + base::RunLoop run_loop; + installer_->UninstallWhitelist(kCrxId); + run_loop.RunUntilIdle(); + } + EXPECT_FALSE(component_update_service_.registered_component()); + EXPECT_FALSE(base::DirectoryExists(whitelist_directory_)); } } // namespace component_updater
diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc index e28da9b..6783ae8 100644 --- a/chrome/browser/content_settings/cookie_settings.cc +++ b/chrome/browser/content_settings/cookie_settings.cc
@@ -74,7 +74,9 @@ content::BrowserContext* CookieSettings::Factory::GetBrowserContextToUse( content::BrowserContext* context) const { - return chrome::GetBrowserContextRedirectedInIncognito(context); + // The incognito profile has its own content settings map. Therefore, it + // should get its own CookieSettings. + return chrome::GetBrowserContextOwnInstanceInIncognito(context); } scoped_refptr<RefcountedKeyedService>
diff --git a/chrome/browser/content_settings/cookie_settings_unittest.cc b/chrome/browser/content_settings/cookie_settings_unittest.cc index 30b547f7..60e5a94f 100644 --- a/chrome/browser/content_settings/cookie_settings_unittest.cc +++ b/chrome/browser/content_settings/cookie_settings_unittest.cc
@@ -281,4 +281,69 @@ kBlockedSite, kExtensionURL)); } +TEST_F(CookieSettingsTest, IncognitoBehaviorOfBlockingRules) { + scoped_refptr<CookieSettings> incognito_settings = + CookieSettings::Factory::GetForProfile(profile_.GetOffTheRecordProfile()); + + // Modify the regular cookie settings after the incognito cookie settings have + // been instantiated. + cookie_settings_->SetCookieSetting( + ContentSettingsPattern::FromURL(kBlockedSite), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_BLOCK); + + // The modification should apply to the regular profile and incognito profile. + EXPECT_FALSE(cookie_settings_->IsReadingCookieAllowed( + kBlockedSite, kBlockedSite)); + EXPECT_FALSE(incognito_settings->IsReadingCookieAllowed( + kBlockedSite, kBlockedSite)); + + // Modify an incognito cookie setting and check that this does not propagate + // into regular mode. + incognito_settings->SetCookieSetting( + ContentSettingsPattern::FromURL(kHttpsSite), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_BLOCK); + EXPECT_TRUE(cookie_settings_->IsReadingCookieAllowed( + kHttpsSite, kHttpsSite)); + EXPECT_FALSE(incognito_settings->IsReadingCookieAllowed( + kHttpsSite, kHttpsSite)); +} + +TEST_F(CookieSettingsTest, IncognitoBehaviorOfBlockingEverything) { + scoped_refptr<CookieSettings> incognito_settings = + CookieSettings::Factory::GetForProfile(profile_.GetOffTheRecordProfile()); + + // Apply the general blocking to the regular profile. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + + // It should be effective for regular and incognito session. + EXPECT_FALSE(cookie_settings_->IsReadingCookieAllowed( + kFirstPartySite, kFirstPartySite)); + EXPECT_FALSE(incognito_settings->IsReadingCookieAllowed( + kFirstPartySite, kFirstPartySite)); + + // A whitelisted item set in incognito mode should only apply to incognito + // mode. + incognito_settings->SetCookieSetting( + ContentSettingsPattern::FromURL(kAllowedSite), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_ALLOW); + EXPECT_TRUE(incognito_settings->IsReadingCookieAllowed( + kAllowedSite, kAllowedSite)); + EXPECT_FALSE(cookie_settings_->IsReadingCookieAllowed( + kAllowedSite, kAllowedSite)); + + // A whitelisted item set in regular mode should apply to regular and + // incognito mode. + cookie_settings_->SetCookieSetting( + ContentSettingsPattern::FromURL(kHttpsSite), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_ALLOW); + EXPECT_TRUE(incognito_settings->IsReadingCookieAllowed( + kHttpsSite, kHttpsSite)); + EXPECT_TRUE(cookie_settings_->IsReadingCookieAllowed( + kHttpsSite, kHttpsSite)); +} + } // namespace
diff --git a/chrome/browser/content_settings/permission_context_base.cc b/chrome/browser/content_settings/permission_context_base.cc index 045ac48..c188377 100644 --- a/chrome/browser/content_settings/permission_context_base.cc +++ b/chrome/browser/content_settings/permission_context_base.cc
@@ -18,12 +18,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" -using chromeos::attestation::PlatformVerificationDialog; -using chromeos::attestation::PlatformVerificationFlow; -#endif - PermissionContextBase::PermissionContextBase( Profile* profile, const ContentSettingsType permission_type) @@ -132,19 +126,6 @@ PermissionContextUmaUtil::PermissionRequested( permission_type_, requesting_origin); -#if defined(OS_CHROMEOS) - // TODO(xhwang): This is to use the existing platform verification UI. Remove - // it when the infobar/bubble UI can satisfy our requirements. - if (permission_type_ == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { - PlatformVerificationDialog::ShowDialog( - web_contents, - base::Bind(&PermissionContextBase::OnPlatformVerificationResult, - weak_factory_.GetWeakPtr(), id, requesting_origin, - embedding_origin, callback)); - return; - } -#endif - if (PermissionBubbleManager::Enabled()) { if (pending_bubbles_.get(id.ToString()) != NULL) return; @@ -248,25 +229,3 @@ ContentSettingsPattern::FromURLNoWildcard(embedding_origin), permission_type_, std::string(), content_setting); } - -#if defined(OS_CHROMEOS) -void PermissionContextBase::OnPlatformVerificationResult( - const PermissionRequestID& id, - const GURL& requesting_origin, - const GURL& embedding_origin, - const BrowserPermissionCallback& callback, - chromeos::attestation::PlatformVerificationFlow::ConsentResponse response) { - if (response == PlatformVerificationFlow::CONSENT_RESPONSE_NONE) { - // Deny request and do not save to content settings. - PermissionDecided(id, requesting_origin, embedding_origin, callback, - false, // Do not save to content settings. - false); // Do not allow the permission. - return; - } - - PermissionDecided( - id, requesting_origin, embedding_origin, callback, - true, // Save to content settings. - response == PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW); -} -#endif
diff --git a/chrome/browser/content_settings/permission_context_base.h b/chrome/browser/content_settings/permission_context_base.h index fe711ecc..740aa8f 100644 --- a/chrome/browser/content_settings/permission_context_base.h +++ b/chrome/browser/content_settings/permission_context_base.h
@@ -15,10 +15,6 @@ #include "components/keyed_service/core/keyed_service.h" #include "url/gurl.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/attestation/platform_verification_flow.h" -#endif - class PermissionQueueController; class PermissionRequestID; class Profile; @@ -131,16 +127,6 @@ // Called when a bubble is no longer used so it can be cleaned up. void CleanUpBubble(const PermissionRequestID& id); -#if defined(OS_CHROMEOS) - void OnPlatformVerificationResult( - const PermissionRequestID& id, - const GURL& requesting_origin, - const GURL& embedding_origin, - const BrowserPermissionCallback& callback, - chromeos::attestation::PlatformVerificationFlow::ConsentResponse - response); -#endif - Profile* profile_; const ContentSettingsType permission_type_; scoped_ptr<PermissionQueueController> permission_queue_controller_;
diff --git a/chrome/browser/devtools/frontend/devtools_discovery_page.html b/chrome/browser/devtools/frontend/devtools_discovery_page.html index 9d9fc57..cf93966 100644 --- a/chrome/browser/devtools/frontend/devtools_discovery_page.html +++ b/chrome/browser/devtools/frontend/devtools_discovery_page.html
@@ -32,7 +32,7 @@ padding: 10px; -webkit-transition-property: background-color, border-color; -webkit-transition: background-color 0.15s, 0.15s; - -webkit-transition-delay: 0, 0; + -webkit-transition-delay: 0ms, 0ms; } .thumbnail {
diff --git a/chrome/browser/download/download_permission_request.cc b/chrome/browser/download/download_permission_request.cc index c8ac3db4..223165f 100644 --- a/chrome/browser/download/download_permission_request.cc +++ b/chrome/browser/download/download_permission_request.cc
@@ -28,8 +28,11 @@ } bool DownloadPermissionRequest::HasUserGesture() const { - // TODO(gbillock): user gesture for multiple downloads is difficult to - // propagate, and the normal thing is that it is background. + // TODO(felt): Right now, the user gesture is not being used so this value + // does not matter. The user gesture-related code either needs to be + // deprecated, or clients (like DownloadPermissionRequest) with their own + // user intent policies need to be able to disable/control the bubble request + // visibility & coalescing logic. See crbug.com/446607. return false; }
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc index 33c3c21..a343335 100644 --- a/chrome/browser/download/download_request_limiter_unittest.cc +++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -5,10 +5,13 @@ #include "chrome/browser/download/download_request_limiter.h" #include "base/bind.h" +#include "base/command_line.h" #include "base/run_loop.h" +#include "chrome/browser/download/download_permission_request.h" #include "chrome/browser/download/download_request_infobar_delegate.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" +#include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -41,8 +44,7 @@ void SetDelegate(Delegate* delegate) override { delegate_ = delegate; } void Show(const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) override; + const std::vector<bool>& accept_state) override; bool CanAcceptRequestUpdate() override { return false; } @@ -68,9 +70,8 @@ PermissionBubbleManager::CreateForWebContents(web_contents()); view_.reset(new FakePermissionBubbleView(this)); - PermissionBubbleManager* manager = - PermissionBubbleManager::FromWebContents(web_contents()); - manager->SetView(view_.get()); + PermissionBubbleManager::FromWebContents(web_contents())-> + SetView(view_.get()); testing_action_ = ACCEPT; ask_allow_count_ = cancel_count_ = continue_count_ = 0; @@ -182,6 +183,13 @@ setting); } + void BubbleManagerDocumentLoadCompleted(bool bubbles_enabled) { + if (!bubbles_enabled) + return; + PermissionBubbleManager::FromWebContents(web_contents())-> + DocumentOnLoadCompletedInMainFrame(); + } + scoped_refptr<DownloadRequestLimiter> download_request_limiter_; // The action that FakeCreate() should take. @@ -206,8 +214,7 @@ void FakePermissionBubbleView::Show( const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) { + const std::vector<bool>& accept_state) { test_->AskAllow(); int action = test_->GetAction(); if (action == DownloadRequestLimiterTest::ACCEPT) { @@ -221,8 +228,42 @@ } } -TEST_F(DownloadRequestLimiterTest, +class DownloadRequestLimiterParamTests + : public DownloadRequestLimiterTest, + public ::testing::WithParamInterface<bool> { + protected: + DownloadRequestLimiterParamTests() {} + ~DownloadRequestLimiterParamTests() override {} + + void SetUp() override { + DownloadRequestLimiterTest::SetUp(); +#if !defined(OS_ANDROID) + if (GetParam()) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnablePermissionsBubbles); + EXPECT_TRUE(PermissionBubbleManager::Enabled()); + } else { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisablePermissionsBubbles); + } +#endif + } + + void BubbleManagerDocumentLoadCompleted() { +#if defined(OS_ANDROID) + DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(false); +#else + DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(GetParam()); +#endif + } + private: + DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiterParamTests); +}; + +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_Allow) { + BubbleManagerDocumentLoadCompleted(); + // All tabs should initially start at ALLOW_ONE_DOWNLOAD. ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD, download_request_limiter_->GetDownloadStatus(web_contents())); @@ -252,9 +293,10 @@ download_request_limiter_->GetDownloadStatus(web_contents())); } -TEST_F(DownloadRequestLimiterTest, +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_ResetOnNavigation) { NavigateAndCommit(GURL("http://foo.com/bar")); + BubbleManagerDocumentLoadCompleted(); // Do two downloads, allowing the second so that we end up with allow all. CanDownload(); @@ -271,6 +313,7 @@ // Navigate to a new URL with the same host, which shouldn't reset the allow // all state. NavigateAndCommit(GURL("http://foo.com/bar2")); + BubbleManagerDocumentLoadCompleted(); CanDownload(); ExpectAndResetCounts(1, 0, 0, __LINE__); ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS, @@ -284,6 +327,7 @@ // Navigate to a completely different host, which should reset the state. NavigateAndCommit(GURL("http://fooey.com")); + BubbleManagerDocumentLoadCompleted(); ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD, download_request_limiter_->GetDownloadStatus(web_contents())); @@ -302,15 +346,17 @@ // Navigate to a new URL with the same host, which shouldn't reset the allow // all state. NavigateAndCommit(GURL("http://fooey.com/bar2")); + BubbleManagerDocumentLoadCompleted(); CanDownload(); ExpectAndResetCounts(0, 1, 0, __LINE__); ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED, download_request_limiter_->GetDownloadStatus(web_contents())); } -TEST_F(DownloadRequestLimiterTest, +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_ResetOnUserGesture) { NavigateAndCommit(GURL("http://foo.com/bar")); + BubbleManagerDocumentLoadCompleted(); // Do one download, which should change to prompt before download. CanDownload(); @@ -348,9 +394,10 @@ download_request_limiter_->GetDownloadStatus(web_contents())); } -TEST_F(DownloadRequestLimiterTest, +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_ResetOnReload) { NavigateAndCommit(GURL("http://foo.com/bar")); + BubbleManagerDocumentLoadCompleted(); ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD, download_request_limiter_->GetDownloadStatus(web_contents())); @@ -396,7 +443,7 @@ download_request_limiter_->GetDownloadStatus(web_contents())); } -TEST_F(DownloadRequestLimiterTest, +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_RawWebContents) { scoped_ptr<WebContents> web_contents(CreateTestWebContents()); @@ -435,9 +482,10 @@ download_request_limiter_->GetDownloadStatus(web_contents.get())); } -TEST_F(DownloadRequestLimiterTest, +TEST_P(DownloadRequestLimiterParamTests, DownloadRequestLimiter_SetHostContentSetting) { NavigateAndCommit(GURL("http://foo.com/bar")); + BubbleManagerDocumentLoadCompleted(); SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW); CanDownload(); @@ -462,3 +510,7 @@ ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD, download_request_limiter_->GetDownloadStatus(web_contents())); } + +INSTANTIATE_TEST_CASE_P(DownloadRequestLimiterTestsWithAndWithoutBubbles, + DownloadRequestLimiterParamTests, + ::testing::Values(false, true));
diff --git a/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.cc b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.cc new file mode 100644 index 0000000..5671c783 --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.cc
@@ -0,0 +1,217 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/json/json_parser.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h" +#include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h" +#include "chrome/grit/browser_resources.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/enhanced_bookmarks/enhanced_bookmark_model.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/referrer.h" +#include "net/base/load_flags.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image_skia.h" + +using content::Referrer; +using bookmarks::BookmarkNode; + +namespace enhanced_bookmarks { + +BookmarkImageServiceAndroid::BookmarkImageServiceAndroid( + content::BrowserContext* browserContext) + : BookmarkImageService( + browserContext->GetPath(), + EnhancedBookmarkModelFactory::GetForBrowserContext(browserContext), + make_scoped_refptr(content::BrowserThread::GetBlockingPool())), + browser_context_(browserContext) { +} + +void BookmarkImageServiceAndroid::RetrieveSalientImage( + const GURL& page_url, + const GURL& image_url, + const std::string& referrer, + net::URLRequest::ReferrerPolicy referrer_policy, + bool update_bookmark) { + const BookmarkNode* bookmark = + enhanced_bookmark_model_->bookmark_model() + ->GetMostRecentlyAddedUserNodeForURL(page_url); + if (!bookmark || !image_url.is_valid()) { + ProcessNewImage(page_url, update_bookmark, gfx::Image(), image_url); + return; + } + + BitmapFetcherHandler* bitmap_fetcher_handler = + new BitmapFetcherHandler(this, image_url); + bitmap_fetcher_handler->Start( + browser_context_, referrer, referrer_policy, + net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES, + update_bookmark, page_url); +} + +void BookmarkImageServiceAndroid::RetrieveSalientImageFromContext( + content::RenderFrameHost* render_frame_host, + const GURL& page_url, + bool update_bookmark) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (IsPageUrlInProgress(page_url)) + return; // A request for this URL is already in progress. + + const BookmarkNode* bookmark = enhanced_bookmark_model_->bookmark_model() + ->GetMostRecentlyAddedUserNodeForURL(page_url); + if (!bookmark) + return; + + // Stop the image extraction if there is already an image present. + GURL url; + int height, width; + if (enhanced_bookmark_model_->GetOriginalImage(bookmark, &url, &width, + &height) || + enhanced_bookmark_model_->GetThumbnailImage(bookmark, &url, &width, + &height)) { + return; + } + + if (script_.empty()) { + script_ = + base::UTF8ToUTF16(ResourceBundle::GetSharedInstance() + .GetRawDataResource(IDR_GET_SALIENT_IMAGE_URL_JS) + .as_string()); + } + + render_frame_host->ExecuteJavaScript( + script_, + base::Bind( + &BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback, + base::Unretained(this), page_url, update_bookmark)); +} + +void BookmarkImageServiceAndroid::FinishSuccessfulPageLoadForTab( + content::WebContents* web_contents, bool update_bookmark) { + content::NavigationEntry* entry = + web_contents->GetController().GetVisibleEntry(); + + // If the navigation is a simple back or forward, do not extract images, those + // were extracted already. + if (!entry || (entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK)) + return; + const GURL& entry_url = entry->GetURL(); + const GURL& entry_original_url = entry->GetOriginalRequestURL(); + std::vector<GURL> urls; + urls.push_back(entry_url); + if (entry_url != entry_original_url) + urls.push_back(entry_original_url); + for (GURL url : urls) { + if (enhanced_bookmark_model_->bookmark_model()->IsBookmarked(url)) { + RetrieveSalientImageFromContext(web_contents->GetMainFrame(), url, + update_bookmark); + } + } +} + +void BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback( + const GURL& page_url, + bool update_bookmark, + const base::Value* result) { + if (!result) + return; + + std::string json; + if (!result->GetAsString(&json)) { + LOG(WARNING) + << "Salient image extracting script returned non-string result."; + return; + } + + scoped_ptr<base::Value> json_data; + int error_code = 0; + std::string errorMessage; + json_data.reset(base::JSONReader::ReadAndReturnError( + json, base::JSON_PARSE_RFC, &error_code, &errorMessage)); + if (error_code || !json_data) { + LOG(WARNING) << "JSON parse error: " << errorMessage.c_str() << json; + return; + } + + base::DictionaryValue* dict; + if (!json_data->GetAsDictionary(&dict)) { + LOG(WARNING) << "JSON parse error, not a dict: " << json; + return; + } + + std::string referrerPolicy; + std::string image_url; + dict->GetString("referrerPolicy", &referrerPolicy); + dict->GetString("imageUrl", &image_url); + + // The policy strings are guaranteed to be in lower-case. + blink::WebReferrerPolicy policy = blink::WebReferrerPolicyDefault; + if (referrerPolicy == "never") + policy = blink::WebReferrerPolicyNever; + if (referrerPolicy == "always") + policy = blink::WebReferrerPolicyAlways; + if (referrerPolicy == "origin") + policy = blink::WebReferrerPolicyOrigin; + + in_progress_page_urls_.insert(page_url); + + Referrer referrer = + Referrer::SanitizeForRequest(GURL(image_url), Referrer(page_url, policy)); + net::URLRequest::ReferrerPolicy referrer_policy = + net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; + if (!referrer.url.is_empty()) { + switch (policy) { + case blink::WebReferrerPolicyDefault: + break; + case blink::WebReferrerPolicyAlways: + case blink::WebReferrerPolicyNever: + case blink::WebReferrerPolicyOrigin: + referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER; + break; + default: + NOTREACHED(); + } + } + RetrieveSalientImage(page_url, GURL(image_url), referrer.url.spec(), + referrer_policy, update_bookmark); +} + +void BookmarkImageServiceAndroid::BitmapFetcherHandler::Start( + content::BrowserContext* browser_context, + const std::string& referrer, + net::URLRequest::ReferrerPolicy referrer_policy, + int load_flags, + bool update_bookmark, + const GURL& page_url) { + update_bookmark_ = update_bookmark; + page_url_ = page_url; + + bitmap_fetcher_.Start(browser_context->GetRequestContext(), referrer, + referrer_policy, load_flags); +} + +void BookmarkImageServiceAndroid::BitmapFetcherHandler::OnFetchComplete( + const GURL url, + const SkBitmap* bitmap) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + gfx::Image image; + if (bitmap) { + gfx::ImageSkia imageSkia = gfx::ImageSkia::CreateFrom1xBitmap(*bitmap); + imageSkia.MakeThreadSafe(); + image = gfx::Image(imageSkia); + } + service_->ProcessNewImage(page_url_, update_bookmark_, image, url); + + delete this; +} + +} // namespace enhanced_bookmarks
diff --git a/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h new file mode 100644 index 0000000..680e8dc --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h
@@ -0,0 +1,85 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_ANDROID_H_ +#define CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_ANDROID_H_ + +#include "components/enhanced_bookmarks/bookmark_image_service.h" +#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" + +namespace chrome { +class BitmapFetcher; +} + +namespace content { +class BrowserContext; +class RenderFrameHost; +class WebContents; +} + +namespace enhanced_bookmarks { + +class BookmarkImageServiceAndroid : public BookmarkImageService { + public: + explicit BookmarkImageServiceAndroid(content::BrowserContext* browserContext); + + void RetrieveSalientImage(const GURL& page_url, + const GURL& image_url, + const std::string& referrer, + net::URLRequest::ReferrerPolicy referrer_policy, + bool update_bookmark) override; + + // Searches the current page for a salient image, if a url is found the image + // is fetched and stored. + void RetrieveSalientImageFromContext( + content::RenderFrameHost* render_frame_host, + const GURL& page_url, + bool update_bookmark); + + // Investigates if the tab points to a bookmarked url in needs of an updated + // image. If it is, invokes RetrieveSalientImageFromContext() for the relevant + // urls. + void FinishSuccessfulPageLoadForTab(content::WebContents* web_contents, + bool update_bookmark); + + private: + void RetrieveSalientImageFromContextCallback(const GURL& page_url, + bool update_bookmark, + const base::Value* result); + + content::BrowserContext* browser_context_; + // The script injected in a page to extract image urls. + base::string16 script_; + + class BitmapFetcherHandler : private chrome::BitmapFetcherDelegate { + public: + explicit BitmapFetcherHandler(BookmarkImageServiceAndroid* service, + const GURL& image_url) + : service_(service), bitmap_fetcher_(image_url, this) {} + void Start(content::BrowserContext* browser_context, + const std::string& referrer, + net::URLRequest::ReferrerPolicy referrer_policy, + int load_flags, + bool update_bookmark, + const GURL& page_url); + void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override; + + protected: + ~BitmapFetcherHandler() override {} + + private: + BookmarkImageServiceAndroid* service_; + chrome::BitmapFetcher bitmap_fetcher_; + bool update_bookmark_; + GURL page_url_; + + DISALLOW_COPY_AND_ASSIGN(BitmapFetcherHandler); + }; + + DISALLOW_COPY_AND_ASSIGN(BookmarkImageServiceAndroid); +}; + +} // namespace enhanced_bookmarks + +#endif // CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_ANDROID_H_
diff --git a/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.cc b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.cc new file mode 100644 index 0000000..c994bbf --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.cc
@@ -0,0 +1,41 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h" +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +namespace enhanced_bookmarks { + +// static +BookmarkImageServiceFactory* BookmarkImageServiceFactory::GetInstance() { + return Singleton<BookmarkImageServiceFactory>::get(); +} + +// static +BookmarkImageService* BookmarkImageServiceFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<BookmarkImageService*>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +BookmarkImageServiceFactory::BookmarkImageServiceFactory() + : BrowserContextKeyedServiceFactory( + "BookmarkExtendedStorageService", + BrowserContextDependencyManager::GetInstance()) {} + +BookmarkImageServiceFactory::~BookmarkImageServiceFactory() {} + +content::BrowserContext* BookmarkImageServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return context; +} + +BookmarkImageService* BookmarkImageServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* browser_context) const { + return new BookmarkImageServiceAndroid(browser_context); +} + +} // namespace enhanced_bookmarks
diff --git a/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h new file mode 100644 index 0000000..5680138 --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h
@@ -0,0 +1,35 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_FACTORY_H_ + +#include "components/enhanced_bookmarks/bookmark_image_service.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace enhanced_bookmarks { + +class BookmarkImageServiceFactory : public BrowserContextKeyedServiceFactory { + public: + static BookmarkImageServiceFactory* GetInstance(); + static BookmarkImageService* GetForBrowserContext( + content::BrowserContext* context); + + ~BookmarkImageServiceFactory() override; + + private: + friend struct DefaultSingletonTraits<BookmarkImageServiceFactory>; + + BookmarkImageServiceFactory(); + + BookmarkImageService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; +}; + +} // namespace enhanced_bookmarks + +#endif // CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_BOOKMARK_IMAGE_SERVICE_FACTORY_H_
diff --git a/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.cc b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.cc new file mode 100644 index 0000000..1b5675b --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.cc
@@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h" + +#include "chrome/browser/bookmarks/enhanced_bookmarks_features.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h" +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h" +#include "chrome/browser/profiles/profile.h" + +using enhanced_bookmarks::BookmarkImageServiceAndroid; +using enhanced_bookmarks::BookmarkImageServiceFactory; + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(EnhancedBookmarkTabHelper); + +void EnhancedBookmarkTabHelper::DocumentOnLoadCompletedInMainFrame() { + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + + if (profile->IsOffTheRecord()) + return; + + bool is_enhanced_bookmarks_enabled = + IsEnhancedBookmarksEnabled(profile->GetPrefs()); + if (!is_enhanced_bookmarks_enabled) + return; + + BookmarkImageServiceAndroid* storage = + static_cast<BookmarkImageServiceAndroid*>( + BookmarkImageServiceFactory::GetForBrowserContext(profile)); + storage->FinishSuccessfulPageLoadForTab(web_contents(), + is_enhanced_bookmarks_enabled); +} + +EnhancedBookmarkTabHelper::EnhancedBookmarkTabHelper( + content::WebContents* contents) + : content::WebContentsObserver(contents) { +}
diff --git a/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h new file mode 100644 index 0000000..1d2c315 --- /dev/null +++ b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h
@@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARK_TAB_HELPER_H_ +#define CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARK_TAB_HELPER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +class EnhancedBookmarkTabHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<EnhancedBookmarkTabHelper> { + public: + ~EnhancedBookmarkTabHelper() override {}; + + // content::WebContentsObserver overrides. + void DocumentOnLoadCompletedInMainFrame() override; + + private: + explicit EnhancedBookmarkTabHelper(content::WebContents* contents); + friend class content::WebContentsUserData<EnhancedBookmarkTabHelper>; + + DISALLOW_COPY_AND_ASSIGN(EnhancedBookmarkTabHelper); +}; + +#endif // CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARK_TAB_HELPER_H_
diff --git a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.cc similarity index 84% rename from chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc rename to chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.cc index f455b3b..eadcae7 100644 --- a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc +++ b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.cc
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h" +#include "chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/prefs/pref_service.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h" #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h" #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service_factory.h" #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h" @@ -20,17 +21,46 @@ #include "components/bookmarks/browser/bookmark_utils.h" #include "components/bookmarks/common/android/bookmark_id.h" #include "components/bookmarks/common/android/bookmark_type.h" +#include "components/enhanced_bookmarks/bookmark_image_service.h" #include "components/enhanced_bookmarks/enhanced_bookmark_model.h" +#include "components/enhanced_bookmarks/image_record.h" #include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/browser_thread.h" #include "jni/EnhancedBookmarksBridge_jni.h" +#include "ui/gfx/android/java_bitmap.h" +#include "ui/gfx/image/image.h" using base::android::AttachCurrentThread; +using base::android::ScopedJavaGlobalRef; using bookmarks::android::JavaBookmarkIdCreateBookmarkId; using bookmarks::android::JavaBookmarkIdGetId; using bookmarks::android::JavaBookmarkIdGetType; +using bookmarks::BookmarkNode; using bookmarks::BookmarkType; using content::BrowserThread; +using enhanced_bookmarks::ImageRecord; + +namespace { + +void Callback(ScopedJavaGlobalRef<jobject>* j_callback, + const ImageRecord& image_record) { + JNIEnv* env = base::android::AttachCurrentThread(); + + scoped_ptr<ScopedJavaGlobalRef<jobject> > j_callback_ptr(j_callback); + ScopedJavaLocalRef<jstring> j_url = + base::android::ConvertUTF8ToJavaString(env, image_record.url.spec()); + + SkBitmap bitmap = image_record.image.AsBitmap(); + ScopedJavaLocalRef<jobject> j_bitmap; + if (!bitmap.isNull()) { + j_bitmap = gfx::ConvertToJavaBitmap(&bitmap); + } + + enhanced_bookmarks::android::Java_SalientImageCallback_onSalientImageReady( + env, j_callback_ptr->obj(), j_bitmap.Release(), j_url.Release()); +} + +} // namespace namespace enhanced_bookmarks { namespace android { @@ -45,6 +75,8 @@ cluster_service_ = ChromeBookmarkServerClusterServiceFactory::GetForBrowserContext(profile_); cluster_service_->AddObserver(this); + bookmark_image_service_ = + BookmarkImageServiceFactory::GetForBrowserContext(profile_); search_service_.reset(new BookmarkServerSearchService( profile_->GetRequestContext(), ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), @@ -62,6 +94,20 @@ delete this; } +void EnhancedBookmarksBridge::SalientImageForUrl(JNIEnv* env, + jobject obj, + jstring j_url, + jobject j_callback) { + DCHECK(j_callback); + + GURL url(base::android::ConvertJavaStringToUTF16(env, j_url)); + scoped_ptr<ScopedJavaGlobalRef<jobject>> j_callback_ptr( + new ScopedJavaGlobalRef<jobject>()); + j_callback_ptr->Reset(env, j_callback); + bookmark_image_service_->SalientImageForUrl( + url, base::Bind(&Callback, j_callback_ptr.release())); +} + ScopedJavaLocalRef<jstring> EnhancedBookmarksBridge::GetBookmarkDescription( JNIEnv* env, jobject obj, jlong id, jint type) { DCHECK(enhanced_bookmark_model_->loaded()); @@ -243,7 +289,7 @@ if (service == cluster_service_) { Java_EnhancedBookmarksBridge_onFiltersChanged(env, obj.obj()); - } else if (service == search_service_.get()){ + } else if (service == search_service_.get()) { Java_EnhancedBookmarksBridge_onSearchResultReturned(env, obj.obj()); } }
diff --git a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h similarity index 83% rename from chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h rename to chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h index 8018b4c..ec6f54e 100644 --- a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h +++ b/chrome/browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARKS_BRIDGE_H_ -#define CHROME_BROWSER_ANDROID_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARKS_BRIDGE_H_ +#ifndef CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARKS_BRIDGE_H_ +#define CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARKS_BRIDGE_H_ #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" @@ -15,6 +15,7 @@ namespace enhanced_bookmarks { class BookmarkServerClusterService; +class BookmarkImageService; namespace android { @@ -24,6 +25,11 @@ ~EnhancedBookmarksBridge() override; void Destroy(JNIEnv*, jobject); + void SalientImageForUrl(JNIEnv* env, + jobject obj, + jstring j_url, + jobject j_callback); + base::android::ScopedJavaLocalRef<jstring> GetBookmarkDescription( JNIEnv* env, jobject obj, @@ -76,11 +82,12 @@ void OnChange(BookmarkServerService* service) override; private: - bool IsEditable(const BookmarkNode* node) const; + bool IsEditable(const bookmarks::BookmarkNode* node) const; JavaObjectWeakGlobalRef weak_java_ref_; - EnhancedBookmarkModel* enhanced_bookmark_model_; // weak - BookmarkServerClusterService* cluster_service_; // weak + EnhancedBookmarkModel* enhanced_bookmark_model_; // weak + BookmarkServerClusterService* cluster_service_; // weak + BookmarkImageService* bookmark_image_service_; // weak scoped_ptr<BookmarkServerSearchService> search_service_; Profile* profile_; // weak DISALLOW_COPY_AND_ASSIGN(EnhancedBookmarksBridge); @@ -91,4 +98,4 @@ } // namespace android } // namespace enhanced_bookmarks -#endif // CHROME_BROWSER_ANDROID_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARKS_BRIDGE_H_ +#endif // CHROME_BROWSER_ENHANCED_BOOKMARKS_ANDROID_ENHANCED_BOOKMARKS_BRIDGE_H_
diff --git a/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.cc b/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.cc index 2643b399..82c5be6 100644 --- a/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.cc +++ b/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.cc
@@ -7,6 +7,8 @@ #include "chrome/browser/sync/profile_sync_service.h" #include "components/enhanced_bookmarks/enhanced_bookmark_model.h" +using bookmarks::BookmarkNode; + namespace enhanced_bookmarks { ChromeBookmarkServerClusterService::ChromeBookmarkServerClusterService(
diff --git a/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h b/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h index c986a04..abe1c51 100644 --- a/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h +++ b/chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h
@@ -34,9 +34,11 @@ void OnSyncCycleCompleted() override; // EnhancedBookmarkModelObserver implementation. - void EnhancedBookmarkAdded(const BookmarkNode* node) override; - void EnhancedBookmarkRemoved(const BookmarkNode* node) override; - void EnhancedBookmarkNodeChanged(const BookmarkNode* node) override; + void EnhancedBookmarkAdded(const bookmarks::BookmarkNode* node) override; + void EnhancedBookmarkRemoved(const bookmarks::BookmarkNode* node) override; + void EnhancedBookmarkNodeChanged( + const bookmarks::BookmarkNode* node) override; + private: // This sets an internal flag to fetch new clusters. void InvalidateCache();
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 869e37fa..061b8c13 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -72,6 +72,7 @@ "//third_party/webrtc/modules/desktop_capture", "//ui/accessibility:ax_gen", "//ui/base", + "//ui/base/ime", "//ui/gfx", "//ui/gfx/geometry", "//ui/resources",
diff --git a/chrome/browser/extensions/active_script_controller.cc b/chrome/browser/extensions/active_script_controller.cc index f3b73b9..6ef7217 100644 --- a/chrome/browser/extensions/active_script_controller.cc +++ b/chrome/browser/extensions/active_script_controller.cc
@@ -37,31 +37,11 @@ namespace extensions { -namespace { - -// Returns true if the extension should be regarded as a "permitted" extension -// for the case of metrics. We need this because we only actually withhold -// permissions if the switch is enabled, but want to record metrics in all -// cases. -// "ExtensionWouldHaveHadHostPermissionsWithheldIfSwitchWasOn()" would be -// more accurate, but too long. -bool ShouldRecordExtension(const Extension* extension) { - return extension->ShouldDisplayInExtensionSettings() && - !Manifest::IsPolicyLocation(extension->location()) && - !Manifest::IsComponentLocation(extension->location()) && - !PermissionsData::CanExecuteScriptEverywhere(extension) && - extension->permissions_data() - ->active_permissions() - ->ShouldWarnAllHosts(); -} - -} // namespace - ActiveScriptController::ActiveScriptController( content::WebContents* web_contents) : content::WebContentsObserver(web_contents), browser_context_(web_contents->GetBrowserContext()), - enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()), + was_used_on_page_(false), extension_registry_observer_(this) { CHECK(web_contents); extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); @@ -143,7 +123,7 @@ } bool ActiveScriptController::WantsToRun(const Extension* extension) { - return enabled_ && pending_requests_.count(extension->id()) > 0; + return pending_requests_.count(extension->id()) > 0; } PermissionsData::AccessType @@ -152,11 +132,6 @@ UserScript::InjectionType type) { CHECK(extension); - // If the feature is not enabled, we automatically allow all extensions to - // run scripts. - if (!enabled_) - permitted_extensions_.insert(extension->id()); - // Allow the extension if it's been explicitly granted permission. if (permitted_extensions_.count(extension->id()) > 0) return PermissionsData::ACCESS_ALLOWED; @@ -187,6 +162,8 @@ // to run. if (list.size() == 1u) NotifyChange(extension); + + was_used_on_page_ = true; } void ActiveScriptController::RunPendingForExtension( @@ -253,8 +230,9 @@ // ran (because this feature is not enabled). Add the extension to the list of // permitted extensions (for metrics), and return immediately. if (request_id == -1) { - if (ShouldRecordExtension(extension)) { - DCHECK(!enabled_); + if (util::ScriptsMayRequireActionForExtension( + extension, + extension->permissions_data()->active_permissions().get())) { permitted_extensions_.insert(extension->id()); } return; @@ -313,9 +291,9 @@ "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", pending_requests_.size()); - // We only log the permitted extensions metric if the feature is enabled, - // because otherwise the data will be boring (100% allowed). - if (enabled_) { + // We only log the permitted extensions metric if the feature was used at all + // on the page, because otherwise the data will be boring. + if (was_used_on_page_) { UMA_HISTOGRAM_COUNTS_100( "Extensions.ActiveScriptController.PermittedExtensions", permitted_extensions_.size()); @@ -344,6 +322,7 @@ LogUMA(); permitted_extensions_.clear(); pending_requests_.clear(); + was_used_on_page_ = false; } void ActiveScriptController::OnExtensionUnloaded(
diff --git a/chrome/browser/extensions/active_script_controller.h b/chrome/browser/extensions/active_script_controller.h index 169ac11..b4310950 100644 --- a/chrome/browser/extensions/active_script_controller.h +++ b/chrome/browser/extensions/active_script_controller.h
@@ -130,10 +130,9 @@ // The associated browser context. content::BrowserContext* browser_context_; - // Whether or not the ActiveScriptController is enabled (corresponding to the - // kActiveScriptEnforcement switch). If it is not, it acts as an empty shell, - // always allowing scripts to run and never displaying actions. - bool enabled_; + // Whether or not the feature was used for any extensions. This may not be the + // case if the user never enabled the scripts-require-action flag. + bool was_used_on_page_; // The map of extension_id:pending_request of all pending requests. PendingRequestMap pending_requests_;
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc index 4e73838..32cbd69f 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.cc +++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -8,9 +8,11 @@ #include "chrome/browser/profiles/profile.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/process_manager.h" #include "extensions/common/extension_messages.h" #include "extensions/common/feature_switch.h" #include "extensions/common/permissions/permission_set.h" @@ -18,16 +20,59 @@ #include "extensions/common/user_script.h" #include "url/gurl.h" -using content::RenderProcessHost; -using content::WebContentsObserver; - namespace extensions { +namespace { + +using CreateMessageFunction = base::Callback<IPC::Message*(bool)>; + +// Creates a new IPC message for updating tab-specific permissions. +IPC::Message* CreateUpdateMessage(const GURL& visible_url, + const std::string& extension_id, + const URLPatternSet& new_hosts, + int tab_id, + bool update_whitelist) { + return new ExtensionMsg_UpdateTabSpecificPermissions( + visible_url, extension_id, new_hosts, update_whitelist, tab_id); +} + +// Creates a new IPC message for clearing tab-specific permissions. +IPC::Message* CreateClearMessage(const std::vector<std::string>& ids, + int tab_id, + bool update_whitelist) { + return new ExtensionMsg_ClearTabSpecificPermissions( + ids, update_whitelist, tab_id); +} + +// Sends a message exactly once to each render process host owning one of the +// given |view_hosts| and |tab_process|. If |tab_process| doesn't own any of the +// |view_hosts|, it will not be signaled to update its origin whitelist. +void SendMessageToProcesses( + const std::set<content::RenderViewHost*>& view_hosts, + content::RenderProcessHost* tab_process, + const CreateMessageFunction& create_message) { + std::set<content::RenderProcessHost*> sent_to_hosts; + for (content::RenderViewHost* view_host : view_hosts) { + content::RenderProcessHost* process_host = view_host->GetProcess(); + if (sent_to_hosts.count(process_host) == 0) { + // Extension processes have to update the origin whitelists. + process_host->Send(create_message.Run(true)); + sent_to_hosts.insert(view_host->GetProcess()); + } + } + // If the tab wasn't one of those processes already updated (it likely + // wasn't), update it. Tabs don't need to update the origin whitelist. + if (sent_to_hosts.count(tab_process) == 0) + tab_process->Send(create_message.Run(false)); +} + +} // namespace + ActiveTabPermissionGranter::ActiveTabPermissionGranter( content::WebContents* web_contents, int tab_id, Profile* profile) - : WebContentsObserver(web_contents), + : content::WebContentsObserver(web_contents), tab_id_(tab_id), extension_registry_observer_(this) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); @@ -66,13 +111,20 @@ const content::NavigationEntry* navigation_entry = web_contents()->GetController().GetVisibleEntry(); if (navigation_entry) { - content::RenderViewHost* render_view_host = - web_contents()->GetRenderViewHost(); - render_view_host->Send(new ExtensionMsg_UpdateTabSpecificPermissions( - render_view_host->GetRoutingID(), - navigation_entry->GetURL(), - extension->id(), - new_hosts)); + // We update all extension render views with the new tab permissions, and + // also the tab itself. + CreateMessageFunction update_message = + base::Bind(&CreateUpdateMessage, + navigation_entry->GetURL(), + extension->id(), + new_hosts, + tab_id_); + SendMessageToProcesses( + ProcessManager::Get(web_contents()->GetBrowserContext())-> + GetRenderViewHostsForExtension(extension->id()), + web_contents()->GetRenderProcessHost(), + update_message); + // If more things ever need to know about this, we should consider making // an observer class. // It's important that this comes after the IPC is sent to the renderer, @@ -128,18 +180,24 @@ if (granted_extensions_.is_empty()) return; + std::set<content::RenderViewHost*> view_hosts; std::vector<std::string> extension_ids; - - for (ExtensionSet::const_iterator it = granted_extensions_.begin(); - it != granted_extensions_.end(); ++it) { - it->get()->permissions_data()->ClearTabSpecificPermissions(tab_id_); - extension_ids.push_back((*it)->id()); + ProcessManager* process_manager = + ProcessManager::Get(web_contents()->GetBrowserContext()); + for (const scoped_refptr<const Extension>& extension : granted_extensions_) { + extension->permissions_data()->ClearTabSpecificPermissions(tab_id_); + extension_ids.push_back(extension->id()); + std::set<content::RenderViewHost*> extension_view_hosts = + process_manager->GetRenderViewHostsForExtension(extension->id()); + view_hosts.insert(extension_view_hosts.begin(), extension_view_hosts.end()); } - content::RenderViewHost* render_view_host = - web_contents()->GetRenderViewHost(); - render_view_host->Send(new ExtensionMsg_ClearTabSpecificPermissions( - render_view_host->GetRoutingID(), extension_ids)); + CreateMessageFunction clear_message = + base::Bind(&CreateClearMessage, extension_ids, tab_id_); + SendMessageToProcesses(view_hosts, + web_contents()->GetRenderProcessHost(), + clear_message); + granted_extensions_.Clear(); }
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index 105ef67..85b84830 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -43,7 +43,9 @@ #include "ui/base/webui/web_ui_util.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; +using content::WebContents; namespace extensions { @@ -67,8 +69,6 @@ namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo; namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo; -using content::WebContents; - namespace { // Returns a single bookmark node from the argument ID.
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h index 9adb7b5..35a612c5 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
@@ -40,10 +40,11 @@ // bookmarks::BaseBookmarkModelObserver: void BookmarkModelChanged() override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; - void OnWillChangeBookmarkMetaInfo(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + void OnWillChangeBookmarkMetaInfo( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void BookmarkMetaInfoChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; private: // Helper to actually dispatch an event to extension listeners. @@ -51,7 +52,7 @@ scoped_ptr<base::ListValue> event_args); // Remembers the previous meta info of a node before it was changed. - BookmarkNode::MetaInfoMap prev_meta_info_; + bookmarks::BookmarkNode::MetaInfoMap prev_meta_info_; content::BrowserContext* browser_context_; bookmarks::BookmarkModel* bookmark_model_;
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc index 6bedfc7..5fedf2d 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
@@ -21,6 +21,7 @@ #include "components/user_prefs/user_prefs.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // Times out on win syzyasan, http://crbug.com/166026 #if defined(SYZYASAN)
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc index 501e99a..82c8d7d 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc
@@ -16,6 +16,7 @@ #include "components/bookmarks/browser/bookmark_utils.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace extensions {
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h index 43557f0..e128501 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h +++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h
@@ -11,11 +11,11 @@ #include "base/basictypes.h" #include "chrome/common/extensions/api/bookmarks.h" -class BookmarkNode; class ChromeBookmarkClient; namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // Helper functions. @@ -25,18 +25,18 @@ // The returned value is owned by the caller. api::bookmarks::BookmarkTreeNode* GetBookmarkTreeNode( ChromeBookmarkClient* client, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, bool recurse, bool only_folders); // Add a JSON representation of |node| to the JSON |nodes|. void AddNode(ChromeBookmarkClient* client, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> >* nodes, bool recurse); void AddNodeFoldersOnly(ChromeBookmarkClient* client, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, std::vector<linked_ptr< api::bookmarks::BookmarkTreeNode> >* nodes, bool recurse); @@ -48,7 +48,7 @@ std::string* error); // Get meta info from |node| and all it's children recursively. -void GetMetaInfo(const BookmarkNode& node, +void GetMetaInfo(const bookmarks::BookmarkNode& node, base::DictionaryValue* id_to_meta_info_map); } // namespace bookmark_api_helpers
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc index 0239876..2f6d5fa 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
@@ -20,6 +20,7 @@ #include "testing/gtest/include/gtest/gtest.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace extensions {
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc index 0389f26..126e618 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -52,6 +52,7 @@ #endif using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace extensions {
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h index 2d4ab19..9c3f082c 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h +++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
@@ -49,26 +49,27 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void ExtensiveBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override; void ExtensiveBookmarkChangesEnded(bookmarks::BookmarkModel* model) override; @@ -141,14 +142,15 @@ // Helper to get the bookmark node from a given string id. // If the given id can't be parsed or doesn't refer to a valid node, sets // error_ and returns NULL. - const BookmarkNode* GetBookmarkNodeFromId(const std::string& id_string); + const bookmarks::BookmarkNode* GetBookmarkNodeFromId( + const std::string& id_string); // Helper to create a bookmark node from a CreateDetails object. If a node // can't be created based on the given details, sets error_ and returns NULL. - const BookmarkNode* CreateBookmarkNode( + const bookmarks::BookmarkNode* CreateBookmarkNode( bookmarks::BookmarkModel* model, const api::bookmarks::CreateDetails& details, - const BookmarkNode::MetaInfoMap* meta_info); + const bookmarks::BookmarkNode::MetaInfoMap* meta_info); // Helper that checks if bookmark editing is enabled. If it's not, this sets // error_ to the appropriate error string. @@ -158,7 +160,7 @@ // is NULL, or a managed node, or the root node. In these cases the node // can't be edited, can't have new child nodes appended, and its direct // children can't be moved or reordered. - bool CanBeModified(const BookmarkNode* node); + bool CanBeModified(const bookmarks::BookmarkNode* node); private: // bookmarks::BaseBookmarkModelObserver:
diff --git a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc index 5b428547..5236b96 100644 --- a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc +++ b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc
@@ -48,8 +48,7 @@ // Replace the host with 'www.cloudprintapp.com' so it matches the cloud // print app's extent. GURL::Replacements replace_host; - std::string host_str("www.cloudprintapp.com"); - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("www.cloudprintapp.com"); return url.ReplaceComponents(replace_host); } };
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc index d2aa388f..fd4e97d7 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -700,13 +700,6 @@ bool EasyUnlockPrivateGetConnectionInfoFunction::DoWork( scoped_refptr<device::BluetoothAdapter> adapter) { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - proximity_auth::switches::kEnableProximityDetection)) { - SetError("Turn on 'enable-easy-unlock-proximity-detection' flag."); - SendResponse(false); - return true; - } - scoped_ptr<easy_unlock_private::GetConnectionInfo::Params> params = easy_unlock_private::GetConnectionInfo::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/extensions/api/gcm/gcm_apitest.cc b/chrome/browser/extensions/api/gcm/gcm_apitest.cc index d72b7f2..1506241 100644 --- a/chrome/browser/extensions/api/gcm/gcm_apitest.cc +++ b/chrome/browser/extensions/api/gcm/gcm_apitest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/prefs/pref_service.h" #include "base/run_loop.h" #include "chrome/browser/extensions/api/gcm/gcm_api.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -11,7 +10,6 @@ #include "chrome/browser/services/gcm/fake_gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/test/result_catcher.h" @@ -85,9 +83,6 @@ } void GcmApiTest::SetUpOnMainThread() { - // Enable GCM such that tests could be run on all channels. - browser()->profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); - gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory( browser()->profile(), &gcm::FakeGCMProfileService::Build); fake_gcm_profile_service_ = static_cast<gcm::FakeGCMProfileService*>(
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index e465ba7..ea174a7 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -132,8 +132,7 @@ } bookmark_app_helper_.reset(new extensions::BookmarkAppHelper( - extensions::ExtensionSystem::Get(context)->extension_service(), web_app, - NULL)); + Profile::FromBrowserContext(context), web_app, NULL)); bookmark_app_helper_->Create( base::Bind(&extensions::ManagementGenerateAppForLinkFunction:: FinishCreateBookmarkApp,
diff --git a/chrome/browser/extensions/api/platform_keys/OWNERS b/chrome/browser/extensions/api/platform_keys/OWNERS new file mode 100644 index 0000000..713045b6 --- /dev/null +++ b/chrome/browser/extensions/api/platform_keys/OWNERS
@@ -0,0 +1 @@ +pneubeck@chromium.org
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc index 819558be..9a4e2d2 100644 --- a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc +++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
@@ -17,6 +17,7 @@ namespace extensions { +namespace api_pk = api::platform_keys; namespace api_pki = api::platform_keys_internal; namespace platform_keys { @@ -53,6 +54,59 @@ } // namespace platform_keys +PlatformKeysInternalSelectClientCertificatesFunction:: + ~PlatformKeysInternalSelectClientCertificatesFunction() { +} + +ExtensionFunction::ResponseAction +PlatformKeysInternalSelectClientCertificatesFunction::Run() { + scoped_ptr<api_pki::SelectClientCertificates::Params> params( + api_pki::SelectClientCertificates::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + chromeos::PlatformKeysService* service = + chromeos::PlatformKeysServiceFactory::GetForBrowserContext( + browser_context()); + DCHECK(service); + + chromeos::platform_keys::ClientCertificateRequest request; + for (const std::vector<char>& cert_authority : + params->details.request.certificate_authorities) { + request.certificate_authorities.push_back( + std::string(cert_authority.begin(), cert_authority.end())); + } + + service->SelectClientCertificates( + request, extension_id(), + base::Bind(&PlatformKeysInternalSelectClientCertificatesFunction:: + OnSelectedCertificates, + this)); + return RespondLater(); +} + +void PlatformKeysInternalSelectClientCertificatesFunction:: + OnSelectedCertificates(scoped_ptr<net::CertificateList> matches, + const std::string& error_message) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (!error_message.empty()) { + Respond(Error(error_message)); + return; + } + DCHECK(matches); + std::vector<linked_ptr<api_pk::Match>> result_matches; + for (const scoped_refptr<net::X509Certificate>& match : *matches) { + linked_ptr<api_pk::Match> result_match(new api_pk::Match); + std::string der_encoded_cert; + net::X509Certificate::GetDEREncoded(match->os_cert_handle(), + &der_encoded_cert); + result_match->certificate.assign(der_encoded_cert.begin(), + der_encoded_cert.end()); + result_matches.push_back(result_match); + } + Respond(ArgumentList( + api_pki::SelectClientCertificates::Results::Create(result_matches))); +} + PlatformKeysInternalSignFunction::~PlatformKeysInternalSignFunction() { }
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api.h b/chrome/browser/extensions/api/platform_keys/platform_keys_api.h index def650c..a423e9df 100644 --- a/chrome/browser/extensions/api/platform_keys/platform_keys_api.h +++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api.h
@@ -6,9 +6,15 @@ #define CHROME_BROWSER_EXTENSIONS_API_PLATFORM_KEYS_PLATFORM_KEYS_API_H_ #include <string> +#include <vector> #include "chrome/browser/extensions/chrome_extension_function.h" +namespace net { +class X509Certificate; +typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; +} + namespace extensions { namespace platform_keys { @@ -25,6 +31,21 @@ } // namespace platform_keys +class PlatformKeysInternalSelectClientCertificatesFunction + : public ChromeUIThreadExtensionFunction { + private: + ~PlatformKeysInternalSelectClientCertificatesFunction() override; + ResponseAction Run() override; + + // Called when the certificates were selected. If an error occurred, |certs| + // will be null and instead |error_message| be set. + void OnSelectedCertificates(scoped_ptr<net::CertificateList> matches, + const std::string& error_message); + + DECLARE_EXTENSION_FUNCTION("platformKeysInternal.selectClientCertificates", + PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES); +}; + class PlatformKeysInternalSignFunction : public ChromeUIThreadExtensionFunction { private:
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc new file mode 100644 index 0000000..c15fb5e --- /dev/null +++ b/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc
@@ -0,0 +1,184 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <cryptohi.h> + +#include "base/macros.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/net/nss_context.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/login/user_names.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/common/policy_map.h" +#include "content/public/browser/notification_service.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/test_utils.h" +#include "crypto/nss_util_internal.h" +#include "crypto/scoped_test_system_nss_key_slot.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/notification_types.h" +#include "net/base/net_errors.h" +#include "net/base/test_data_directory.h" +#include "net/cert/nss_cert_database.h" +#include "net/test/cert_test_util.h" +#include "net/test/url_request/url_request_mock_http_job.h" +#include "policy/policy_constants.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace { + +enum DeviceStatus { DEVICE_STATUS_ENROLLED, DEVICE_STATUS_NOT_ENROLLED }; + +enum UserAffiliation { + USER_AFFILIATION_ENROLLED_DOMAIN, + USER_AFFILIATION_UNRELATED +}; + +struct Params { + Params(DeviceStatus device_status, UserAffiliation user_affiliation) + : device_status_(device_status), user_affiliation_(user_affiliation) {} + + DeviceStatus device_status_; + UserAffiliation user_affiliation_; +}; + +class PlatformKeysTest : public ExtensionApiTest, + public ::testing::WithParamInterface<Params> { + public: + PlatformKeysTest() {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + ExtensionApiTest::SetUpCommandLine(command_line); + + std::string user_email = "someuser@anydomain.com"; + + // The command line flag kLoginUser determines the user's email and thus + // his affiliation to the domain that the device is enrolled to. + if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) + user_email = chromeos::login::kStubUser; + + command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, user_email); + } + + void SetUpInProcessBrowserTestFixture() override { + ExtensionApiTest::SetUpInProcessBrowserTestFixture(); + + if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) { + device_policy_test_helper_.device_policy()->policy_data().set_username( + chromeos::login::kStubUser); + + device_policy_test_helper_.device_policy()->Build(); + device_policy_test_helper_.MarkAsEnterpriseOwned(); + } + } + + void SetUpOnMainThread() override { + { + base::RunLoop loop; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&PlatformKeysTest::SetUpTestSystemSlotOnIO, + base::Unretained(this), + browser()->profile()->GetResourceContext(), + loop.QuitClosure())); + loop.Run(); + } + + ExtensionApiTest::SetUpOnMainThread(); + + { + base::RunLoop loop; + GetNSSCertDatabaseForProfile( + browser()->profile(), + base::Bind(&PlatformKeysTest::SetupTestCerts, base::Unretained(this), + loop.QuitClosure())); + loop.Run(); + } + + chromeos::PlatformKeysServiceFactory::GetForBrowserContext( + browser()->profile())->DisablePermissionCheckForTesting(); + } + + void TearDownOnMainThread() override { + ExtensionApiTest::TearDownOnMainThread(); + + base::RunLoop loop; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&PlatformKeysTest::TearDownTestSystemSlotOnIO, + base::Unretained(this), loop.QuitClosure())); + loop.Run(); + } + + private: + void SetupTestCerts(const base::Closure& done_callback, + net::NSSCertDatabase* cert_db) { + scoped_refptr<net::X509Certificate> client_cert1 = + net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(), + "client_1.pem", "client_1.pk8", + cert_db->GetPrivateSlot().get()); + ASSERT_TRUE(client_cert1.get()); + + // Import a second client cert signed by another CA than client_1 into the + // system wide key slot. + scoped_refptr<net::X509Certificate> client_cert2 = + net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(), + "client_2.pem", "client_2.pk8", + test_system_slot_->slot()); + ASSERT_TRUE(client_cert2.get()); + + done_callback.Run(); + } + + void SetUpTestSystemSlotOnIO(content::ResourceContext* context, + const base::Closure& done_callback) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + test_system_slot_.reset(new crypto::ScopedTestSystemNSSKeySlot()); + ASSERT_TRUE(test_system_slot_->ConstructedSuccessfully()); + + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + done_callback); + } + + void TearDownTestSystemSlotOnIO(const base::Closure& done_callback) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + test_system_slot_.reset(); + + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + done_callback); + } + + policy::DevicePolicyCrosTestHelper device_policy_test_helper_; + scoped_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_; +}; + +} // namespace + +IN_PROC_BROWSER_TEST_P(PlatformKeysTest, Basic) { + // By default, the system token is not available. + std::string system_token_availability; + + // Only if the current user is of the same domain as the device is enrolled + // to, the system token is available to the extension. + if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED && + GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) { + system_token_availability = "systemTokenEnabled"; + } + + ASSERT_TRUE(RunExtensionSubtest("platform_keys", + "basic.html?" + system_token_availability)) + << message_; +} + +INSTANTIATE_TEST_CASE_P( + CheckSystemTokenAvailability, + PlatformKeysTest, + ::testing::Values( + Params(DEVICE_STATUS_ENROLLED, USER_AFFILIATION_ENROLLED_DOMAIN), + Params(DEVICE_STATUS_ENROLLED, USER_AFFILIATION_UNRELATED), + Params(DEVICE_STATUS_NOT_ENROLLED, USER_AFFILIATION_UNRELATED)));
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc index 2faf9f2..01b690e 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -316,10 +316,10 @@ ResultCatcher catcher; // Navigate to a URL on a different hostname. - std::string initial_host = "www.example.com"; - host_resolver()->AddRule(initial_host, "127.0.0.1"); + static const char kInitialHost[] = "www.example.com"; + host_resolver()->AddRule(kInitialHost, "127.0.0.1"); GURL::Replacements replacements; - replacements.SetHostStr(initial_host); + replacements.SetHostStr(kInitialHost); GURL initial_url = test_server_->GetURL("/index.html").ReplaceComponents(replacements); ui_test_utils::NavigateToURL(browser(), initial_url);
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc index b96d23e..fe9b644 100644 --- a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc +++ b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
@@ -134,8 +134,7 @@ // Replace the host with 'www.example.com' so it matches the web store // app's extent. GURL::Replacements replace_host; - std::string host_str("www.example.com"); - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("www.example.com"); return url.ReplaceComponents(replace_host); }
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index a189991..09a0e0c 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -49,8 +49,7 @@ // as in the test apps manifests. GURL GetTestBaseURL(const std::string& test_directory) { GURL::Replacements replace_host; - std::string host_str("localhost"); // must stay in scope with replace_host - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL base_url = embedded_test_server()->GetURL( "/extensions/api_test/" + test_directory + "/"); return base_url.ReplaceComponents(replace_host);
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc index f7632ec..6d8c2f12 100644 --- a/chrome/browser/extensions/bookmark_app_helper.cc +++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -6,18 +6,31 @@ #include <cctype> +#include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/favicon_downloader.h" +#include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/app_list_service.h" +#include "chrome/browser/ui/app_list/app_list_util.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/host_desktop.h" +#include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" +#include "chrome/common/url_constants.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" +#include "extensions/browser/extension_system.h" #include "extensions/browser/image_loader.h" #include "extensions/browser/notification_types.h" +#include "extensions/browser/pref_names.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/icons_handler.h" @@ -38,6 +51,16 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_family.h" +#if defined(OS_MACOSX) +#include "base/command_line.h" +#include "chrome/browser/web_applications/web_app_mac.h" +#include "chrome/common/chrome_switches.h" +#endif + +#if defined(USE_ASH) +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#endif + namespace { // Overlays a shortcut icon over the bottom left corner of a given image. @@ -218,12 +241,19 @@ icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size]); } -BookmarkAppHelper::BookmarkAppHelper(ExtensionService* service, +BookmarkAppHelper::BookmarkAppHelper(Profile* profile, WebApplicationInfo web_app_info, content::WebContents* contents) - : contents_(contents), + : profile_(profile), + contents_(contents), web_app_info_(web_app_info), - crx_installer_(extensions::CrxInstaller::CreateSilent(service)) { + crx_installer_(extensions::CrxInstaller::CreateSilent( + ExtensionSystem::Get(profile)->extension_service())) { + web_app_info_.open_as_window = + profile_->GetPrefs()->GetInteger( + extensions::pref_names::kBookmarkAppCreationLaunchType) == + extensions::LAUNCH_TYPE_WINDOW; + registrar_.Add(this, extensions::NOTIFICATION_CRX_INSTALLER_DONE, content::Source<CrxInstaller>(crx_installer_.get())); @@ -279,7 +309,7 @@ // app creation. if (!success) { favicon_downloader_.reset(); - callback_.Run(NULL, web_app_info_); + callback_.Run(nullptr, web_app_info_); return; } @@ -335,10 +365,106 @@ web_app_info_.generated_icon_color, &generated_icons); ReplaceWebAppIcons(generated_icons, &web_app_info_); - - // Install the app. - crx_installer_->InstallWebApp(web_app_info_); favicon_downloader_.reset(); + + if (!contents_) { + // The web contents can be null in tests. + OnBubbleCompleted(true, web_app_info_); + return; + } + + Browser* browser = chrome::FindBrowserWithWebContents(contents_); + if (!browser) { + // The browser can be null in tests. + OnBubbleCompleted(true, web_app_info_); + return; + } + browser->window()->ShowBookmarkAppBubble( + web_app_info_, base::Bind(&BookmarkAppHelper::OnBubbleCompleted, + base::Unretained(this))); +} + +void BookmarkAppHelper::OnBubbleCompleted( + bool user_accepted, + const WebApplicationInfo& web_app_info) { + if (user_accepted) { + web_app_info_ = web_app_info; + crx_installer_->InstallWebApp(web_app_info_); + } else { + callback_.Run(nullptr, web_app_info_); + } +} + +void BookmarkAppHelper::FinishInstallation(const Extension* extension) { + // Set the default 'open as' preference for use next time the dialog is + // shown. + extensions::LaunchType launch_type = web_app_info_.open_as_window + ? extensions::LAUNCH_TYPE_WINDOW + : extensions::LAUNCH_TYPE_REGULAR; + profile_->GetPrefs()->SetInteger( + extensions::pref_names::kBookmarkAppCreationLaunchType, launch_type); + + // Set the launcher type for the app. + extensions::SetLaunchType(profile_, extension->id(), launch_type); + + if (!contents_) { + // The web contents can be null in tests. + callback_.Run(extension, web_app_info_); + return; + } + + Browser* browser = chrome::FindBrowserWithWebContents(contents_); + if (!browser) { + // The browser can be null in tests. + callback_.Run(extension, web_app_info_); + return; + } + + // Pin the app to the relevant launcher depending on the OS. + Profile* current_profile = profile_->GetOriginalProfile(); + chrome::HostDesktopType desktop = browser->host_desktop_type(); + if (desktop != chrome::HOST_DESKTOP_TYPE_ASH) { + web_app::ShortcutLocations creation_locations; +#if defined(OS_LINUX) + creation_locations.on_desktop = true; +#else + creation_locations.on_desktop = false; +#endif + creation_locations.applications_menu_location = + web_app::APP_MENU_LOCATION_HIDDEN; + creation_locations.in_quick_launch_bar = true; + web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER, + creation_locations, current_profile, extension); +#if defined(USE_ASH) + } else { + ChromeLauncherController::instance()->PinAppWithID(extension->id()); +#endif + } + + // Show the newly installed app in the app launcher, in finder (on Mac) or + // chrome://apps. + if (IsAppLauncherEnabled()) { + AppListService::Get(desktop) + ->ShowForAppInstall(current_profile, extension->id(), false); +#if defined(OS_MACOSX) + } else if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableHostedAppShimCreation)) { + web_app::RevealAppShimInFinderForApp(profile_, extension); +#endif + } else { + chrome::NavigateParams params(current_profile, + GURL(chrome::kChromeUIAppsURL), + ui::PAGE_TRANSITION_LINK); + params.disposition = SINGLETON_TAB; + chrome::Navigate(¶ms); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, + content::Source<content::WebContents>(params.target_contents), + content::Details<const std::string>(&extension->id())); + } + + callback_.Run(extension, web_app_info_); } void BookmarkAppHelper::Observe(int type, @@ -351,11 +477,11 @@ DCHECK(extension); DCHECK_EQ(AppLaunchInfo::GetLaunchWebURL(extension), web_app_info_.app_url); - callback_.Run(extension, web_app_info_); + FinishInstallation(extension); break; } case extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR: - callback_.Run(NULL, web_app_info_); + callback_.Run(nullptr, web_app_info_); break; default: NOTREACHED();
diff --git a/chrome/browser/extensions/bookmark_app_helper.h b/chrome/browser/extensions/bookmark_app_helper.h index 31442a6..3a47947 100644 --- a/chrome/browser/extensions/bookmark_app_helper.h +++ b/chrome/browser/extensions/bookmark_app_helper.h
@@ -19,6 +19,7 @@ class ExtensionService; class FaviconDownloader; +class Profile; class SkBitmap; namespace content { @@ -39,8 +40,10 @@ // This helper class will create a bookmark app out of |web_app_info| and // install it to |service|. Icons will be downloaded from the URLs in // |web_app_info.icons| using |contents| if |contents| is not NULL. - // All existing icons from WebApplicationInfo will also be used. - BookmarkAppHelper(ExtensionService* service, + // All existing icons from WebApplicationInfo will also be used. The user + // will then be prompted to edit the creation information via a bubble and + // will have a chance to cancel the operation. + BookmarkAppHelper(Profile* profile, WebApplicationInfo web_app_info, content::WebContents* contents); ~BookmarkAppHelper() override; @@ -80,11 +83,23 @@ void OnIconsDownloaded(bool success, const std::map<GURL, std::vector<SkBitmap> >& bitmaps); + // Called after the bubble has been shown, and the user has either accepted or + // the dialog was dismissed. + void OnBubbleCompleted(bool user_accepted, + const WebApplicationInfo& web_app_info); + + // Called when the installation of the app is complete to perform the final + // installation steps. + void FinishInstallation(const Extension* extension); + // Overridden from content::NotificationObserver: void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) override; + // The profile that the bookmark app is being added to. + Profile* profile_; + // The web contents that the bookmark app is being created for. content::WebContents* contents_;
diff --git a/chrome/browser/extensions/bookmark_app_helper_unittest.cc b/chrome/browser/extensions/bookmark_app_helper_unittest.cc index 36cab55..dc5c7e6 100644 --- a/chrome/browser/extensions/bookmark_app_helper_unittest.cc +++ b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
@@ -117,7 +117,7 @@ TestBookmarkAppHelper(ExtensionService* service, WebApplicationInfo web_app_info, content::WebContents* contents) - : BookmarkAppHelper(service, web_app_info, contents) {} + : BookmarkAppHelper(service->profile(), web_app_info, contents) {} ~TestBookmarkAppHelper() override {}
diff --git a/chrome/browser/extensions/chrome_app_api_browsertest.cc b/chrome/browser/extensions/chrome_app_api_browsertest.cc index d85b539..805019b 100644 --- a/chrome/browser/extensions/chrome_app_api_browsertest.cc +++ b/chrome/browser/extensions/chrome_app_api_browsertest.cc
@@ -101,20 +101,20 @@ #define MAYBE_IsInstalled IsInstalled #endif IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, MAYBE_IsInstalled) { - std::string app_host("app.com"); - std::string nonapp_host("nonapp.com"); + static const char kAppHost[] = "app.com"; + static const char kNonAppHost[] = "nonapp.com"; - host_resolver()->AddRule(app_host, "127.0.0.1"); - host_resolver()->AddRule(nonapp_host, "127.0.0.1"); + host_resolver()->AddRule(kAppHost, "127.0.0.1"); + host_resolver()->AddRule(kNonAppHost, "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); GURL test_file_url(test_server()->GetURL("extensions/test_file.html")); GURL::Replacements replace_host; - replace_host.SetHostStr(app_host); + replace_host.SetHostStr(kAppHost); GURL app_url(test_file_url.ReplaceComponents(replace_host)); - replace_host.SetHostStr(nonapp_host); + replace_host.SetHostStr(kNonAppHost); GURL non_app_url(test_file_url.ReplaceComponents(replace_host)); // Before the app is installed, app.com does not think that it is installed @@ -188,23 +188,23 @@ } IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, GetDetailsForFrame) { - std::string app_host("app.com"); - std::string nonapp_host("nonapp.com"); - std::string checkout_host("checkout.com"); + const char kAppHost[] = "app.com"; + const char kNonAppHost[] = "nonapp.com"; + const char kCheckoutHost[] = "checkout.com"; - host_resolver()->AddRule(app_host, "127.0.0.1"); - host_resolver()->AddRule(nonapp_host, "127.0.0.1"); - host_resolver()->AddRule(checkout_host, "127.0.0.1"); + host_resolver()->AddRule(kAppHost, "127.0.0.1"); + host_resolver()->AddRule(kNonAppHost, "127.0.0.1"); + host_resolver()->AddRule(kCheckoutHost, "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); GURL test_file_url(test_server()->GetURL( "files/extensions/get_app_details_for_frame.html")); GURL::Replacements replace_host; - replace_host.SetHostStr(checkout_host); + replace_host.SetHostStr(kCheckoutHost); GURL checkout_url(test_file_url.ReplaceComponents(replace_host)); - replace_host.SetHostStr(app_host); + replace_host.SetHostStr(kAppHost); GURL app_url(test_file_url.ReplaceComponents(replace_host)); // Load an app which includes app.com in its extent. @@ -247,21 +247,21 @@ IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningState) { - std::string app_host("app.com"); - std::string non_app_host("nonapp.com"); + static const char kAppHost[] = "app.com"; + static const char kNonAppHost[] = "nonapp.com"; - host_resolver()->AddRule(app_host, "127.0.0.1"); - host_resolver()->AddRule(non_app_host, "127.0.0.1"); + host_resolver()->AddRule(kAppHost, "127.0.0.1"); + host_resolver()->AddRule(kNonAppHost, "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); GURL test_file_url(test_server()->GetURL( "files/extensions/get_app_details_for_frame.html")); GURL::Replacements replace_host; - replace_host.SetHostStr(app_host); + replace_host.SetHostStr(kAppHost); GURL app_url(test_file_url.ReplaceComponents(replace_host)); - replace_host.SetHostStr(non_app_host); + replace_host.SetHostStr(kNonAppHost); GURL non_app_url(test_file_url.ReplaceComponents(replace_host)); // Before the app is installed, app.com does not think that it is installed @@ -314,21 +314,21 @@ } IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningStateFrame) { - std::string app_host("app.com"); - std::string non_app_host("nonapp.com"); + static const char kAppHost[] = "app.com"; + static const char kNonAppHost[] = "nonapp.com"; - host_resolver()->AddRule(app_host, "127.0.0.1"); - host_resolver()->AddRule(non_app_host, "127.0.0.1"); + host_resolver()->AddRule(kAppHost, "127.0.0.1"); + host_resolver()->AddRule(kNonAppHost, "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); GURL test_file_url(test_server()->GetURL( "files/extensions/get_app_details_for_frame_reversed.html")); GURL::Replacements replace_host; - replace_host.SetHostStr(app_host); + replace_host.SetHostStr(kAppHost); GURL app_url(test_file_url.ReplaceComponents(replace_host)); - replace_host.SetHostStr(non_app_host); + replace_host.SetHostStr(kNonAppHost); GURL non_app_url(test_file_url.ReplaceComponents(replace_host)); // Check the install and running state of a non-app iframe running
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index a8d8322..ed60dcb 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -338,8 +338,7 @@ // We disallow all injection on the webstore. GURL::Replacements replacements; - std::string host(kWebstoreDomain); - replacements.SetHostStr(host); + replacements.SetHostStr(kWebstoreDomain); url = embedded_test_server()->GetURL("/extensions/test_file_with_body.html") .ReplaceComponents(replacements); EXPECT_TRUE(CheckStyleInjection(browser(), url, false));
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 13d8da7..cf6fcc7 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -598,42 +598,4 @@ EXPECT_FALSE(InstallExtension(crx_path, 0)); } -IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, WithheldElevationCheck) { - // Enable consent flag and install extension. The <all_hosts> permission will - // be withheld. - scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( - new FeatureSwitch::ScopedOverride( - FeatureSwitch::scripts_require_action(), true)); - - const char kManifest[] = - "{" - " \"name\": \"Withheld test\"," - " \"version\": \"1.0\"," - " \"permissions\": [" - " \"http://*/*\"" - " ]," - " \"manifest_version\": 2" - "}"; - TestExtensionDir dir; - dir.WriteManifest(kManifest); - base::FilePath crx_path = dir.Pack(); - EXPECT_FALSE(crx_path.empty()); - const Extension* extension = InstallExtension(crx_path, 1); - EXPECT_TRUE(base::PathExists(extension->path())); - - std::string extension_id = extension->id(); - ExtensionRegistry* registry = ExtensionRegistry::Get( - browser()->profile()); - EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_id)); - - // Disable consent flag and reinstall extension. It should now be disabled - // because previously withheld permissions are now being requested. - enable_scripts_switch.reset(); - extension = InstallExtension(crx_path, -1); - EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); - EXPECT_TRUE(registry->disabled_extensions().GetByID(extension_id)); - EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())->GetDisableReasons( - extension_id) & Extension::DISABLE_PERMISSIONS_INCREASE); -} - } // namespace extensions
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc index 6258a86..a54ac2c 100644 --- a/chrome/browser/extensions/extension_context_menu_model.cc +++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -156,8 +156,10 @@ extension_action_->HasPopup(SessionTabHelper::IdForTab(web_contents)); } else if (command_id == UNINSTALL) { // Some extension types can not be uninstalled. - return extensions::ExtensionSystem::Get( - profile_)->management_policy()->UserMayModifySettings(extension, NULL); + extensions::ManagementPolicy* policy = + extensions::ExtensionSystem::Get(profile_)->management_policy(); + return policy->UserMayModifySettings(extension, nullptr) && + !policy->MustRemainInstalled(extension, nullptr); } return true; }
diff --git a/chrome/browser/extensions/extension_dom_clipboard_apitest.cc b/chrome/browser/extensions/extension_dom_clipboard_apitest.cc index 092dd02..ff8a1f4b 100644 --- a/chrome/browser/extensions/extension_dom_clipboard_apitest.cc +++ b/chrome/browser/extensions/extension_dom_clipboard_apitest.cc
@@ -45,8 +45,7 @@ GURL base_url = embedded_test_server()->GetURL( "/extensions/api_test/clipboard/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); std::string launch_page_path =
diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc index 4cf7f77..c76a0c9b 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc +++ b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
@@ -17,7 +17,6 @@ #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" -#include "base/prefs/pref_service.h" #include "base/run_loop.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" @@ -29,7 +28,6 @@ #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "components/gcm_driver/fake_gcm_app_handler.h" #include "components/gcm_driver/fake_gcm_client.h" @@ -233,9 +231,6 @@ extension_service_->set_show_extensions_prompts(false); extension_service_->set_install_updates_when_idle_for_test(false); - // Enable GCM such that tests could be run on all channels. - profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); - // Create GCMProfileService that talks with fake GCMClient. gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( profile(), &ExtensionGCMAppHandlerTest::BuildGCMProfileService);
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc index 00b032a..909c68f3 100644 --- a/chrome/browser/extensions/extension_nacl_browsertest.cc +++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -206,8 +206,7 @@ GURL url = test_server()->GetURL("files/extensions/native_client/test.html"); GURL::Replacements replace_host; - std::string host_str("localhost"); - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); replace_host.ClearPort(); url = url.ReplaceComponents(replace_host);
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc index 7553bda5..2f2fbf8 100644 --- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc +++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -48,13 +48,11 @@ "files/extensions/api_test/extension_resource_request_policy/" "index.html")); - std::string host_a("a.com"); GURL::Replacements make_host_a_com; - make_host_a_com.SetHostStr(host_a); + make_host_a_com.SetHostStr("a.com"); - std::string host_b("b.com"); GURL::Replacements make_host_b_com; - make_host_b_com.SetHostStr(host_b); + make_host_b_com.SetHostStr("b.com"); // A web host that has permission. ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 94e4b52..e13371f 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -1031,8 +1031,11 @@ Profile::FromBrowserContext(host->GetBrowserContext()); if (host_profile->GetOriginalProfile() == profile_->GetOriginalProfile()) { + // We don't need to include tab permisisons here, since the extension + // was just loaded. std::vector<ExtensionMsg_Loaded_Params> loaded_extensions( - 1, ExtensionMsg_Loaded_Params(extension)); + 1, ExtensionMsg_Loaded_Params(extension, + false /* no tab permissions */)); host->Send( new ExtensionMsg_Loaded(loaded_extensions)); }
diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc index 656e185..ac493ff 100644 --- a/chrome/browser/extensions/extension_ui_unittest.cc +++ b/chrome/browser/extensions/extension_ui_unittest.cc
@@ -329,23 +329,22 @@ scoped_ptr<base::DictionaryValue> value(handler()->CreateExtensionDetailValue( all_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); bool result = false; - const std::string kWantsAllUrls = "wantsAllUrls"; + const std::string kShowAllUrls = "showAllUrls"; const std::string kAllowAllUrls = "allowAllUrls"; // The extension should want all urls, but not currently have it. - EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); EXPECT_TRUE(result); EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); EXPECT_FALSE(result); // Give the extension all urls. - util::SetAllowedScriptingOnAllUrls( - all_urls_extension->id(), profile(), true); + util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); // Now the extension should both want and have all urls. value.reset(handler()->CreateExtensionDetailValue( all_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); - EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); EXPECT_TRUE(result); EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); EXPECT_TRUE(result); @@ -353,20 +352,34 @@ // The other extension should neither want nor have all urls. value.reset(handler()->CreateExtensionDetailValue( no_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); - EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); EXPECT_FALSE(result); EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); EXPECT_FALSE(result); + // Revoke the first extension's permissions. + util::SetAllowedScriptingOnAllUrls( + all_urls_extension->id(), profile(), false); + // Turn off the switch and load another extension (so permissions are // re-initialized). enable_scripts_switch.reset(); - // Even though the extension has the all urls preference, the checkbox - // shouldn't show up with the switch off. + // Since the extension doesn't have access to all urls (but normally would), + // the extension should have the "want" flag even with the switch off. value.reset(handler()->CreateExtensionDetailValue( all_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); - EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); + EXPECT_TRUE(result); + EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); + EXPECT_FALSE(result); + + // If we grant the extension all urls, then it should no longer "want" it, + // since it is back in its normal state (with the switch off). + util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); + value.reset(handler()->CreateExtensionDetailValue( + all_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); EXPECT_FALSE(result); EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); EXPECT_TRUE(result); @@ -379,10 +392,10 @@ // show up without the switch. value.reset(handler()->CreateExtensionDetailValue( all_urls_extension.get(), std::vector<ExtensionPage>(), NULL)); - EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result)); + EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result)); EXPECT_FALSE(result); EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result)); - EXPECT_FALSE(result); + EXPECT_TRUE(result); } } // namespace extensions
diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index b07ab1c..f513a99 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc
@@ -70,6 +70,35 @@ return id; } +// Sets the preference for scripting on all urls to |allowed|, optionally +// updating the extension's active permissions (based on |update_permissions|). +void SetAllowedScriptingOnAllUrlsHelper( + content::BrowserContext* context, + const std::string& extension_id, + bool allowed, + bool update_permissions) { + // TODO(devlin): Right now, we always need to have a value for this pref. + // Once the scripts-require-action feature launches, we can change the set + // to be null if false. + ExtensionPrefs::Get(context)->UpdateExtensionPref( + extension_id, + kExtensionAllowedOnAllUrlsPrefName, + new base::FundamentalValue(allowed)); + + if (update_permissions) { + const Extension* extension = + ExtensionRegistry::Get(context)->enabled_extensions().GetByID( + extension_id); + if (extension) { + PermissionsUpdater updater(context); + if (allowed) + updater.GrantWithheldImpliedAllHosts(extension); + else + updater.WithholdImpliedAllHosts(extension); + } + } +} + } // namespace bool IsIncognitoEnabled(const std::string& extension_id, @@ -176,46 +205,42 @@ bool AllowedScriptingOnAllUrls(const std::string& extension_id, content::BrowserContext* context) { bool allowed = false; - return ExtensionPrefs::Get(context)->ReadPrefAsBoolean( - extension_id, - kExtensionAllowedOnAllUrlsPrefName, - &allowed) && - allowed; + ExtensionPrefs* prefs = ExtensionPrefs::Get(context); + if (!prefs->ReadPrefAsBoolean(extension_id, + kExtensionAllowedOnAllUrlsPrefName, + &allowed)) { + // If there is no value present, we make one, defaulting it to the value of + // the 'scripts require action' flag. If the flag is on, then the extension + // does not have permission to script on all urls by default. + allowed = DefaultAllowedScriptingOnAllUrls(); + SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, false); + } + return allowed; } void SetAllowedScriptingOnAllUrls(const std::string& extension_id, content::BrowserContext* context, bool allowed) { - if (allowed == AllowedScriptingOnAllUrls(extension_id, context)) - return; // Nothing to do here. - - ExtensionPrefs::Get(context)->UpdateExtensionPref( - extension_id, - kExtensionAllowedOnAllUrlsPrefName, - allowed ? new base::FundamentalValue(true) : NULL); - - const Extension* extension = - ExtensionRegistry::Get(context)->enabled_extensions().GetByID( - extension_id); - if (extension) { - PermissionsUpdater updater(context); - if (allowed) - updater.GrantWithheldImpliedAllHosts(extension); - else - updater.WithholdImpliedAllHosts(extension); - } + if (allowed != AllowedScriptingOnAllUrls(extension_id, context)) + SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, true); } -bool ScriptsMayRequireActionForExtension(const Extension* extension) { - // An extension requires user action to execute scripts iff the switch to do - // so is enabled, the extension shows up in chrome:extensions (so the user can - // grant withheld permissions), the extension is not part of chrome or - // corporate policy, and also not on the scripting whitelist. - return FeatureSwitch::scripts_require_action()->IsEnabled() && - extension->ShouldDisplayInExtensionSettings() && +bool DefaultAllowedScriptingOnAllUrls() { + return !FeatureSwitch::scripts_require_action()->IsEnabled(); +} + +bool ScriptsMayRequireActionForExtension( + const Extension* extension, + const PermissionSet* permissions) { + // An extension may require user action to execute scripts iff the extension + // shows up in chrome:extensions (so the user can grant withheld permissions), + // is not part of chrome or corporate policy, not on the scripting whitelist, + // and requires enough permissions that we should withhold them. + return extension->ShouldDisplayInExtensionSettings() && !Manifest::IsPolicyLocation(extension->location()) && !Manifest::IsComponentLocation(extension->location()) && - !PermissionsData::CanExecuteScriptEverywhere(extension); + !PermissionsData::CanExecuteScriptEverywhere(extension) && + permissions->ShouldWarnAllHosts(); } bool IsAppLaunchable(const std::string& extension_id, @@ -350,8 +375,8 @@ } bool IsNewBookmarkAppsEnabled() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableNewBookmarkApps); + return !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableNewBookmarkApps); } } // namespace util
diff --git a/chrome/browser/extensions/extension_util.h b/chrome/browser/extensions/extension_util.h index 7240500..4535e99 100644 --- a/chrome/browser/extensions/extension_util.h +++ b/chrome/browser/extensions/extension_util.h
@@ -26,6 +26,7 @@ class Extension; struct ExtensionInfo; +class PermissionSet; namespace util { @@ -68,6 +69,9 @@ bool AllowedScriptingOnAllUrls(const std::string& extension_id, content::BrowserContext* context); +// Returns the default value for being allowed to script on all urls. +bool DefaultAllowedScriptingOnAllUrls(); + // Sets whether the extension with |extension_id| is allowed to execute scripts // on all urls (exempting chrome:// urls, etc) without explicit user consent. // This should only be used with FeatureSwitch::scripts_require_action() @@ -77,8 +81,12 @@ bool allowed); // Returns true if the --scripts-require-action flag would possibly affect -// the given |extension|. -bool ScriptsMayRequireActionForExtension(const Extension* extension); +// the given |extension| and |permissions|. We pass in the |permissions| +// explicitly, as we may need to check with permissions other than the ones +// that are currently on the extension's PermissionsData. +bool ScriptsMayRequireActionForExtension( + const Extension* extension, + const PermissionSet* permissions); // Returns true if |extension_id| can be launched (possibly only after being // enabled).
diff --git a/chrome/browser/extensions/isolated_app_browsertest.cc b/chrome/browser/extensions/isolated_app_browsertest.cc index 38ee2bd..c55f602 100644 --- a/chrome/browser/extensions/isolated_app_browsertest.cc +++ b/chrome/browser/extensions/isolated_app_browsertest.cc
@@ -140,8 +140,7 @@ GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html")); @@ -212,8 +211,7 @@ // so the URLs we navigate to must have host "localhost". GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html")); @@ -305,8 +303,7 @@ // so the URLs we navigate to must have host "localhost". GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html")); @@ -388,8 +385,7 @@ GURL root_url = embedded_test_server()->GetURL("/"); GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); root_url = root_url.ReplaceComponents(replace_host); base_url = base_url.ReplaceComponents(replace_host); @@ -460,8 +456,7 @@ // so the URLs we navigate to must have host "localhost". GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); // Create three tabs in the isolated app in different ways. @@ -519,8 +514,7 @@ // so the URLs we navigate to must have host "localhost". GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); // Enter some state into sessionStorage three times on the same origin, but
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index 75212d9..5461804 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -34,6 +34,7 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using extensions::Extension; using extensions::ResultCatcher;
diff --git a/chrome/browser/extensions/permission_message_combinations_unittest.cc b/chrome/browser/extensions/permission_message_combinations_unittest.cc index 8562553..a10a8954 100644 --- a/chrome/browser/extensions/permission_message_combinations_unittest.cc +++ b/chrome/browser/extensions/permission_message_combinations_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/values_test_util.h" #include "chrome/browser/extensions/test_extension_environment.h" #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h" +#include "extensions/common/extension.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/switches.h" #include "testing/gmock/include/gmock/gmock-matchers.h"
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc index 6a68371..65608c1 100644 --- a/chrome/browser/extensions/permissions_updater.cc +++ b/chrome/browser/extensions/permissions_updater.cc
@@ -182,14 +182,14 @@ bounded_active = GetBoundedActivePermissions(extension, active_permissions); } - // Withhold permissions if the switch applies to this extension. - // Non-transient extensions also must not have the preference to allow - // scripting on all urls. - bool should_withhold_permissions = - util::ScriptsMayRequireActionForExtension(extension); - if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) { - should_withhold_permissions &= - !util::AllowedScriptingOnAllUrls(extension->id(), browser_context_); + // Determine whether or not to withhold host permissions. + bool should_withhold_permissions = false; + if (util::ScriptsMayRequireActionForExtension(extension, + bounded_active.get())) { + should_withhold_permissions = + init_flag_ & INIT_FLAG_TRANSIENT ? + !util::DefaultAllowedScriptingOnAllUrls() : + !util::AllowedScriptingOnAllUrls(extension->id(), browser_context_); } URLPatternSet granted_explicit_hosts;
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc index 7b199f7..6179b50 100644 --- a/chrome/browser/extensions/permissions_updater_unittest.cc +++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -11,10 +11,12 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/permissions_updater.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_test_util.h" #include "chrome/test/base/testing_profile.h" +#include "components/crx_file/id_util.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" @@ -36,7 +38,8 @@ scoped_refptr<const Extension> CreateExtensionWithPermissions( const std::set<URLPattern>& scriptable_hosts, const std::set<URLPattern>& explicit_hosts, - Manifest::Location location) { + Manifest::Location location, + const std::string& name) { ListBuilder scriptable_host_list; for (std::set<URLPattern>::const_iterator pattern = scriptable_hosts.begin(); pattern != scriptable_hosts.end(); @@ -59,12 +62,13 @@ .SetLocation(location) .SetManifest( DictionaryBuilder() - .Set("name", "extension") + .Set("name", name) .Set("description", "foo") .Set("manifest_version", 2) .Set("version", "0.1.2.3") .Set("content_scripts", ListBuilder().Append(script.Pass())) .Set("permissions", explicit_host_list.Pass())) + .SetID(crx_file::id_util::GenerateId(name)) .Build(); } @@ -300,7 +304,7 @@ all_host_patterns, safe_patterns); scoped_refptr<const Extension> extension = CreateExtensionWithPermissions( - all_patterns, all_patterns, Manifest::INTERNAL); + all_patterns, all_patterns, Manifest::INTERNAL, "a"); const PermissionsData* permissions_data = extension->permissions_data(); PermissionsUpdater updater(profile_.get()); updater.InitializePermissions(extension.get()); @@ -359,7 +363,7 @@ // Creating a component extension should result in no withheld permissions. extension = CreateExtensionWithPermissions( - all_patterns, all_patterns, Manifest::COMPONENT); + all_patterns, all_patterns, Manifest::COMPONENT, "b"); permissions_data = extension->permissions_data(); updater.InitializePermissions(extension.get()); EXPECT_TRUE(SetsAreEqual( @@ -380,7 +384,7 @@ // Without the switch, we shouldn't withhold anything. switch_override.reset(); extension = CreateExtensionWithPermissions( - all_patterns, all_patterns, Manifest::INTERNAL); + all_patterns, all_patterns, Manifest::INTERNAL, "c"); permissions_data = extension->permissions_data(); updater.InitializePermissions(extension.get()); EXPECT_TRUE(SetsAreEqual( @@ -399,4 +403,73 @@ .empty()); } +// Tests that withholding all hosts behaves properly with extensions installed +// when the switch is turned on and off. +TEST_F(PermissionsUpdaterTest, WithholdAllHostsWithTransientSwitch) { + InitializeEmptyExtensionService(); + + URLPattern all_hosts(URLPattern::SCHEME_ALL, "<all_urls>"); + std::set<URLPattern> all_host_patterns; + all_host_patterns.insert(all_hosts); + + scoped_refptr<const Extension> extension_a = CreateExtensionWithPermissions( + all_host_patterns, all_host_patterns, Manifest::INTERNAL, "a"); + PermissionsUpdater updater(profile()); + updater.InitializePermissions(extension_a.get()); + const PermissionsData* permissions_data = extension_a->permissions_data(); + + // Since the extension was created without the switch on, it should default + // to having all urls access. + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions()->scriptable_hosts().patterns(), + all_host_patterns)); + EXPECT_TRUE( + permissions_data->withheld_permissions()->scriptable_hosts().is_empty()); + EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile())); + + // Enable the switch, and re-init permission for the extension. + scoped_ptr<FeatureSwitch::ScopedOverride> switch_override( + new FeatureSwitch::ScopedOverride(FeatureSwitch::scripts_require_action(), + FeatureSwitch::OVERRIDE_ENABLED)); + updater.InitializePermissions(extension_a.get()); + + // Since the extension was installed when the switch was off, it should still + // have the all urls pref. + permissions_data = extension_a->permissions_data(); + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions()->scriptable_hosts().patterns(), + all_host_patterns)); + EXPECT_TRUE( + permissions_data->withheld_permissions()->scriptable_hosts().is_empty()); + EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile())); + + // Load a new extension, which also has all urls. Since the switch is now on, + // the permissions should be withheld. + scoped_refptr<const Extension> extension_b = CreateExtensionWithPermissions( + all_host_patterns, all_host_patterns, Manifest::INTERNAL, "b"); + updater.InitializePermissions(extension_b.get()); + permissions_data = extension_b->permissions_data(); + + EXPECT_TRUE( + permissions_data->active_permissions()->scriptable_hosts().is_empty()); + EXPECT_TRUE(SetsAreEqual( + permissions_data->withheld_permissions()->scriptable_hosts().patterns(), + all_host_patterns)); + EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile())); + + // Disable the switch, and reload the extension. + switch_override.reset(); + updater.InitializePermissions(extension_b.get()); + + // Since the extension was installed with the switch on, it should still be + // restricted with the switch off. + permissions_data = extension_b->permissions_data(); + EXPECT_TRUE( + permissions_data->active_permissions()->scriptable_hosts().is_empty()); + EXPECT_TRUE(SetsAreEqual( + permissions_data->withheld_permissions()->scriptable_hosts().patterns(), + all_host_patterns)); + EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile())); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/process_management_browsertest.cc b/chrome/browser/extensions/process_management_browsertest.cc index fc1532e..3515540 100644 --- a/chrome/browser/extensions/process_management_browsertest.cc +++ b/chrome/browser/extensions/process_management_browsertest.cc
@@ -67,8 +67,7 @@ GURL base_url = embedded_test_server()->GetURL( "/extensions/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); // Load an extension before adding tabs. @@ -200,8 +199,7 @@ GURL base_url = embedded_test_server()->GetURL( "/extensions/"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); base_url = base_url.ReplaceComponents(replace_host); ASSERT_TRUE(LoadExtension(
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index 9f2495b..5bbc2aa 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -124,7 +124,7 @@ // Set up a test server running at http://[extension-id] ASSERT_TRUE(extension.get()); - const std::string aliased_host = extension->id(); + const std::string& aliased_host = extension->id(); host_resolver()->AddRule(aliased_host, "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); GURL url =
diff --git a/chrome/browser/extensions/signin/gaia_auth_extension_loader.cc b/chrome/browser/extensions/signin/gaia_auth_extension_loader.cc index c636b89..7ae76c0 100644 --- a/chrome/browser/extensions/signin/gaia_auth_extension_loader.cc +++ b/chrome/browser/extensions/signin/gaia_auth_extension_loader.cc
@@ -86,7 +86,7 @@ namespace extensions { GaiaAuthExtensionLoader::GaiaAuthExtensionLoader(BrowserContext* context) - : browser_context_(context), load_count_(0) {} + : browser_context_(context), load_count_(0), last_data_id_(0) {} GaiaAuthExtensionLoader::~GaiaAuthExtensionLoader() { DCHECK_EQ(0, load_count_); @@ -100,8 +100,25 @@ void GaiaAuthExtensionLoader::UnloadIfNeeded() { --load_count_; - if (load_count_ == 0) + if (load_count_ == 0) { UnloadGaiaAuthExtension(browser_context_); + data_.clear(); + } +} + +int GaiaAuthExtensionLoader::AddData(const std::string& data) { + ++last_data_id_; + data_[last_data_id_] = data; + return last_data_id_; +} + +bool GaiaAuthExtensionLoader::GetData(int data_id, std::string* data) { + auto it = data_.find(data_id); + if (it == data_.end()) + return false; + + *data = it->second; + return true; } void GaiaAuthExtensionLoader::Shutdown() { @@ -109,6 +126,7 @@ UnloadGaiaAuthExtension(browser_context_); load_count_ = 0; } + data_.clear(); } // static
diff --git a/chrome/browser/extensions/signin/gaia_auth_extension_loader.h b/chrome/browser/extensions/signin/gaia_auth_extension_loader.h index 20fd4648..146596e1 100644 --- a/chrome/browser/extensions/signin/gaia_auth_extension_loader.h +++ b/chrome/browser/extensions/signin/gaia_auth_extension_loader.h
@@ -5,7 +5,10 @@ #ifndef CHROME_BROWSER_EXTENSIONS_SIGNIN_GAIA_AUTH_EXTENSION_LOADER_H_ #define CHROME_BROWSER_EXTENSIONS_SIGNIN_GAIA_AUTH_EXTENSION_LOADER_H_ -#include "base/memory/scoped_ptr.h" +#include <map> +#include <string> + +#include "base/macros.h" #include "extensions/browser/browser_context_keyed_api_factory.h" namespace content { @@ -29,6 +32,15 @@ // Unload the gaia auth extension if no pending reference. void UnloadIfNeeded(); + // Add a string data for gaia auth extension. Returns an ID that + // could be used to get the data. All strings are cleared when gaia auth + // is unloaded. + int AddData(const std::string& data); + + // Get data for the given ID. Returns true if the data is found and + // its value is copied to |data|. Otherwise, returns false. + bool GetData(int data_id, std::string* data); + static GaiaAuthExtensionLoader* Get(content::BrowserContext* context); // BrowserContextKeyedAPI implementation. @@ -50,6 +62,9 @@ content::BrowserContext* browser_context_; int load_count_; + int last_data_id_; + std::map<int, std::string> data_; + DISALLOW_COPY_AND_ASSIGN(GaiaAuthExtensionLoader); };
diff --git a/chrome/browser/extensions/signin/gaia_auth_extension_loader_browsertest.cc b/chrome/browser/extensions/signin/gaia_auth_extension_loader_browsertest.cc new file mode 100644 index 0000000..d5ecff6 --- /dev/null +++ b/chrome/browser/extensions/signin/gaia_auth_extension_loader_browsertest.cc
@@ -0,0 +1,57 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" + +namespace extensions { + +namespace { + +const char kTestData1[] = "A test string"; +const char kTestData2[] = "Another test string"; + +} // namespace + +typedef InProcessBrowserTest GaiaAuthExtensionLoaderTest; + +IN_PROC_BROWSER_TEST_F(GaiaAuthExtensionLoaderTest, AddAndGet) { + + GaiaAuthExtensionLoader* loader = GaiaAuthExtensionLoader::Get( + browser()->profile()); + loader->LoadIfNeeded(); + + int id1 = loader->AddData(kTestData1); + int id2 = loader->AddData(kTestData2); + EXPECT_NE(id1, id2); + + std::string fetched; + EXPECT_TRUE(loader->GetData(id1, &fetched)); + EXPECT_EQ(kTestData1, fetched); + + EXPECT_TRUE(loader->GetData(id2, &fetched)); + EXPECT_EQ(kTestData2, fetched); + + const int kUnknownId = 1234; + EXPECT_FALSE(loader->GetData(kUnknownId, &fetched)); + + loader->UnloadIfNeeded(); +} + +IN_PROC_BROWSER_TEST_F(GaiaAuthExtensionLoaderTest, ClearDataOnUnload) { + GaiaAuthExtensionLoader* loader = GaiaAuthExtensionLoader::Get( + browser()->profile()); + loader->LoadIfNeeded(); + + int id = loader->AddData(kTestData1); + std::string fetched; + EXPECT_TRUE(loader->GetData(id, &fetched)); + + loader->UnloadIfNeeded(); + EXPECT_FALSE(loader->GetData(id, &fetched)); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 9f05f93..d5c48c9 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -26,7 +26,6 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/chrome_extension_messages.h" @@ -60,10 +59,6 @@ #include "extensions/common/feature_switch.h" #include "extensions/common/manifest_handlers/icons_handler.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" -#endif - #if defined(OS_WIN) #include "chrome/browser/web_applications/web_app_win.h" #endif @@ -198,19 +193,6 @@ const Extension* extension, const WebApplicationInfo& web_app_info) { pending_web_app_action_ = NONE; - - // There was an error with downloading the icons or installing the app. - if (!extension) - return; - -#if defined(OS_CHROMEOS) - ChromeLauncherController::instance()->PinAppWithID(extension->id()); -#endif - - Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); - if (browser) { - browser->window()->ShowBookmarkAppBubble(web_app_info, extension->id()); - } } void TabHelper::RenderViewCreated(RenderViewHost* render_view_host) { @@ -319,9 +301,8 @@ if (web_app_info_.title.empty()) web_app_info_.title = base::UTF8ToUTF16(web_app_info_.app_url.spec()); - bookmark_app_helper_.reset(new BookmarkAppHelper( - ExtensionSystem::Get(profile_)->extension_service(), - web_app_info_, web_contents())); + bookmark_app_helper_.reset( + new BookmarkAppHelper(profile_, web_app_info_, web_contents())); bookmark_app_helper_->Create(base::Bind( &TabHelper::FinishCreateBookmarkApp, weak_ptr_factory_.GetWeakPtr())); break;
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc index fd61a90..0c9aacd 100644 --- a/chrome/browser/extensions/window_open_apitest.cc +++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -204,8 +204,7 @@ // to below must be within that domain, so that they fall within the app's // web extent. GURL::Replacements replace_host; - std::string a_dot_com = "a.com"; - replace_host.SetHostStr(a_dot_com); + replace_host.SetHostStr("a.com"); const std::string popup_app_contents_path( "files/extensions/api_test/window_open/popup_blocking/hosted_app/");
diff --git a/chrome/browser/history/DEPS b/chrome/browser/history/DEPS index 672b4f55..f322229 100644 --- a/chrome/browser/history/DEPS +++ b/chrome/browser/history/DEPS
@@ -6,54 +6,36 @@ # Please send reviews to sdefresne@chromium.org when adding dependencies to # this list. "-chrome/browser", - "-components/search_engines", - "+chrome/browser/chrome_notification_types.h", - "+chrome/browser/common", - "+chrome/browser/favicon", + "-components", + "+chrome/browser/history", - "+chrome/browser/network_time", - "+chrome/tools/profiles", # For history unit tests. - "+components/visitedlink/browser", + "+components/history", + "+components/favicon_base", + "+components/keyed_service/core", + "+components/signin/core/browser", # TODO(sdefresne): Bring this list to zero. # # Do not add to the list of temporarily-allowed dependencies below, # and please do not introduce more #includes of these files. "!chrome/browser/autocomplete/history_url_provider.h", - "!chrome/browser/bookmarks/bookmark_model_factory.h", - "!chrome/browser/bookmarks/chrome_bookmark_client.h", - "!chrome/browser/bookmarks/chrome_bookmark_client_factory.h", - "!chrome/browser/browser_process.h", - "!chrome/browser/chromeos/login/existing_user_controller.h", - "!chrome/browser/content_settings/cookie_settings.h", - "!chrome/browser/diagnostics/sqlite_diagnostics.h", - "!chrome/browser/omnibox/omnibox_field_trial.h", - "!chrome/browser/prefs/scoped_user_pref_update.h", + "!chrome/browser/chrome_notification_types.h", "!chrome/browser/prerender/prerender_contents.h", "!chrome/browser/prerender/prerender_manager.h", "!chrome/browser/prerender/prerender_manager_factory.h", "!chrome/browser/profiles/incognito_helpers.h", "!chrome/browser/profiles/profile.h", "!chrome/browser/profiles/profile_manager.h", - "!chrome/browser/signin/oauth2_token_service.h", - "!chrome/browser/signin/profile_oauth2_token_service.h", "!chrome/browser/signin/profile_oauth2_token_service_factory.h", - "!chrome/browser/signin/signin_manager.h", "!chrome/browser/signin/signin_manager_factory.h", - "!chrome/browser/signin/token_service_factory.h", - "!chrome/browser/sync/profile_sync_service.h", - "!chrome/browser/sync/profile_sync_service_factory.h", - "!chrome/browser/sync/profile_sync_service_mock.h", "!chrome/browser/ui/browser.h", "!chrome/browser/ui/browser_finder.h", - "!chrome/browser/ui/profile_error_dialog.h", - "!chrome/browser/ui/webui/ntp/most_visited_handler.h", - "!chrome/browser/ui/webui/ntp/new_tab_ui.h", - "!components/bookmarks/browser/bookmark_model.h", "!components/bookmarks/browser/bookmark_utils.h", - "!components/omnibox/autocomplete_match.h", - "!components/omnibox/autocomplete_result.h", + "!components/dom_distiller/core/url_constants.h", + "!components/omnibox/omnibox_field_trial.h", "!components/omnibox/url_prefix.h", + "!components/visitedlink/browser/visitedlink_delegate.h", + "!components/visitedlink/browser/visitedlink_master.h", ] specific_include_rules = { @@ -61,12 +43,30 @@ '.*_(api|browser|)test\.cc': [ "+chrome/browser", ], + # chrome_.* and .*_factory won't be componentized as they belong to the + # embedder, so they can depend on other feature in chrome/. Same thing + # for android specific code. + '(chrome_.*|.*_factory)\.(cc|h)': [ + "+chrome/browser/bookmarks/bookmark_model_factory.h", + "+chrome/browser/bookmarks/chrome_bookmark_client.h", + "+chrome/browser/bookmarks/chrome_bookmark_client_factory.h", + "+chrome/browser/content_settings/cookie_settings.h", + "+chrome/browser/sync/profile_sync_service.h", + "+chrome/browser/sync/profile_sync_service_factory.h", + "+chrome/browser/ui/profile_error_dialog.h", + "+components/bookmarks/browser", + "+components/keyed_service/content", + ], # TODO(sdefresne): Bring this list to zero. # # Do not add to the list of temporarily-allowed dependencies below, # and please do not introduce more #includes of these files. '.*_[a-z]*test\.cc': [ + "!chrome/browser/autocomplete/scored_history_match_builder.h", + "!chrome/browser/bookmarks/bookmark_model_factory.h", + "!chrome/browser/sync/profile_sync_service.h", + "!chrome/browser/sync/profile_sync_service_factory.h", + "!chrome/browser/sync/profile_sync_service_mock.h", "!components/bookmarks/test/bookmark_test_helpers.h", - "!components/bookmarks/test/test_bookmark_client.h", ] }
diff --git a/chrome/browser/history/android/DEPS b/chrome/browser/history/android/DEPS new file mode 100644 index 0000000..d4ff1bb --- /dev/null +++ b/chrome/browser/history/android/DEPS
@@ -0,0 +1,7 @@ +include_rules = [ + # Android specific code is not considered blocking for the componentization of + # chrome/browser/history, so it is allowed to use chrome/browser and + # components/. + "+chrome/browser", + "+components/bookmarks/browser", +]
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc index 122766b..2464245 100644 --- a/chrome/browser/history/android/android_provider_backend_unittest.cc +++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -38,6 +38,7 @@ using base::TimeDelta; using base::UTF8ToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; namespace history {
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler.cc b/chrome/browser/history/android/bookmark_model_sql_handler.cc index cd57bcba..3c9e5e2 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler.cc +++ b/chrome/browser/history/android/bookmark_model_sql_handler.cc
@@ -14,6 +14,7 @@ using base::Time; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; namespace history {
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc index 508c7e2..529f982 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc +++ b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
@@ -23,6 +23,7 @@ #include "testing/gtest/include/gtest/gtest.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; namespace history {
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc index cbf82bf..e78998d 100644 --- a/chrome/browser/history/history_backend_unittest.cc +++ b/chrome/browser/history/history_backend_unittest.cc
@@ -17,6 +17,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" +#include "base/prefs/pref_service.h" #include "base/run_loop.h" #include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" @@ -27,6 +28,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/importer/imported_favicon_usage.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "components/history/core/browser/history_constants.h" #include "components/history/core/browser/history_database_params.h" @@ -3042,7 +3044,8 @@ scoped_ptr<HistoryService> service( new HistoryService(&history_client, profile.get())); EXPECT_TRUE( - service->Init(TestHistoryDatabaseParamsForPath(profile->GetPath()))); + service->Init(profile->GetPrefs()->GetString(prefs::kAcceptLanguages), + TestHistoryDatabaseParamsForPath(profile->GetPath()))); service->AddPage( url, base::Time::Now(), NULL, 1, GURL(), RedirectList(),
diff --git a/chrome/browser/history/history_querying_unittest.cc b/chrome/browser/history/history_querying_unittest.cc index 3cdf1e9..b9d55b9 100644 --- a/chrome/browser/history/history_querying_unittest.cc +++ b/chrome/browser/history/history_querying_unittest.cc
@@ -167,7 +167,8 @@ ASSERT_TRUE(base::CreateDirectory(history_dir_)); history_.reset(new HistoryService); - if (!history_->Init(TestHistoryDatabaseParamsForPath(history_dir_))) { + if (!history_->Init(std::string(), + TestHistoryDatabaseParamsForPath(history_dir_))) { history_.reset(); // Tests should notice this NULL ptr & fail. return; }
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc index 6adc6755b..306408cc 100644 --- a/chrome/browser/history/history_service.cc +++ b/chrome/browser/history/history_service.cc
@@ -25,21 +25,15 @@ #include "base/location.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" -#include "base/prefs/pref_service.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" #include "base/time/time.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_backend.h" #include "chrome/browser/history/in_memory_history_backend.h" #include "chrome/browser/history/in_memory_url_index.h" #include "chrome/browser/history/web_history_service.h" -#include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/importer/imported_favicon_usage.h" -#include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/dom_distiller/core/url_constants.h" #include "components/history/core/browser/download_row.h" @@ -222,22 +216,20 @@ HistoryService::HistoryService() : thread_(new base::Thread(kHistoryThreadName)), history_client_(NULL), - profile_(NULL), backend_loaded_(false), no_db_(false), weak_ptr_factory_(this) { } -HistoryService::HistoryService(history::HistoryClient* client, Profile* profile) +HistoryService::HistoryService( + history::HistoryClient* history_client, Profile* profile) : thread_(new base::Thread(kHistoryThreadName)), - history_client_(client), - profile_(profile), + history_client_(history_client), visitedlink_master_(new visitedlink::VisitedLinkMaster( profile, this, true)), backend_loaded_(false), no_db_(false), weak_ptr_factory_(this) { - DCHECK(profile_); } HistoryService::~HistoryService() { @@ -967,6 +959,7 @@ bool HistoryService::Init( bool no_db, + const std::string& languages, const history::HistoryDatabaseParams& history_database_params) { DCHECK(thread_) << "History service being called after cleanup"; DCHECK(thread_checker_.CalledOnValidThread()); @@ -980,9 +973,9 @@ history_dir_ = history_database_params.history_dir; no_db_ = no_db; - if (profile_) { - std::string languages = - profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); + if (!languages.empty()) { + // Do not create |in_memory_url_index_| when languages is empty (which + // should only happens during testing). in_memory_url_index_.reset(new history::InMemoryURLIndex( this, history_dir_, languages, history_client_)); in_memory_url_index_->Init(); @@ -995,13 +988,6 @@ history_client_)); history_backend_.swap(backend); - // There may not be a profile when unit testing. - std::string languages; - if (profile_) { - PrefService* prefs = profile_->GetPrefs(); - languages = prefs->GetString(prefs::kAcceptLanguages); - } - ScheduleTask(PRIORITY_UI, base::Bind(&HistoryBackend::Init, history_backend_.get(), languages, no_db_, history_database_params)); @@ -1165,6 +1151,7 @@ } void HistoryService::ExpireLocalAndRemoteHistoryBetween( + history::WebHistoryService* web_history, const std::set<GURL>& restrict_urls, Time begin_time, Time end_time, @@ -1172,9 +1159,6 @@ base::CancelableTaskTracker* tracker) { // TODO(dubroy): This should be factored out into a separate class that // dispatches deletions to the proper places. - - history::WebHistoryService* web_history = - WebHistoryServiceFactory::GetForProfile(profile_); if (web_history) { // TODO(dubroy): This API does not yet support deletion of specific URLs. DCHECK(restrict_urls.empty());
diff --git a/chrome/browser/history/history_service.h b/chrome/browser/history/history_service.h index b167f43..23c8e4b 100644 --- a/chrome/browser/history/history_service.h +++ b/chrome/browser/history/history_service.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_HISTORY_HISTORY_SERVICE_H_ #include <set> +#include <string> #include <vector> #include "base/basictypes.h" @@ -38,10 +39,10 @@ #endif class GURL; -class PageUsageData; +class HistoryService; +struct ImportedFaviconUsage; class PageUsageRequest; class Profile; -struct ImportedFaviconUsage; class SkBitmap; namespace base { @@ -55,22 +56,24 @@ namespace history { +struct DownloadRow; +struct HistoryAddPageArgs; class HistoryBackend; class HistoryClient; +class HistoryDBTask; class HistoryDatabase; struct HistoryDatabaseParams; -class HistoryDBTask; class HistoryQueryTest; class HistoryServiceObserver; class HistoryTest; class InMemoryHistoryBackend; class InMemoryURLIndex; class InMemoryURLIndexTest; +struct KeywordSearchTermVisit; +class PageUsageData; class URLDatabase; class VisitFilter; -struct DownloadRow; -struct HistoryAddPageArgs; -struct KeywordSearchTermVisit; +class WebHistoryService; } // namespace history @@ -84,11 +87,11 @@ public visitedlink::VisitedLinkDelegate { public: // Miscellaneous commonly-used types. - typedef std::vector<PageUsageData*> PageUsageDataList; + typedef std::vector<history::PageUsageData*> PageUsageDataList; // Must call Init after construction. The |history::HistoryClient| object // must be valid for the whole lifetime of |HistoryService|. - explicit HistoryService(history::HistoryClient* client, Profile* profile); + HistoryService(history::HistoryClient* client, Profile* profile); // The empty constructor is provided only for testing. HistoryService(); @@ -96,9 +99,11 @@ // Initializes the history service, returning true on success. On false, do // not call any other functions. The given directory will be used for storing - // the history files. - bool Init(const history::HistoryDatabaseParams& history_database_params) { - return Init(false, history_database_params); + // the history files. |languages| is a comma-separated list of languages to + // use when interpreting URLs, it must not be empty (except during testing). + bool Init(const std::string& languages, + const history::HistoryDatabaseParams& history_database_params) { + return Init(false, languages, history_database_params); } // Triggers the backend to load if it hasn't already, and then returns whether @@ -351,11 +356,13 @@ // Removes all visits to the given URLs in the specified time range. Calls // ExpireHistoryBetween() to delete local visits, and handles deletion of // synced visits if appropriate. - void ExpireLocalAndRemoteHistoryBetween(const std::set<GURL>& restrict_urls, - base::Time begin_time, - base::Time end_time, - const base::Closure& callback, - base::CancelableTaskTracker* tracker); + void ExpireLocalAndRemoteHistoryBetween( + history::WebHistoryService* web_history, + const std::set<GURL>& restrict_urls, + base::Time begin_time, + base::Time end_time, + const base::Closure& callback, + base::CancelableTaskTracker* tracker); // Processes the given |delete_directive| and sends it to the // SyncChangeProcessor (if it exists). Returns any error resulting @@ -561,6 +568,7 @@ // Low-level Init(). Same as the public version, but adds a |no_db| parameter // that is only set by unittests which causes the backend to not init its DB. bool Init(bool no_db, + const std::string& languages, const history::HistoryDatabaseParams& history_database_params); // Called by the HistoryURLProvider class to schedule an autocomplete, it @@ -812,9 +820,6 @@ // outlive |HistoryService|. history::HistoryClient* history_client_; - // The profile, may be null when testing. - Profile* profile_; - // Used for propagating link highlighting data across renderers. May be null // in tests. scoped_ptr<visitedlink::VisitedLinkMaster> visitedlink_master_;
diff --git a/chrome/browser/history/history_service_factory.cc b/chrome/browser/history/history_service_factory.cc index 87a406a..1c39d82 100644 --- a/chrome/browser/history/history_service_factory.cc +++ b/chrome/browser/history/history_service_factory.cc
@@ -75,10 +75,11 @@ KeyedService* HistoryServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - Profile* profile = static_cast<Profile*>(context); + Profile* profile = Profile::FromBrowserContext(context); scoped_ptr<HistoryService> history_service(new HistoryService( ChromeHistoryClientFactory::GetForProfile(profile), profile)); if (!history_service->Init( + profile->GetPrefs()->GetString(prefs::kAcceptLanguages), history::HistoryDatabaseParamsForPath(profile->GetPath()))) { return nullptr; }
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc index 346c54ef4..6a3cf00 100644 --- a/chrome/browser/history/history_unittest.cc +++ b/chrome/browser/history/history_unittest.cc
@@ -1000,7 +1000,8 @@ history_dir_ = temp_dir_.path().AppendASCII("HistoryTest"); ASSERT_TRUE(base::CreateDirectory(history_dir_)); history_service_.reset(new HistoryService); - if (!history_service_->Init(HistoryDatabaseParamsForPath(history_dir_))) { + if (!history_service_->Init(std::string(), + HistoryDatabaseParamsForPath(history_dir_))) { history_service_.reset(); ADD_FAILURE(); }
diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc index f7e8180..a33236d 100644 --- a/chrome/browser/importer/profile_writer.cc +++ b/chrome/browser/importer/profile_writer.cc
@@ -38,6 +38,7 @@ #endif using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/invalidation/DEPS b/chrome/browser/invalidation/DEPS index 4330e28..64f2560 100644 --- a/chrome/browser/invalidation/DEPS +++ b/chrome/browser/invalidation/DEPS
@@ -5,5 +5,6 @@ # Needed for InvalidationController JNI methods. "+chrome/jni/InvalidationController_jni.h", + "+components/gcm_driver", "+components/invalidation", ]
diff --git a/chrome/browser/invalidation/ticl_profile_settings_provider.cc b/chrome/browser/invalidation/ticl_profile_settings_provider.cc index b0160122..6b2292c9 100644 --- a/chrome/browser/invalidation/ticl_profile_settings_provider.cc +++ b/chrome/browser/invalidation/ticl_profile_settings_provider.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "components/gcm_driver/gcm_channel_status_syncer.h" namespace invalidation { @@ -23,7 +24,7 @@ base::Bind(&TiclProfileSettingsProvider::FireOnUseGCMChannelChanged, base::Unretained(this))); registrar_.Add( - prefs::kGCMChannelEnabled, + gcm::prefs::kGCMChannelStatus, base::Bind(&TiclProfileSettingsProvider::FireOnUseGCMChannelChanged, base::Unretained(this))); }
diff --git a/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc b/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc index dc9b0ed..7d62b4c 100644 --- a/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc +++ b/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" +#include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/invalidation/fake_invalidation_state_tracker.h" #include "components/invalidation/invalidation_state_tracker.h" #include "components/invalidation/ticl_invalidation_service.h" @@ -79,26 +80,26 @@ // If GCM is enabled and invalidation channel setting is not set or set to // true then use GCM channel. - prefs->SetBoolean(prefs::kGCMChannelEnabled, true); + prefs->SetBoolean(gcm::prefs::kGCMChannelStatus, true); prefs->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, true); EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel()); - prefs->SetBoolean(prefs::kGCMChannelEnabled, true); + prefs->SetBoolean(gcm::prefs::kGCMChannelStatus, true); prefs->ClearPref(prefs::kInvalidationServiceUseGCMChannel); EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel()); - prefs->ClearPref(prefs::kGCMChannelEnabled); + prefs->ClearPref(gcm::prefs::kGCMChannelStatus); prefs->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, true); EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel()); // If invalidation channel setting is set to false, fall back to push channel. - prefs->SetBoolean(prefs::kGCMChannelEnabled, true); + prefs->SetBoolean(gcm::prefs::kGCMChannelStatus, true); prefs->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, false); EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); // If invalidation channel setting says use GCM but GCM is not enabled, fall // back to push channel. - prefs->SetBoolean(prefs::kGCMChannelEnabled, false); + prefs->SetBoolean(gcm::prefs::kGCMChannelStatus, false); prefs->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, true); EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); }
diff --git a/chrome/browser/jumplist_win.h b/chrome/browser/jumplist_win.h index 84f8fadf..e8931da 100644 --- a/chrome/browser/jumplist_win.h +++ b/chrome/browser/jumplist_win.h
@@ -33,7 +33,6 @@ class NotificationRegistrar; } -class PageUsageData; class PrefChangeRegistrar; class Profile; @@ -42,7 +41,6 @@ // JumpList: // * Retrieving "Most Visited" pages from HistoryService; // * Retrieving strings from the application resource; -// * Creating COM objects used by JumpList from PageUsageData objects; // * Adding COM objects to JumpList, etc. // // This class observes the tabs and policies of the given Profile and updates
diff --git a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc index cae9ef8..8b7b3b5 100644 --- a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc +++ b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
@@ -27,8 +27,8 @@ "You need to add this solution to your .gclient to run this test:\n" "{\n" " \"name\" : \"webrtc.DEPS\",\n" - " \"url\" : \"svn://svn.chromium.org/chrome/trunk/deps/" - "third_party/webrtc/webrtc.DEPS\",\n" + " \"url\" : \"https://chromium.googlesource.com/chromium/deps/" + "webrtc/webrtc.DEPS\",\n" "}"; const char kTitlePageOfAppEngineAdminPage[] = "Instances"; @@ -86,13 +86,19 @@ } base::FilePath apprtc_dir = - GetSourceDir().Append(FILE_PATH_LITERAL( - "out/webrtc-samples/samples/web/content/apprtc")); + GetSourceDir().Append(FILE_PATH_LITERAL("out/apprtc/out/app_engine")); if (!base::PathExists(apprtc_dir)) { - LOG(ERROR) << "Missing AppRTC code at " << + LOG(ERROR) << "Missing AppRTC AppEngine app at " << apprtc_dir.value() << ". " << kAdviseOnGclientSolution; return false; } + if (!base::PathExists(apprtc_dir.Append(FILE_PATH_LITERAL("app.yaml")))) { + LOG(ERROR) << "The AppRTC AppEngine app at " << + apprtc_dir.value() << " appears to have not been built." << + "This should have been done by webrtc.DEPS scripts which invoke " << + "'grunt build' on AppRTC."; + return false; + } base::CommandLine command_line(base::CommandLine::NO_PROGRAM); EXPECT_TRUE(GetPythonCommand(&command_line)); @@ -226,7 +232,14 @@ base::Process collider_server_; }; -IN_PROC_BROWSER_TEST_F(WebRtcApprtcBrowserTest, MANUAL_WorksOnApprtc) { +#if defined(OS_WIN) +// Disabled due to https://github.com/webrtc/apprtc/issues/48. +#define MAYBE_MANUAL_WorksOnApprtc DISABLED_MANUAL_WorksOnApprtc +#else +#define MAYBE_MANUAL_WorksOnApprtc MANUAL_WorksOnApprtc +#endif + +IN_PROC_BROWSER_TEST_F(WebRtcApprtcBrowserTest, MAYBE_MANUAL_WorksOnApprtc) { // Disabled on Win XP: http://code.google.com/p/webrtc/issues/detail?id=2703. if (OnWinXp()) return;
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.cc b/chrome/browser/media/protected_media_identifier_permission_context.cc index 990be4c..05e8a68a 100644 --- a/chrome/browser/media/protected_media_identifier_permission_context.cc +++ b/chrome/browser/media/protected_media_identifier_permission_context.cc
@@ -13,14 +13,26 @@ #include "content/public/browser/web_contents.h" #if defined(OS_CHROMEOS) +#include <utility> + +#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/settings/cros_settings_names.h" +#include "ui/views/widget/widget.h" + +using chromeos::attestation::PlatformVerificationDialog; +using chromeos::attestation::PlatformVerificationFlow; #endif ProtectedMediaIdentifierPermissionContext:: ProtectedMediaIdentifierPermissionContext(Profile* profile) : PermissionContextBase(profile, - CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { + CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) +#if defined(OS_CHROMEOS) + , + weak_factory_(this) +#endif +{ } ProtectedMediaIdentifierPermissionContext:: @@ -30,23 +42,62 @@ void ProtectedMediaIdentifierPermissionContext::RequestPermission( content::WebContents* web_contents, const PermissionRequestID& id, - const GURL& requesting_frame_origin, + const GURL& requesting_origin, bool user_gesture, const BrowserPermissionCallback& callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!IsProtectedMediaIdentifierEnabled()) { - NotifyPermissionSet(id, - requesting_frame_origin, - web_contents->GetLastCommittedURL().GetOrigin(), - callback, false, false); + GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); + + if (!requesting_origin.is_valid() || !embedding_origin.is_valid() || + !IsProtectedMediaIdentifierEnabled()) { + NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, + false /* persist */, false /* granted */); return; } - PermissionContextBase::RequestPermission(web_contents, id, - requesting_frame_origin, - user_gesture, - callback); +#if defined(OS_CHROMEOS) + // On ChromeOS, we don't use PermissionContextBase::RequestPermission() which + // uses the standard permission infobar/bubble UI. See http://crbug.com/454847 + // Instead, we check the content setting and show the existing platform + // verification UI. + // TODO(xhwang): Remove when http://crbug.com/454847 is fixed. + ContentSetting content_setting = + GetPermissionStatus(requesting_origin, embedding_origin); + + switch (content_setting) { + case CONTENT_SETTING_BLOCK: + NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, + false /* persist */, false /* granted */); + return; + case CONTENT_SETTING_ALLOW: + NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, + false /* persist */, true /* granted */); + return; + default: + break; + } + + // Since the dialog is modal, we only support one prompt per |web_contents|. + // Reject the new one if there is already one pending. See + // http://crbug.com/447005 + if (pending_requests_.count(web_contents)) { + callback.Run(false); + return; + } + + views::Widget* widget = PlatformVerificationDialog::ShowDialog( + web_contents, requesting_origin, + base::Bind(&ProtectedMediaIdentifierPermissionContext:: + OnPlatformVerificationResult, + weak_factory_.GetWeakPtr(), web_contents, id, + requesting_origin, embedding_origin, callback)); + pending_requests_.insert( + std::make_pair(web_contents, std::make_pair(widget, id))); +#else + PermissionContextBase::RequestPermission(web_contents, id, requesting_origin, + user_gesture, callback); +#endif } ContentSetting ProtectedMediaIdentifierPermissionContext::GetPermissionStatus( @@ -59,6 +110,27 @@ embedding_origin); } +void ProtectedMediaIdentifierPermissionContext::CancelPermissionRequest( + content::WebContents* web_contents, + const PermissionRequestID& id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + +#if defined(OS_CHROMEOS) + PendingRequestMap::iterator request = pending_requests_.find(web_contents); + if (request == pending_requests_.end() || !request->second.second.Equals(id)) + return; + + // Close the |widget_|. OnPlatformVerificationResult() will be fired + // during this process, but since |web_contents| is removed from + // |pending_requests_|, the callback will simply be dropped. + views::Widget* widget = request->second.first; + pending_requests_.erase(request); + widget->Close(); +#else + PermissionContextBase::CancelPermissionRequest(web_contents, id); +#endif +} + void ProtectedMediaIdentifierPermissionContext::UpdateTabContext( const PermissionRequestID& id, const GURL& requesting_frame, @@ -73,7 +145,6 @@ content_settings->OnProtectedMediaIdentifierPermissionSet( requesting_frame.GetOrigin(), allowed); } - } // TODO(xhwang): We should consolidate the "protected content" related pref @@ -101,3 +172,34 @@ << "Protected media identifier disabled by the user or by device policy."; return enabled; } + +#if defined(OS_CHROMEOS) +void ProtectedMediaIdentifierPermissionContext::OnPlatformVerificationResult( + content::WebContents* web_contents, + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + const BrowserPermissionCallback& callback, + chromeos::attestation::PlatformVerificationFlow::ConsentResponse response) { + // The request may have been canceled. Drop the callback in that case. + PendingRequestMap::iterator request = pending_requests_.find(web_contents); + if (request == pending_requests_.end()) + return; + + DCHECK(request->second.second.Equals(id)); + pending_requests_.erase(request); + + if (response == PlatformVerificationFlow::CONSENT_RESPONSE_NONE) { + // Deny request and do not save to content settings. + NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, + false, // Do not save to content settings. + false); // Do not allow the permission. + return; + } + + NotifyPermissionSet( + id, requesting_origin, embedding_origin, callback, + true, // Save to content settings. + response == PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW); +} +#endif
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.h b/chrome/browser/media/protected_media_identifier_permission_context.h index 58fba09..4cc94f5 100644 --- a/chrome/browser/media/protected_media_identifier_permission_context.h +++ b/chrome/browser/media/protected_media_identifier_permission_context.h
@@ -6,10 +6,22 @@ #define CHROME_BROWSER_MEDIA_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_CONTEXT_H_ #include "chrome/browser/content_settings/permission_context_base.h" +#include "components/content_settings/core/common/permission_request_id.h" -class PermissionRequestID; +#if defined(OS_CHROMEOS) +#include <map> + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" +#include "chrome/browser/chromeos/attestation/platform_verification_flow.h" +#endif + class Profile; +namespace views { +class Widget; +} + namespace content { class RenderViewHost; class WebContents; @@ -26,12 +38,14 @@ // valid iframes. It also adds special logic when called through an extension. void RequestPermission(content::WebContents* web_contents, const PermissionRequestID& id, - const GURL& requesting_frame_origin, + const GURL& requesting_origin, bool user_gesture, const BrowserPermissionCallback& callback) override; ContentSetting GetPermissionStatus( const GURL& requesting_origin, const GURL& embedding_origin) const override; + void CancelPermissionRequest(content::WebContents* web_contents, + const PermissionRequestID& id) override; private: ~ProtectedMediaIdentifierPermissionContext() override; @@ -44,6 +58,29 @@ // user in the master switch in content settings, or by the device policy. bool IsProtectedMediaIdentifierEnabled() const; +#if defined(OS_CHROMEOS) + void OnPlatformVerificationResult( + content::WebContents* web_contents, + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + const BrowserPermissionCallback& callback, + chromeos::attestation::PlatformVerificationFlow::ConsentResponse + response); + + // |this| is shared among multiple WebContents, so we could receive multiple + // permission requests. This map tracks all pending requests. Note that we + // only allow one request per WebContents. + typedef std::map<content::WebContents*, + std::pair<views::Widget*, PermissionRequestID>> + PendingRequestMap; + PendingRequestMap pending_requests_; + + // Must be the last member, to ensure that it will be + // destroyed first, which will invalidate weak pointers + base::WeakPtrFactory<ProtectedMediaIdentifierPermissionContext> weak_factory_; +#endif + DISALLOW_COPY_AND_ASSIGN(ProtectedMediaIdentifierPermissionContext); };
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc index f04ec04c..e79300a5 100644 --- a/chrome/browser/net/cookie_policy_browsertest.cc +++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -63,8 +63,7 @@ // changed when we follow a redirect. ASSERT_EQ("127.0.0.1", redirected_url.host()); GURL::Replacements replacements; - std::string new_host("www.example.com"); - replacements.SetHostStr(new_host); + replacements.SetHostStr("www.example.com"); redirected_url = redirected_url.ReplaceComponents(replacements); std::string cookie =
diff --git a/chrome/browser/net/crl_set_fetcher.cc b/chrome/browser/net/crl_set_fetcher.cc index 43ee505..b61fac2 100644 --- a/chrome/browser/net/crl_set_fetcher.cc +++ b/chrome/browser/net/crl_set_fetcher.cc
@@ -241,4 +241,8 @@ return false; } +bool CRLSetFetcher::Uninstall() { + return false; +} + CRLSetFetcher::~CRLSetFetcher() {}
diff --git a/chrome/browser/net/crl_set_fetcher.h b/chrome/browser/net/crl_set_fetcher.h index 3568df3..08f5c00 100644 --- a/chrome/browser/net/crl_set_fetcher.h +++ b/chrome/browser/net/crl_set_fetcher.h
@@ -25,8 +25,7 @@ class ComponentUpdateService; } -class CRLSetFetcher : public update_client::ComponentInstaller, - public base::RefCountedThreadSafe<CRLSetFetcher> { +class CRLSetFetcher : public update_client::ComponentInstaller { public: CRLSetFetcher(); @@ -42,6 +41,7 @@ const base::FilePath& unpack_path) override; bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; + bool Uninstall() override; private: friend class base::RefCountedThreadSafe<CRLSetFetcher>;
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc index fe5d0d98..307c61c25 100644 --- a/chrome/browser/net/predictor_browsertest.cc +++ b/chrome/browser/net/predictor_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "content/public/test/test_utils.h" #include "net/base/net_errors.h" #include "net/dns/host_resolver_proc.h" @@ -20,6 +21,8 @@ namespace { +const char kChromiumHostname[] = "chromium.org"; + // Records a history of all hostnames for which resolving has been requested, // and immediately fails the resolution requests themselves. class HostResolutionRequestRecorder : public net::HostResolverProc { @@ -189,5 +192,13 @@ WaitUntilHostHasBeenRequested(target_url_.host()); } +IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DnsPrefetch) { + ASSERT_TRUE(test_server()->Start()); + ui_test_utils::NavigateToURL( + browser(), + GURL(test_server()->GetURL("files/predictor/dns_prefetch.html"))); + WaitUntilHostHasBeenRequested(kChromiumHostname); +} + } // namespace chrome_browser_net
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.cc b/chrome/browser/net/pref_proxy_config_tracker_impl.cc index 3e969c8..6e9b771 100644 --- a/chrome/browser/net/pref_proxy_config_tracker_impl.cc +++ b/chrome/browser/net/pref_proxy_config_tracker_impl.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" +#include "base/profiler/scoped_tracker.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/prefs/proxy_config_dictionary.h" @@ -101,6 +102,10 @@ void ChromeProxyConfigService::OnProxyConfigChanged( const net::ProxyConfig& config, ConfigAvailability availability) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455942 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455942 ChromeProxyConfigService::OnProxyConfigChanged")); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Check whether there is a proxy configuration defined by preferences. In
diff --git a/chrome/browser/net/proxy_browsertest.cc b/chrome/browser/net/proxy_browsertest.cc index ca230ac..d705a09 100644 --- a/chrome/browser/net/proxy_browsertest.cc +++ b/chrome/browser/net/proxy_browsertest.cc
@@ -129,9 +129,8 @@ // Visit a page that tries to establish WebSocket connection. The title // of the page will be 'PASS' on success. - std::string scheme("http"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); ui_test_utils::NavigateToURL(browser(), ws_server.GetURL("proxied_request_check.html") .ReplaceComponents(replacements));
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc index 85dc0b17..ce94aae 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
@@ -15,6 +15,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "jni/DataReductionProxySettings_jni.h" +#include "net/proxy/proxy_server.h" using base::android::ConvertUTF8ToJavaString; @@ -46,7 +47,7 @@ ScopedJavaLocalRef<jstring> DataReductionProxySettingsAndroid::GetDataReductionProxyOrigin( JNIEnv* env, jobject obj) { - return ConvertUTF8ToJavaString(env, Settings()->params()->origin().spec()); + return ConvertUTF8ToJavaString(env, Settings()->params()->origin().ToURI()); } jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyEnabled(
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc index 4248c272..1660c618 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
@@ -15,6 +15,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h" +#include "net/proxy/proxy_server.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -23,7 +24,7 @@ using testing::AnyNumber; using testing::Return; -const char kDataReductionProxyDev[] = "http://foo-dev.com:80"; +const char kDataReductionProxyDev[] = "foo-dev.com:80"; using data_reduction_proxy::DataReductionProxySettings; @@ -154,8 +155,8 @@ SettingsAndroid()->GetDataReductionProxyOrigin(env_, NULL); ASSERT_TRUE(result.obj()); const base::android::JavaRef<jstring>& str_ref = result; - EXPECT_EQ(GURL(expected_params_->DefaultOrigin()), - GURL(ConvertJavaStringToUTF8(str_ref))); + EXPECT_EQ(expected_params_->DefaultOrigin(), + ConvertJavaStringToUTF8(str_ref)); } TEST_F(DataReductionProxySettingsAndroidTest, @@ -169,8 +170,8 @@ SettingsAndroid()->GetDataReductionProxyOrigin(env_, NULL); ASSERT_TRUE(result.obj()); const base::android::JavaRef<jstring>& str_ref = result; - EXPECT_EQ(GURL(kDataReductionProxyDev), - GURL(ConvertJavaStringToUTF8(str_ref))); + EXPECT_EQ(kDataReductionProxyDev, + ConvertJavaStringToUTF8(str_ref)); } TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) {
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc index 7aee438..3ef21c0b 100644 --- a/chrome/browser/net/websocket_browsertest.cc +++ b/chrome/browser/net/websocket_browsertest.cc
@@ -38,18 +38,16 @@ protected: void NavigateToHTTP(const std::string& path) { // Visit a HTTP page for testing. - std::string scheme("http"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); ui_test_utils::NavigateToURL( browser(), ws_server_.GetURL(path).ReplaceComponents(replacements)); } void NavigateToHTTPS(const std::string& path) { // Visit a HTTPS page for testing. - std::string scheme("https"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("https"); ui_test_utils::NavigateToURL( browser(), wss_server_.GetURL(path).ReplaceComponents(replacements)); } @@ -204,9 +202,8 @@ ASSERT_TRUE(ws_server_.Start()); // Open connect_check.html via HTTP with credentials in the URL. - std::string scheme("http"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); ui_test_utils::NavigateToURL( browser(), ws_server_.GetURLWithUserAndPassword("connect_check.html", "test", "test") @@ -221,9 +218,8 @@ ASSERT_TRUE(wss_server_.Start()); // Open connect_check.html via HTTPS with credentials in the URL. - std::string scheme("https"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("https"); ui_test_utils::NavigateToURL( browser(), wss_server_.GetURLWithUserAndPassword(
diff --git a/chrome/browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc b/chrome/browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc index 469f0a3..23f09c3 100644 --- a/chrome/browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc +++ b/chrome/browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc
@@ -87,7 +87,6 @@ message_center::NotifierId::APPLICATION, "test-notifier"); // Logged in as a normal user. - EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(1); LoginUser(kTestUsers[0]); EXPECT_EQ(1, GetStateChangedCountAndReset()); EXPECT_TRUE(ShouldShowNotificationAsPopup(notifier_id)); @@ -122,7 +121,6 @@ ash::system_notifier::kNotifierDisplay); // Logged in as a normal user. - EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(1); LoginUser(kTestUsers[0]); EXPECT_EQ(1, GetStateChangedCountAndReset()); EXPECT_TRUE(ShouldShowNotificationAsPopup(notifier_id));
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index beddbb3..1d8b463e 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -2195,7 +2195,7 @@ DisableJavascriptCalls(); // The loader page should look like Google. - const std::string kGoogleDotCom("www.google.com"); + static const char kGoogleDotCom[] = "www.google.com"; SetLoaderHostOverride(kGoogleDotCom); set_loader_path("files/prerender/prerender_loader_with_replace_state.html");
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc index c5861c0..15b6bc4 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc +++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
@@ -207,11 +207,10 @@ } bool LaunchBrowser(const base::CommandLine& command_line, Profile* profile) { - int return_code = 0; StartupBrowserCreator browser_creator; return StartupBrowserCreator::ProcessCmdLineImpl( command_line, base::FilePath(), false, profile, - StartupBrowserCreator::Profiles(), &return_code, &browser_creator); + StartupBrowserCreator::Profiles(), &browser_creator); } protected:
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc index 43b855e9..fff3e38 100644 --- a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc +++ b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
@@ -322,11 +322,10 @@ base::CommandLine MakeCmdLine(const std::string& procname) override; bool LaunchBrowser(const base::CommandLine& command_line, Profile* profile) { - int return_code = 0; StartupBrowserCreator browser_creator; return StartupBrowserCreator::ProcessCmdLineImpl( command_line, base::FilePath(), false, profile, - StartupBrowserCreator::Profiles(), &return_code, &browser_creator); + StartupBrowserCreator::Profiles(), &browser_creator); } protected:
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc index bcb7ee2..5335eb9 100644 --- a/chrome/browser/profiles/profile_info_cache.cc +++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -148,13 +148,6 @@ base::DeleteFile(image_path, false); } -// Used by SaveAvatarImageAtPath to post a task to delete the |downloader| -// "soon". We can't just delete it directly there because -// SaveAvatarImageAtPath is called from this very downloader. -void DeleteDownloader(ProfileAvatarDownloader* downloader) { - delete downloader; -} - } // namespace ProfileInfoCache::ProfileInfoCache(PrefService* prefs, @@ -857,23 +850,6 @@ } // static -std::vector<base::string16> ProfileInfoCache::GetProfileNames() { - std::vector<base::string16> names; - PrefService* local_state = g_browser_process->local_state(); - const base::DictionaryValue* cache = local_state->GetDictionary( - prefs::kProfileInfoCache); - base::string16 name; - for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd(); - it.Advance()) { - const base::DictionaryValue* info = NULL; - it.value().GetAsDictionary(&info); - info->GetString(kNameKey, &name); - names.push_back(name); - } - return names; -} - -// static void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterDictionaryPref(prefs::kProfileInfoCache); } @@ -914,9 +890,8 @@ if (downloader_iter != avatar_images_downloads_in_progress_.end()) { // We mustn't delete the avatar downloader right here, since we're being // called by it. - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&DeleteDownloader, - downloader_iter->second)); + BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, + downloader_iter->second); avatar_images_downloads_in_progress_.erase(downloader_iter); }
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h index 95db92c4..1fe8937 100644 --- a/chrome/browser/profiles/profile_info_cache.h +++ b/chrome/browser/profiles/profile_info_cache.h
@@ -129,12 +129,6 @@ const base::FilePath& GetUserDataDir() const; - // Gets all names of profiles associated with this instance of Chrome. - // Because this method will be called during uninstall, before the creation - // of the ProfileManager, it reads directly from the local state preferences, - // rather than going through the ProfileInfoCache object. - static std::vector<base::string16> GetProfileNames(); - // Register cache related preferences in Local State. static void RegisterPrefs(PrefRegistrySimple* registry);
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc index 57c2e338..d3e6d47 100644 --- a/chrome/browser/profiles/profile_info_cache_unittest.cc +++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "components/signin/core/common/profile_management_switches.h" #include "content/public/browser/notification_observer.h" @@ -530,7 +531,19 @@ ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles()); // Check that the profiles can be extracted from the local state. - std::vector<base::string16> names = ProfileInfoCache::GetProfileNames(); + std::vector<base::string16> names; + PrefService* local_state = g_browser_process->local_state(); + const base::DictionaryValue* cache = local_state->GetDictionary( + prefs::kProfileInfoCache); + base::string16 name; + for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd(); + it.Advance()) { + const base::DictionaryValue* info = NULL; + it.value().GetAsDictionary(&info); + info->GetString("name", &name); + names.push_back(name); + } + for (size_t i = 0; i < 4; i++) ASSERT_FALSE(names[i].empty()); }
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 9b85dff..4bb0f38 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -262,10 +262,9 @@ content::RecordAction(UserMetricsAction("NewWindow")); base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - int return_code; StartupBrowserCreator browser_creator; - browser_creator.LaunchBrowser(command_line, profile, base::FilePath(), - process_startup, is_first_run, &return_code); + browser_creator.LaunchBrowser( + command_line, profile, base::FilePath(), process_startup, is_first_run); #endif // defined(OS_IOS) }
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index 089354c5..18d11c8c 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -45,6 +45,7 @@ const uint32 kFilteredMessageClasses[] = { ChromeMsgStart, + DnsPrefetchMsgStart, }; } // namespace
diff --git a/chrome/browser/resources/about_version.css b/chrome/browser/resources/about_version.css index 4f19be8..343dedf 100644 --- a/chrome/browser/resources/about_version.css +++ b/chrome/browser/resources/about_version.css
@@ -59,4 +59,5 @@ font-family: monospace; max-width: 430px; padding-left: 5px; + vertical-align: bottom; }
diff --git a/chrome/browser/resources/chromeos/OWNERS b/chrome/browser/resources/chromeos/OWNERS index a509302..03bb6b3 100644 --- a/chrome/browser/resources/chromeos/OWNERS +++ b/chrome/browser/resources/chromeos/OWNERS
@@ -3,6 +3,7 @@ achuith@chromium.org zelidrag@chromium.org satorux@chromium.org +stevenjb@chromium.org per-file drive_internals*=hashimoto@chromium.org per-file drive_internals*=kinaba@chromium.org
diff --git a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js index 41edd0e21..f3d312211 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js +++ b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
@@ -1511,7 +1511,6 @@ unknown: 'unknown', tooltip: 'tooltip', webArea: 'webArea', - webView: 'webView', window: 'window' }; /**
diff --git a/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js index 5731239..d7d7bd4 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js +++ b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
@@ -6,7 +6,6 @@ goog.provide('cvox.TextChangeEvent'); goog.provide('cvox.TypingEcho'); -goog.require('cvox.AbstractTts'); goog.require('cvox.ChromeVox'); goog.require('cvox.TtsInterface'); goog.require('goog.i18n.MessageFormat');
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js index c14c6a9..3e6fe19 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -55,9 +55,11 @@ * @return {boolean} */ AutomationPredicate.leaf = function(node) { - return !node.firstChild || node.children.every(function(n) { - return n.state.invisible; - }); + return !node.firstChild || + node.role == chrome.automation.RoleType.button || + node.children.every(function(n) { + return n.state.invisible; + }); }; /**
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js index 16f7506..d5d9956 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
@@ -88,12 +88,8 @@ while (cur) { var next = dir == Dir.BACKWARD ? cur.previousSibling : cur.nextSibling; - if (!AutomationUtil.isInSameTree(cur, next)) - return null; if (next) return next; - if (!AutomationUtil.isInSameTree(cur, cur.parent)) - return null; cur = cur.parent; } }; @@ -168,10 +164,6 @@ var candidate = node; while (candidate) { ret.push(candidate); - - if (!AutomationUtil.isInSameTree(candidate, candidate.parent)) - break; - candidate = candidate.parent; } return ret.reverse(); @@ -234,17 +226,4 @@ return divA.indexInParent <= divB.indexInParent ? Dir.FORWARD : Dir.BACKWARD; }; -/** - * Determines whether the two given nodes come from the same tree source. - * @param {AutomationNode} a - * @param {AutomationNode} b - * @return {boolean} - */ -AutomationUtil.isInSameTree = function(a, b) { - if (!a || !b) - return true; - - return a.root === b.root; -}; - }); // goog.scope
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js index 7659707e..c330608 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -16,6 +16,7 @@ goog.require('Output.EventType'); goog.require('cursors.Cursor'); goog.require('cvox.ChromeVoxEditableTextBase'); +goog.require('cvox.TabsApiHandler'); goog.scope(function() { var AutomationNode = chrome.automation.AutomationNode; @@ -36,6 +37,14 @@ this.whitelist_ = ['chromevox_next_test']; /** + * @type {cvox.TabsApiHandler} + * @private + */ + this.tabsHandler_ = new cvox.TabsApiHandler(cvox.ChromeVox.tts, + cvox.ChromeVox.braille, + cvox.ChromeVox.earcons); + + /** * @type {cursors.Range} * @private */ @@ -73,29 +82,43 @@ // Register listeners for ... // Desktop. - chrome.automation.getDesktop(this.onGotDesktop); + chrome.automation.getDesktop(this.onGotTree); + + // Tabs. + chrome.tabs.onUpdated.addListener(this.onTabUpdated); }; Background.prototype = { /** - * Handles all setup once a new automation tree appears. - * @param {chrome.automation.AutomationNode} desktop + * Handles chrome.tabs.onUpdated. + * @param {number} tabId + * @param {Object} changeInfo */ - onGotDesktop: function(desktop) { + onTabUpdated: function(tabId, changeInfo) { + if (changeInfo.status != 'complete') + return; + chrome.tabs.get(tabId, function(tab) { + if (!tab.url) + return; + + var next = this.isWhitelisted_(tab.url); + + this.toggleChromeVoxVersion({next: next, classic: !next}); + }.bind(this)); + }, + + /** + * Handles all setup once a new automation tree appears. + * @param {chrome.automation.AutomationNode} root + */ + onGotTree: function(root) { // Register all automation event listeners. for (var eventType in this.listeners_) - desktop.addEventListener(eventType, this.listeners_[eventType], true); + root.addEventListener(eventType, this.listeners_[eventType], true); - // The focused state gets set on the containing webView node. - var webView = desktop.find({role: chrome.automation.RoleType.webView, - state: {focused: true}}); - if (webView) { - var root = webView.find({role: chrome.automation.RoleType.rootWebArea}); - if (root) { - this.onLoadComplete( - {target: root, - type: chrome.automation.EventType.loadComplete}); - } + if (root.attributes.docLoaded) { + this.onLoadComplete( + {target: root, type: chrome.automation.EventType.loadComplete}); } }, @@ -247,28 +270,14 @@ * @param {Object} evt */ onLoadComplete: function(evt) { - var next = this.isWhitelisted_(evt.target.attributes.url); - this.toggleChromeVoxVersion({next: next, classic: !next}); // Don't process nodes inside of web content if ChromeVox Next is inactive. if (evt.target.root.role != chrome.automation.RoleType.desktop && !this.active_) return; - if (this.currentRange_) - return; - - var root = evt.target; - var webView = root; - while (webView && webView.role != chrome.automation.RoleType.webView) - webView = webView.parent; - - if (!webView || !webView.state.focused) - return; - - var node = AutomationUtil.findNodePost(root, + var node = AutomationUtil.findNodePost(evt.target, Dir.FORWARD, AutomationPredicate.leaf); - if (node) this.currentRange_ = cursors.Range.fromNode(node); @@ -353,11 +362,21 @@ if (opt_options.next) { if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) - chrome.commands.onCommand.addListener(this.onGotCommand); - this.active_ = true; + chrome.commands.onCommand.addListener(this.onGotCommand); + + if (!this.active_) + chrome.automation.getTree(this.onGotTree); + this.active_ = true; } else { if (chrome.commands.onCommand.hasListener(this.onGotCommand)) chrome.commands.onCommand.removeListener(this.onGotCommand); + + if (this.active_) { + for (var eventType in this.listeners_) { + this.currentRange_.getStart().getNode().root.removeEventListener( + eventType, this.listeners_[eventType], true); + } + } this.active_ = false; }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index d37e4d9..7ed70f7c 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -97,7 +97,7 @@ }, true); cvox.ChromeVox.tts.expectSpeech('end', testDone, true); - this.runWithAutomation(function() {/*! + this.runWithDocument(function() {/*! <p>start <p>end */}, @@ -107,7 +107,7 @@ /** Tests consistency of navigating forward and backward. */ TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithAutomation(this.linksAndHeadingsDoc, function() { + this.runWithDocument(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expectAfter = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts); @@ -138,7 +138,7 @@ TEST_F('BackgroundTest', 'CaretNavigation', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithAutomation(this.linksAndHeadingsDoc, function() { + this.runWithDocument(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expectAfter = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts); @@ -168,7 +168,7 @@ // Flaky: http://crbug.com/451362 TEST_F('BackgroundTest', 'DISABLED_SelectSingleBasic', function() { - this.runWithAutomation(this.formsDoc, function(tabId) { + this.runWithDocument(this.formsDoc, function(tabId) { var sendDownToSelect = this.sendKeyToElement.bind(this, tabId, 'Down', '#fruitSelect'); var expect = cvox.ChromeVox.tts.expectSpeech.bind(cvox.ChromeVox.tts); @@ -181,7 +181,7 @@ TEST_F('BackgroundTest', 'ContinuousRead', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithAutomation(this.linksAndHeadingsDoc, function() { + this.runWithDocument(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expect = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs index d5b9fd3..7cc281a4b 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
@@ -70,7 +70,6 @@ range = range.move(move[0], move[1]); var expectedStart = move[2]; var expectedEnd = move[3]; - this.makeCursorAssertion(expectedStart, range.getStart()); this.makeCursorAssertion(expectedEnd, range.getEnd()); } @@ -94,25 +93,27 @@ * @param {string=} opt_testType Either CURSOR or RANGE. */ runCursorMovesOnDocument: function(doc, moves, opt_testType) { - this.runWithAutomation(doc, - function(root) { - var start = null; + this.runWithDocument(doc, + function() { + chrome.automation.getTree(function(root) { + var start = null; - // This occurs as a result of a load complete. - var start = AutomationUtil.findNodePost(root, - FORWARD, - AutomationPredicate.leaf); + // This occurs as a result of a load complete. + var start = AutomationUtil.findNodePost(root, + FORWARD, + AutomationPredicate.leaf); - var cursor = new cursors.Cursor(start, 0); - if (!opt_testType || opt_testType == this.CURSOR) { var cursor = new cursors.Cursor(start, 0); - this.cursorMoveAndAssert(cursor, moves); - testDone(); - } else if (opt_testType == this.RANGE) { - var range = new cursors.Range(cursor, cursor); - this.rangeMoveAndAssert(range, moves); - testDone(); - } + if (!opt_testType || opt_testType == this.CURSOR) { + var cursor = new cursors.Cursor(start, 0); + this.cursorMoveAndAssert(cursor, moves); + testDone(); + } else if (opt_testType == this.RANGE) { + var range = new cursors.Range(cursor, cursor); + this.rangeMoveAndAssert(range, moves); + testDone(); + } + }.bind(this)); }.bind(this)); },
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 7fb786b7..0e3c520 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -13,8 +13,6 @@ goog.require('cursors.Cursor'); goog.require('cursors.Range'); goog.require('cursors.Unit'); -goog.require('cvox.AbstractEarcons'); -goog.require('cvox.NavBraille'); goog.require('cvox.Spannable'); goog.require('cvox.ValueSelectionSpan'); goog.require('cvox.ValueSpan'); @@ -53,17 +51,23 @@ /** @type {!Array.<Object>} */ this.locations_ = []; /** @type {function()} */ - this.speechStartCallback_ = function() {}; + this.speechStartCallback_; /** @type {function()} */ - this.speechEndCallback_ = function() {}; + this.speechEndCallback_; /** @type {function()} */ - this.speechInterruptedCallback_ = function() {}; + this.speechInterruptedCallback_; /** * Current global options. * @type {{speech: boolean, braille: boolean, location: boolean}} */ this.formatOptions_ = {speech: true, braille: false, location: true}; + + /** + * Speech properties to apply to the entire output. + * @type {!Object.<string, *>} + */ + this.speechProperties_ = {}; }; /** @@ -83,7 +87,8 @@ braille: '' }, alert: { - speak: '@aria_role_alert $name $earcon(ALERT_NONMODAL)' + speak: '!doNotInterrupt ' + + '@aria_role_alert $name $earcon(ALERT_NONMODAL) $descendants' }, button: { speak: '$name $earcon(BUTTON, @tag_button)' @@ -309,15 +314,26 @@ var onEvent = function(evt) { switch (evt.type) { - case 'start': this.speechStartCallback_(); break; - case 'end': this.speechEndCallback_(); break; - case 'interrupted': this.speechInterruptedCallback_(); break; + case 'start': + this.speechStartCallback_(); + break; + case 'end': + this.speechEndCallback_(); + break; + case 'interrupted': + this.speechInterruptedCallback_ && this.speechInterruptedCallback_(); + break; } }.bind(this); if (buff.toString()) { + if (this.speechStartCallback_ || + this.speechEndCallback_ || + this.speechInterruptedCallback_) + this.speechProperties_['onEvent'] = onEvent; + cvox.ChromeVox.tts.speak( - buff.toString(), cvox.QueueMode.FLUSH, {onEvent: onEvent}); + buff.toString(), cvox.QueueMode.FLUSH, this.speechProperties_); } var actions = buff.getSpansInstanceOf(Output.Action); @@ -433,11 +449,17 @@ this.addToSpannable_(buff, node.role, options); } else if (token == 'value') { var text = node.attributes.value; - var offset = buff.getLength(); - if (node.attributes.textSelStart !== undefined) { - options.annotation = new Output.SelectionSpan( - node.attributes.textSelStart, - node.attributes.textSelEnd); + if (text) { + var offset = buff.getLength(); + if (node.attributes.textSelStart !== undefined) { + options.annotation = new Output.SelectionSpan( + node.attributes.textSelStart, + node.attributes.textSelEnd); + } + } else if (node.role == chrome.automation.RoleType.staticText) { + // TODO(dtseng): Remove once Blink treats staticText values as + // names. + text = node.attributes.name; } this.addToSpannable_(buff, text, options); } else if (token == 'indexInParent') { @@ -459,6 +481,22 @@ if (node) this.format_(node, formatString, buff); } + } else if (token == 'descendants') { + if (AutomationPredicate.leaf(node)) + return; + + // Construct a range to the leftmost and rightmost leaves. + var leftmost = AutomationUtil.findNodePre( + node, Dir.FORWARD, AutomationPredicate.leaf); + var rightmost = AutomationUtil.findNodePre( + node, Dir.BACKWARD, AutomationPredicate.leaf); + if (!leftmost || !rightmost) + return; + + var subrange = new cursors.Range( + new cursors.Cursor(leftmost, 0), + new cursors.Cursor(rightmost, 0)); + this.range_(subrange, null, 'navigate', buff); } else if (node.attributes[token]) { this.addToSpannable_(buff, node.attributes[token], options); } else if (node.state[token]) { @@ -508,6 +546,8 @@ if (msg) { this.addToSpannable_(buff, msg, options); } + } else if (prefix == '!') { + this.speechProperties_[token] = true; } }.bind(this)); },
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js b/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js index 038155f..e432a998 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js
@@ -32,14 +32,7 @@ runWithAutomation: function(doc, callback) { this.runWithDocument(doc, function() { chrome.automation.getTree(function(root) { - if (root.children.length == 0) { - root.addEventListener('loadComplete', - function() { - callback(root); - }.bind(this), true); - } else { - callback(root); - } + callback(root); }.bind(this)); }.bind(this)); }
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js b/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js index fb34e1a..0915e112 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js
@@ -113,7 +113,7 @@ // Process any idleUtterances. this.idleUtterances_.forEach(function(utterance) { this.process_(utterance, true); - }.bind(this)); + }); }, /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js index df2e3a5..572b104 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -23,6 +23,11 @@ signInUrl_: null, /** + * Gaia auth params for sign in frame. + */ + signInParams_: {}, + + /** * The current step. This is the last value passed to showStep(). */ currentStep_: null, @@ -132,18 +137,17 @@ * URL. */ onBeforeShow: function(data) { - var url = data.signin_url; - url += '?gaiaUrl=' + encodeURIComponent(data.gaiaUrl); - url += '&needPassword=0'; - this.signInUrl_ = url; + this.signInParams_ = {}; + this.signInParams_['gaiaUrl'] = data.gaiaUrl; + this.signInParams_['needPassword'] = false; + this.signInUrl_ = data.signin_url; var modes = ['manual', 'forced', 'recovery']; for (var i = 0; i < modes.length; ++i) { this.classList.toggle('mode-' + modes[i], data.enrollment_mode == modes[i]); } this.managementDomain_ = data.management_domain; - $('oauth-enroll-signin-frame').contentWindow.location.href = - this.signInUrl_; + this.doReload(); this.learnMoreHelpTopicID_ = data.learn_more_help_topic_id; this.updateLocalizedContent(); this.showStep(STEP_SIGNIN); @@ -187,8 +191,16 @@ }, doReload: function() { - $('oauth-enroll-signin-frame').contentWindow.location.href = - this.signInUrl_; + var signInFrame = $('oauth-enroll-signin-frame'); + + var sendParamsOnLoad = function() { + signInFrame.removeEventListener('load', sendParamsOnLoad); + signInFrame.contentWindow.postMessage(this.signInParams_, + 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik'); + }.bind(this); + + signInFrame.addEventListener('load', sendParamsOnLoad); + signInFrame.contentWindow.location.href = this.signInUrl_; }, /**
diff --git a/chrome/browser/resources/chromeos/neterror.js b/chrome/browser/resources/chromeos/neterror.js index 2a3dcc8f..2dad8fa 100644 --- a/chrome/browser/resources/chromeos/neterror.js +++ b/chrome/browser/resources/chromeos/neterror.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. function toggleHelpBox() { - var helpBoxOuter = $('help-box-outer'); + var helpBoxOuter = $('details'); helpBoxOuter.classList.toggle('hidden'); var detailsButton = $('details-button'); if (helpBoxOuter.classList.contains('hidden')) {
diff --git a/chrome/browser/resources/chromeos/network/network_config.js b/chrome/browser/resources/chromeos/network/network_config.js deleted file mode 100644 index 29ac7a7..0000000 --- a/chrome/browser/resources/chromeos/network/network_config.js +++ /dev/null
@@ -1,147 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -/** - * @fileoverview This object provides a similar API to chrome.networkingPrivate. - * It simulates the extension callback model by storing callbacks in a member - * object and invoking them when the corresponding method is called by Chrome in - * response to a chrome.send call. - */ - -var networkConfig = { - /** - * Return the property associated with a key (which may reference a - * sub-object). - * - * @param {Object} properties The object containing the network properties. - * @param {string} key The ONC key for the property. May refer to a nested - * propety, e.g. 'WiFi.Security'. - * @return {*} The value associated with the property. - */ - getValueFromProperties: function(properties, key) { - if (!key) { - console.error('Empty key'); - return undefined; - } - var dot = key.indexOf('.'); - if (dot > 0) { - var key1 = key.substring(0, dot); - var key2 = key.substring(dot + 1); - var subobject = properties[key1]; - if (subobject) - return this.getValueFromProperties(subobject, key2); - } - return properties[key]; - }, - - /** - * Generate a unique id for 'callback' and store it for future retrieval. - * - * @param {function} callback The associated callback. - * @return {integer} The id of the callback. - * @private - */ - callbackId: 1, - callbackMap: {}, - storeCallback_: function(callback) { - var id = this.callbackId++; - this.callbackMap[id] = callback; - return id; - }, - - /** - * Retrieve the callback associated with |id| and remove it from the map. - * - * @param {integer} id The id of the callback. - * @return {function} The associated callback. - * @private - */ - retrieveCallback_: function(id) { - var callback = this.callbackMap[id]; - delete this.callbackMap[id]; - return callback; - }, - - /** - * Callback invoked by Chrome. - * - * @param {Array} args A list of arguments passed to the callback. The first - * entry must be the callbackId passed to chrome.send. - */ - chromeCallbackSuccess: function(args) { - var callbackId = args.shift(); - var callback = this.retrieveCallback_(callbackId); - this.lastError = ''; - if (callback) - callback.apply(null, args); - else - console.error('Callback not found for id: ' + callbackId); - }, - - /** - * Error Callback invoked by Chrome. Sets lastError and logs to the console. - * - * @param {Args} args A list of arguments. The first entry must be the - * callbackId passed to chrome.send. - */ - lastError: '', - chromeCallbackError: function(args) { - var callbackId = args.shift(); - this.lastError = args.shift(); - console.error('Callback error: "' + this.lastError); - // We still invoke the callback, but with null args. The callback should - // check this.lastError and handle that. - var callback = this.retrieveCallback_(callbackId); - if (callback) - callback.apply(null, null); - }, - - /** - * Implement networkingPrivate.getProperties. See networking_private.json. - * - * @param {string} guid The guid identifying the network. - * @param {function()} callback The callback to call on completion. - */ - getProperties: function(guid, callback) { - var callbackId = this.storeCallback_(callback); - chrome.send('networkConfig.getProperties', [callbackId, guid]); - }, - - /** - * Implement networkingPrivate.getManagedProperties. See - * networking_private.json. - * - * @param {string} guid The guid identifying the network. - * @param {function()} callback The callback to call on completion. - */ - getManagedProperties: function(guid, callback) { - var callbackId = this.storeCallback_(callback); - chrome.send('networkConfig.getManagedProperties', [callbackId, guid]); - }, - - /** - * Implement networkingPrivate.getNetworks. See networking_private.json. - * - * @param {string} guid The guid identifying the network. - * @param {function()} callback The callback to call on completion. - */ - getNetworks: function(filter, callback) { - var callbackId = this.storeCallback_(callback); - chrome.send('networkConfig.getNetworks', [callbackId, filter]); - }, - - /** - * Debugging method to get raw Shill properties - * - * @param {string} guid The guid identifying the network. - * @param {function()} callback The callback to call on completion. - */ - getShillProperties: function(guid, callback) { - var callbackId = this.storeCallback_(callback); - chrome.send('networkConfig.getShillProperties', [callbackId, guid]); - }, - -};
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chrome/browser/resources/chromeos/network_ui/network_ui.html index 155c4cd..83135d6 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.html +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.html
@@ -8,7 +8,6 @@ <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="chrome://network/strings.js"></script> - <script src="chrome://network/network_config.js"></script> <script src="chrome://network/network_ui.js"></script> </head> <body>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.js b/chrome/browser/resources/chromeos/network_ui/network_ui.js index 8d86f54d..54ef7f3 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.js +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.js
@@ -36,7 +36,32 @@ ]; /** - * Create a cell with a button for expanding a network state table row. + * Returns the property associated with a key (which may reference a + * sub-object). + * + * @param {Object} properties The object containing the network properties. + * @param {string} key The ONC key for the property. May refer to a nested + * propety, e.g. 'WiFi.Security'. + * @return {*} The value associated with the property. + */ + var getValueFromProperties = function(properties, key) { + if (!key) { + console.error('Empty key'); + return undefined; + } + var dot = key.indexOf('.'); + if (dot > 0) { + var key1 = key.substring(0, dot); + var key2 = key.substring(dot + 1); + var subobject = properties[key1]; + if (subobject) + return getValueFromProperties(subobject, key2); + } + return properties[key]; + }; + + /** + * Creates a cell with a button for expanding a network state table row. * * @param {string} guid The GUID identifying the network. * @return {DOMElement} The created td element that displays the given value. @@ -55,7 +80,7 @@ }; /** - * Create a cell in network state table. + * Creates a cell in network state table. * * @param {string} value Content in the cell. * @return {DOMElement} The created td element that displays the given value. @@ -67,7 +92,7 @@ }; /** - * Create a row in the network state table. + * Creates a row in the network state table. * * @param {Array} stateFields The state fields to use for the row. * @param {Object} state Property values for the network or favorite. @@ -83,10 +108,10 @@ var field = stateFields[i]; var value = ''; if (typeof field == 'string') { - value = networkConfig.getValueFromProperties(state, field); + value = getValueFromProperties(state, field); } else { for (var j = 0; j < field.length; ++j) { - value = networkConfig.getValueFromProperties(state, field[j]); + value = getValueFromProperties(state, field[j]); if (value) break; } @@ -99,7 +124,7 @@ }; /** - * Create table for networks or favorites. + * Creates a table for networks or favorites. * * @param {string} tablename The name of the table to be created. * @param {Array} stateFields The list of fields for the table. @@ -136,7 +161,7 @@ }; /** - * Toggle the button state and add or remove a row displaying the complete + * Toggles the button state and add or remove a row displaying the complete * state information for a row. * * @param {DOMElement} btn The button that was clicked. @@ -169,36 +194,65 @@ emptyCell.style.border = 'none'; expandedRow.appendChild(emptyCell); var detailCell = document.createElement('td'); + detailCell.id = guid; detailCell.className = 'state-table-expanded-cell'; detailCell.colSpan = baseRow.childNodes.length - 1; expandedRow.appendChild(detailCell); - var showDetail = function(state) { - if (networkConfig.lastError) - detailCell.textContent = networkConfig.lastError; + var showDetail = function(state, error) { + if (error && error.message) + detailCell.textContent = error.message; else detailCell.textContent = JSON.stringify(state, null, '\t'); }; var selected = $('get-property-format').selectedIndex; var selectedId = $('get-property-format').options[selected].value; - if (selectedId == 'shill') - networkConfig.getShillProperties(guid, showDetail); - else if (selectedId == 'managed') - networkConfig.getManagedProperties(guid, showDetail); - else - networkConfig.getProperties(guid, showDetail); + if (selectedId == 'shill') { + chrome.send('getShillProperties', [guid]); + } else if (selectedId == 'managed') { + chrome.networkingPrivate.getManagedProperties(guid, function(properties) { + showDetail(properties, chrome.runtime.lastError); }); + } else { + chrome.networkingPrivate.getProperties(guid, function(properties) { + showDetail(properties, chrome.runtime.lastError); }); + } return expandedRow; }; /** + * Callback invoked by Chrome after a getShillProperties call. + * + * @param {Object} properties The requested Shill properties. Will contain + * just the 'GUID' and 'ShillError' properties if the call failed. + */ + var getShillPropertiesResult = function(args) { + var properties = args.shift(); + var guid = properties['GUID']; + if (!guid) { + console.error('No GUID in getShillPropertiesResult'); + return; + } + + var detailCell = document.querySelector('td#' + guid); + if (!detailCell) { + console.error('No cell for GUID: ' + guid); + return; + } + + if (properties['ShillError']) + detailCell.textContent = properties['ShillError']; + else + detailCell.textContent = JSON.stringify(properties, null, '\t'); + + }; + + /** * Requests an update of all network info. */ var requestNetworks = function() { - networkConfig.getNetworks( - { 'type': 'All', 'visible': true }, - onVisibleNetworksReceived); - networkConfig.getNetworks( - { 'type': 'All', 'configured': true }, - onFavoriteNetworksReceived); + chrome.networkingPrivate.getNetworks( + {'networkType': 'All', 'visible': true}, onVisibleNetworksReceived); + chrome.networkingPrivate.getNetworks( + {'networkType': 'All', 'configured': true}, onFavoriteNetworksReceived); }; /** @@ -211,7 +265,7 @@ }; /** - * Get network information from WebUI. + * Gets network information from WebUI. */ document.addEventListener('DOMContentLoaded', function() { $('refresh').onclick = requestNetworks; @@ -219,5 +273,7 @@ requestNetworks(); }); - return {}; + return { + getShillPropertiesResult: getShillPropertiesResult + }; })();
diff --git a/chrome/browser/resources/chromeos/offline_net_load.html b/chrome/browser/resources/chromeos/offline_net_load.html index c62d124..821853d1 100644 --- a/chrome/browser/resources/chromeos/offline_net_load.html +++ b/chrome/browser/resources/chromeos/offline_net_load.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;.style.fontSize:fontsize;lang:language"> +<html i18n-values="dir:textdirection;lang:language"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, @@ -31,20 +31,17 @@ jsdisplay="details"></button> </div> </div> - <!-- Outer and inner divs are needed both for margins and sizing. --> - <div id="help-box-outer" class="hidden"> - <div id="details"> - <div jsselect="summary"> - <span jsvalues=".innerHTML:msg"></span> - </div> - <div class="suggestions" jsselect="suggestions"> - <div class="suggestion-header" jsvalues=".innerHTML:header"></div> - <div class="suggestion-body" jsvalues=".innerHTML:body"></div> - </div> - <button id="diagnose-button" onclick="diagnoseErrors()" - jscontent="diagnose" jsdisplay="diagnose"></button> - <div class="error-code" jscontent="errorCode"></div> + <div id="details" class="hidden"> + <div jsselect="summary"> + <span jsvalues=".innerHTML:msg"></span> </div> + <div class="suggestions" jsselect="suggestions"> + <div class="suggestion-header" jsvalues=".innerHTML:header"></div> + <div class="suggestion-body" jsvalues=".innerHTML:body"></div> + </div> + <button id="diagnose-button" onclick="diagnoseErrors()" + jscontent="diagnose" jsdisplay="diagnose"></button> + <div class="error-code" jscontent="errorCode"></div> </div> </div> <div id="sub-frame-error">
diff --git a/chrome/browser/resources/downloads/compiled_resources.gyp b/chrome/browser/resources/downloads/compiled_resources.gyp index 5b2c777..56f946a 100644 --- a/chrome/browser/resources/downloads/compiled_resources.gyp +++ b/chrome/browser/resources/downloads/compiled_resources.gyp
@@ -8,10 +8,14 @@ 'variables': { 'depends': [ '../../../../ui/webui/resources/js/action_link.js', + '../../../../ui/webui/resources/js/assert.js', + '../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', '../../../../ui/webui/resources/js/cr.js', '../../../../ui/webui/resources/js/cr/ui.js', '../../../../ui/webui/resources/js/cr/ui/command.js', - '../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + '../../../../ui/webui/resources/js/cr/ui/focus_grid.js', + '../../../../ui/webui/resources/js/cr/ui/focus_row.js', + '../../../../ui/webui/resources/js/event_tracker.js', '../../../../ui/webui/resources/js/util.js', ], 'externs': ['<(CLOSURE_DIR)/externs/chrome_send_externs.js'],
diff --git a/chrome/browser/resources/downloads/downloads.js b/chrome/browser/resources/downloads/downloads.js index 5a3aeb40..54dca4f0 100644 --- a/chrome/browser/resources/downloads/downloads.js +++ b/chrome/browser/resources/downloads/downloads.js
@@ -156,7 +156,7 @@ /** * Determines if element should be focusable. - * @param {!Element} element + * @param {Element} element * @return {boolean} * @private */
diff --git a/chrome/browser/resources/extensions/extension_focus_manager.js b/chrome/browser/resources/extensions/extension_focus_manager.js index b220024..377744ca 100644 --- a/chrome/browser/resources/extensions/extension_focus_manager.js +++ b/chrome/browser/resources/extensions/extension_focus_manager.js
@@ -3,16 +3,16 @@ // found in the LICENSE file. cr.define('extensions', function() { - var FocusManager = cr.ui.FocusManager; - - function ExtensionFocusManager() { - FocusManager.disableMouseFocusOnButtons(); - } + /** + * @constructor + * @extends {cr.ui.FocusManager} + */ + function ExtensionFocusManager() {} cr.addSingletonGetter(ExtensionFocusManager); ExtensionFocusManager.prototype = { - __proto__: FocusManager.prototype, + __proto__: cr.ui.FocusManager.prototype, /** @override */ getFocusParent: function() {
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js index b8ab0d4..f540d33 100644 --- a/chrome/browser/resources/extensions/extension_list.js +++ b/chrome/browser/resources/extensions/extension_list.js
@@ -51,6 +51,7 @@ * prettifiedPath: (string|undefined), * recommendedInstall: boolean, * runtimeErrors: (Array.<RuntimeError>|undefined), + * showAllUrls: boolean, * suspiciousInstall: boolean, * terminated: boolean, * updateRequiredByPolicy: boolean, @@ -58,7 +59,6 @@ * views: Array.<{renderViewId: number, renderProcessId: number, * path: string, incognito: boolean, * generatedBackgroundPage: boolean}>, - * wantsAllUrls: boolean, * wantsErrorCollection: boolean, * wantsFileAccess: boolean, * warnings: (Array|undefined)}} @@ -133,10 +133,8 @@ if (idToOpenOptions && $(idToOpenOptions)) this.showEmbeddedExtensionOptions_(idToOpenOptions, true); - if (this.data_.extensions.length == 0) - this.classList.add('empty-extension-list'); - else - this.classList.remove('empty-extension-list'); + var noExtensions = this.data_.extensions.length == 0; + this.classList.toggle('empty-extension-list', noExtensions); }, /** @@ -260,7 +258,7 @@ // The 'allow on all urls' checkbox. This should only be visible if // active script restrictions are enabled. If they are not enabled, no // extensions should want all urls. - if (extension.wantsAllUrls) { + if (extension.showAllUrls) { var allUrls = node.querySelector('.all-urls-control'); allUrls.addEventListener('click', function(e) { chrome.send('extensionSettingsAllowOnAllUrls', @@ -567,20 +565,32 @@ if (scroll) this.scrollToNode_(extensionId); + // Add the options query string. Corner case: the 'options' query string // will clobber the 'id' query string if the options link is clicked when // 'id' is in the URL, or if both query strings are in the URL. uber.replaceState({}, '?options=' + extensionId); - extensions.ExtensionOptionsOverlay.getInstance(). - setExtensionAndShowOverlay(extensionId, - extension.name, - extension.icon); - + var overlay = extensions.ExtensionOptionsOverlay.getInstance(); + var shownCallback = function() { + // This overlay doesn't get focused automatically as <extensionoptions> + // is created after the overlay is shown. + if (cr.ui.FocusOutlineManager.forDocument(document).visible) + overlay.setInitialFocus(); + }; + overlay.setExtensionAndShowOverlay(extensionId, extension.name, + extension.icon, shownCallback); this.optionsShown_ = true; - $('overlay').addEventListener('cancelOverlay', function() { - this.optionsShown_ = false; - }.bind(this)); + + var self = this; + $('overlay').addEventListener('cancelOverlay', function f() { + self.optionsShown_ = false; + $('overlay').removeEventListener('cancelOverlay', f); + }); + + // TODO(dbeam): why do we need to focus <extensionoptions> before and + // after its showing animation? Makes very little sense to me. + overlay.setInitialFocus(); }, };
diff --git a/chrome/browser/resources/extensions/extension_options_overlay.js b/chrome/browser/resources/extensions/extension_options_overlay.js index 174e16e..07684a9 100644 --- a/chrome/browser/resources/extensions/extension_options_overlay.js +++ b/chrome/browser/resources/extensions/extension_options_overlay.js
@@ -40,6 +40,19 @@ this.showOverlay_ = showOverlay; }, + setInitialFocus: function() { + this.getExtensionOptions_().focus(); + }, + + /** + * @return {?Element} + * @private + */ + getExtensionOptions_: function() { + return $('extension-options-overlay-guest').querySelector( + 'extensionoptions'); + }, + /** * Handles a click on the close button. * @param {Event} event The click event. @@ -47,10 +60,7 @@ */ handleDismiss_: function(event) { this.setVisible_(false); - var extensionoptions = - $('extension-options-overlay-guest') - .querySelector('extensionoptions'); - + var extensionoptions = this.getExtensionOptions_(); if (extensionoptions) $('extension-options-overlay-guest').removeChild(extensionoptions); @@ -67,6 +77,8 @@ * @param {string} extensionName The name of the extension, which is used * as the header of the overlay. * @param {string} extensionIcon The URL of the extension's icon. + * @param {function():void} shownCallback A function called when + * showing completes. * @suppress {checkTypes} * TODO(vitalyp): remove the suppression after adding * chrome/renderer/resources/extensions/extension_options.js @@ -74,7 +86,8 @@ */ setExtensionAndShowOverlay: function(extensionId, extensionName, - extensionIcon) { + extensionIcon, + shownCallback) { var overlay = $('extension-options-overlay'); var overlayHeader = $('extension-options-overlay-header'); var overlayGuest = $('extension-options-overlay-guest'); @@ -121,13 +134,14 @@ // the overlay. It is calculated by multiplying the pythagorean distance // between old and the new size (in px) with a constant speed of // 0.25 ms/px. - var animationTime = 0.25 * Math.sqrt( - Math.pow(newWidth - oldWidth, 2) + - Math.pow(newHeight - oldHeight, 2)); + var loading = document.documentElement.classList.contains('loading'); + var animationTime = loading ? 0 : + 0.25 * Math.sqrt(Math.pow(newWidth - oldWidth, 2) + + Math.pow(newHeight - oldHeight, 2)); - if (animation) { + if (animation) animation.cancel(); - } + animation = overlay.animate([ {width: oldWidth + 'px', height: oldHeight + 'px'}, {width: newWidth + 'px', height: newHeight + 'px'} @@ -138,13 +152,19 @@ animation.onfinish = function(e) { animation = null; + // The <extensionoptions> element is ready to place back in the - // overlay. Make sure that it's sized to take up the full - // width/height of the overlay. + // overlay. Make sure that it's sized to take up the full width/height + // of the overlay. overlayGuest.style.position = ''; overlayGuest.style.left = ''; overlayGuest.style.width = newWidth + 'px'; overlayGuest.style.height = newHeight + 'px'; + + if (shownCallback) { + shownCallback(); + shownCallback = null; + } }; }.bind(this);
diff --git a/chrome/browser/resources/extensions/extensions.css b/chrome/browser/resources/extensions/extensions.css index 0224110..fc3a4bc 100644 --- a/chrome/browser/resources/extensions/extensions.css +++ b/chrome/browser/resources/extensions/extensions.css
@@ -3,7 +3,7 @@ * found in the LICENSE file. */ html.loading * { - transition-duration: 0 !important; + transition-duration: 0ms !important; } html:not(.focus-outline-visible) @@ -49,6 +49,10 @@ white-space: nowrap; } +#dev-controls .button-container button:not(:last-of-type) { + -webkit-margin-end: 5px; +} + #apps-developer-tools-promo { align-items: center; border-top: 1px solid #eee;
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html index 72bc6d18..3887401 100644 --- a/chrome/browser/resources/extensions/extensions.html +++ b/chrome/browser/resources/extensions/extensions.html
@@ -32,6 +32,7 @@ <script src="chrome://resources/js/cr/ui/drag_wrapper.js"></script> <script src="chrome://resources/js/cr/ui/focus_manager.js"></script> <script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script> +<script src="chrome://resources/js/cr/ui/node_utils.js"></script> <script src="chrome://resources/js/cr/ui/overlay.js"></script> <if expr="chromeos">
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js index 9c3bc1d9..65a0fc6 100644 --- a/chrome/browser/resources/extensions/extensions.js +++ b/chrome/browser/resources/extensions/extensions.js
@@ -374,18 +374,13 @@ /** * Sets the given overlay to show. This hides whatever overlay is currently * showing, if any. - * @param {HTMLElement} node The overlay page to show. If falsey, all overlays + * @param {HTMLElement} node The overlay page to show. If null, all overlays * are hidden. */ ExtensionSettings.showOverlay = function(node) { var pageDiv = $('extension-settings'); - if (node) { - pageDiv.style.width = window.getComputedStyle(pageDiv).width; - document.body.classList.add('no-scroll'); - } else { - document.body.classList.remove('no-scroll'); - pageDiv.style.width = ''; - } + pageDiv.style.width = node ? window.getComputedStyle(pageDiv).width : ''; + document.body.classList.toggle('no-scroll', !!node); var currentlyShowingOverlay = ExtensionSettings.getCurrentOverlay(); if (currentlyShowingOverlay) { @@ -394,8 +389,11 @@ } if (node) { - if (document.activeElement != document.body) - document.activeElement.blur(); + var lastFocused = document.activeElement; + $('overlay').addEventListener('cancelOverlay', function f() { + lastFocused.focus(); + $('overlay').removeEventListener('cancelOverlay', f); + }); node.classList.add('showing'); } @@ -405,10 +403,27 @@ } $('overlay').hidden = !node; + + if (node) + ExtensionSettings.focusOverlay(); + uber.invokeMethodOnParent(node ? 'beginInterceptingEvents' : 'stopInterceptingEvents'); }; + ExtensionSettings.focusOverlay = function() { + var currentlyShowingOverlay = ExtensionSettings.getCurrentOverlay(); + assert(currentlyShowingOverlay); + + if (cr.ui.FocusOutlineManager.forDocument(document).visible) + cr.ui.setInitialFocus(currentlyShowingOverlay); + + if (!currentlyShowingOverlay.contains(document.activeElement)) { + // Make sure focus isn't stuck behind the overlay. + document.activeElement.blur(); + } + }; + /** * Utility function to find the width of various UI strings and synchronize * the width of relevant spans. This is crucial for making sure the
diff --git a/chrome/browser/resources/gaia_auth/main.js b/chrome/browser/resources/gaia_auth/main.js index 914bed5..dc1ebe4 100644 --- a/chrome/browser/resources/gaia_auth/main.js +++ b/chrome/browser/resources/gaia_auth/main.js
@@ -36,6 +36,15 @@ ]; /** + * Allowed origins of the hosting page. + * @type {Array.<string>} + */ +Authenticator.ALLOWED_PARENT_ORIGINS = [ + 'chrome://oobe', + 'chrome://chrome-signin' +]; + +/** * Singleton getter of Authenticator. * @return {Object} The singleton instance of Authenticator. */ @@ -73,23 +82,32 @@ GAIA_URL: 'https://accounts.google.com/', GAIA_PAGE_PATH: 'ServiceLogin?skipvpage=true&sarp=1&rm=hide', - PARENT_PAGE: 'chrome://oobe/', SERVICE_ID: 'chromeoslogin', CONTINUE_URL: Authenticator.THIS_EXTENSION_ORIGIN + '/success.html', CONSTRAINED_FLOW_SOURCE: 'chrome', initialize: function() { - var params = getUrlSearchParams(location.search); - this.parentPage_ = params.parentPage || this.PARENT_PAGE; + var handleInitializeMessage = function(e) { + if (Authenticator.ALLOWED_PARENT_ORIGINS.indexOf(e.origin) == -1) { + console.error('Unexpected parent message, origin=' + e.origin); + return; + } + window.removeEventListener('message', handleInitializeMessage); + + var params = e.data; + params.parentPage = e.origin; + this.initializeFromParent_(params); + this.onPageLoad_(); + }.bind(this); + + document.addEventListener('DOMContentLoaded', function() { + window.addEventListener('message', handleInitializeMessage); + }); + }, + + initializeFromParent_: function(params) { + this.parentPage_ = params.parentPage; this.gaiaUrl_ = params.gaiaUrl || this.GAIA_URL; - - // Sanitize Gaia url before continuing. - var scheme = extractProtocol(this.gaiaUrl_); - if (scheme != 'https:' && scheme != 'http:') { - console.error('Bad Gaia URL, url=' + this.gaiaURL_); - return; - } - this.gaiaPath_ = params.gaiaPath || this.GAIA_PAGE_PATH; this.inputLang_ = params.hl; this.inputEmail_ = params.email; @@ -108,8 +126,6 @@ this.assumeLoadedOnLoadEvent_ = this.gaiaPath_.indexOf('ServiceLogin') !== 0 || this.service_ !== 'chromeoslogin'; - - document.addEventListener('DOMContentLoaded', this.onPageLoad_.bind(this)); }, isGaiaMessage_: function(msg) {
diff --git a/chrome/browser/resources/gaia_auth/manifest.json b/chrome/browser/resources/gaia_auth/manifest.json index ecb4550..e62cc45 100644 --- a/chrome/browser/resources/gaia_auth/manifest.json +++ b/chrome/browser/resources/gaia_auth/manifest.json
@@ -17,7 +17,7 @@ "all_frames": true } ], - "content_security_policy": "default-src 'self'; script-src 'self'; frame-src *; style-src 'self' 'unsafe-inline'", + "content_security_policy": "default-src 'self'; script-src 'self'; frame-src 'self' http: https:; style-src 'self'", "description": "GAIA Component Extension", "incognito": "split", "web_accessible_resources": [
diff --git a/chrome/browser/resources/gaia_auth/manifest_keyboard.json b/chrome/browser/resources/gaia_auth/manifest_keyboard.json index 7718c0b..676bb98 100644 --- a/chrome/browser/resources/gaia_auth/manifest_keyboard.json +++ b/chrome/browser/resources/gaia_auth/manifest_keyboard.json
@@ -25,7 +25,7 @@ "all_frames": true } ], - "content_security_policy": "default-src 'self'; script-src 'self'; frame-src *; style-src 'self' 'unsafe-inline'", + "content_security_policy": "default-src 'self'; script-src 'self'; frame-src 'self' http: https:; style-src 'self'", "description": "GAIA Component Extension", "incognito": "split", "web_accessible_resources": [
diff --git a/chrome/browser/resources/gaia_auth/offline.css b/chrome/browser/resources/gaia_auth/offline.css index 92b5b03..5bf69db 100644 --- a/chrome/browser/resources/gaia_auth/offline.css +++ b/chrome/browser/resources/gaia_auth/offline.css
@@ -167,14 +167,14 @@ overflow: visible; } .g-button:hover { - -webkit-transition: all 0; + -webkit-transition: all 0ms; background-color: #f8f8f8; background-image: linear-gradient(to bottom, #f8f8f8, #f1f1f1); border: 1px solid #c6c6c6; box-shadow: 0 1px 1px rgba(0,0,0,0.1); color: #333; text-decoration: none; - transition: all 0; + transition: all 0ms; } .g-button:active { background-color: #f6f6f6;
diff --git a/chrome/browser/resources/gaia_auth/offline.js b/chrome/browser/resources/gaia_auth/offline.js index 7b4da1f5..dcc153f 100644 --- a/chrome/browser/resources/gaia_auth/offline.js +++ b/chrome/browser/resources/gaia_auth/offline.js
@@ -6,9 +6,11 @@ * @fileoverview Offline login implementation. */ -function load() { - var params = getUrlSearchParams(location.search); - +/** + * Initialize the offline page. + * @param {Object} params Intialization params passed from parent page. + */ +function load(params) { // Setup localized strings. $('sign-in-title').textContent = decodeURIComponent(params['stringSignIn']); $('email-label').textContent = decodeURIComponent(params['stringEmail']); @@ -59,4 +61,26 @@ window.parent.postMessage({'method': 'loginUILoaded'}, 'chrome://oobe/'); } -document.addEventListener('DOMContentLoaded', load); +/** + * Handles initialization message from parent page. + * @param {MessageEvent} e + */ +function handleInitializeMessage(e) { + var ALLOWED_PARENT_ORIGINS = [ + 'chrome://oobe', + 'chrome://chrome-signin' + ]; + + if (ALLOWED_PARENT_ORIGINS.indexOf(e.origin) == -1) + return; + + window.removeEventListener('message', handleInitializeMessage); + + var params = e.data; + params.parentPage = e.origin; + load(params); +} + +document.addEventListener('DOMContentLoaded', function() { + window.addEventListener('message', handleInitializeMessage); +});
diff --git a/chrome/browser/resources/gaia_auth/util.js b/chrome/browser/resources/gaia_auth/util.js index 039465ab..1ad55136 100644 --- a/chrome/browser/resources/gaia_auth/util.js +++ b/chrome/browser/resources/gaia_auth/util.js
@@ -12,31 +12,6 @@ } /** - * Extract query params from given search string of an URL. - * @param {string} search The search portion of an URL to extract params. - * @return {Object} The key value pairs of the extracted params. - */ -function getUrlSearchParams(search) { - var params = {}; - - if (search) { - // Strips leading '?' - search = search.substring(1); - var pairs = search.split('&'); - for (var i = 0; i < pairs.length; ++i) { - var pair = pairs[i].split('='); - if (pair.length == 2) { - params[pair[0]] = decodeURIComponent(pair[1]); - } else { - params[pair] = true; - } - } - } - - return params; -} - -/** * Creates a new URL which is the old URL with a GET param of key=value. * Copied from ui/webui/resources/js/util.js. * @param {string} url The base URL. There is not sanity checking on the URL so @@ -72,15 +47,3 @@ a.href = url; return a.hostname; } - -/** - * Extract protocol from an URL. - * @param {string} url An URL string. - * @return {string} The protocol of the URL. - */ -function extractProtocol(url) { - var a = document.createElement('a'); - a.href = url; - return a.protocol; -} -
diff --git a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js index b33c347..aedb60be 100644 --- a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js +++ b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
@@ -110,6 +110,12 @@ __proto__: cr.EventTarget.prototype, /** + * Auth extension params + * @type {Object} + */ + authParams_: {}, + + /** * An url to use with {@code reload}. * @type {?string} * @private @@ -237,7 +243,7 @@ * invoked with a credential object. */ load: function(authMode, data, successCallback) { - var params = []; + var params = {}; var populateParams = function(nameList, values) { if (!values) @@ -246,14 +252,13 @@ for (var i in nameList) { var name = nameList[i]; if (values[name]) - params.push(name + '=' + encodeURIComponent(values[name])); + params[name] = values[name]; } }; populateParams(SUPPORTED_PARAMS, data); populateParams(LOCALIZED_STRING_PARAMS, data.localizedStrings); - params.push('parentPage=' + encodeURIComponent(window.location.origin)); - params.push('needPassword=1'); + params['needPassword'] = true; var url; switch (authMode) { @@ -262,23 +267,29 @@ break; case AuthMode.DESKTOP: url = AUTH_URL; - params.push('desktopMode=1'); + params['desktopMode'] = true; break; default: url = AUTH_URL; } - url += '?' + params.join('&'); - this.frame_.src = url; + this.authParams_ = params; this.reloadUrl_ = url; this.successCallback_ = successCallback; - this.authFlow = AuthFlow.GAIA; + + this.reload(); }, /** * Reloads the auth extension. */ reload: function() { + var sendParamsOnLoad = function() { + this.frame_.removeEventListener('load', sendParamsOnLoad); + this.frame_.contentWindow.postMessage(this.authParams_, AUTH_URL_BASE); + }.bind(this); + + this.frame_.addEventListener('load', sendParamsOnLoad); this.frame_.src = this.reloadUrl_; this.authFlow = AuthFlow.GAIA; },
diff --git a/chrome/browser/resources/help/help.js b/chrome/browser/resources/help/help.js index 5407b6a..b213a750 100644 --- a/chrome/browser/resources/help/help.js +++ b/chrome/browser/resources/help/help.js
@@ -19,7 +19,6 @@ PageManager.registerOverlay(help.ChannelChangePage.getInstance(), HelpPage.getInstance()); } - cr.ui.FocusManager.disableMouseFocusOnButtons(); PageManager.addObserver(new uber.PageManagerObserver()); PageManager.initialize(HelpPage.getInstance()); uber.onContentFrameLoaded();
diff --git a/chrome/browser/resources/help_app/OWNERS b/chrome/browser/resources/help_app/OWNERS index c78d452..8bba85f 100644 --- a/chrome/browser/resources/help_app/OWNERS +++ b/chrome/browser/resources/help_app/OWNERS
@@ -1,2 +1,5 @@ dpolukhin@chromium.org nkostylev@chromium.org +cnwan@chromium.org +cylee@chromium.org +davidyu@chromium.org
diff --git a/chrome/browser/resources/md_settings/md_settings.html b/chrome/browser/resources/md_settings/md_settings.html new file mode 100644 index 0000000..2b65be8 --- /dev/null +++ b/chrome/browser/resources/md_settings/md_settings.html
@@ -0,0 +1,17 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <title>Settings</title> + <link rel="import" + href="chrome://resources/polymer/paper-button/paper-button.html"> +</head> +<body> + <header> + <h1>Settings</h1> + </header> + <div class="main"> + <paper-button id="manage-button" raised>Manage</paper-button> + </div> +</body> +</html>
diff --git a/chrome/browser/resources/ntp4/apps_page.css b/chrome/browser/resources/ntp4/apps_page.css index fc9c61b..de0f83a 100644 --- a/chrome/browser/resources/ntp4/apps_page.css +++ b/chrome/browser/resources/ntp4/apps_page.css
@@ -23,7 +23,7 @@ /* Active gets applied right before .suppress-active, so to avoid flicker * we need to make the scale go back to normal without an animation. */ .app-contents.suppress-active { - -webkit-transition-duration: 0; + -webkit-transition-duration: 0ms; } .app-contents > span {
diff --git a/chrome/browser/resources/ntp4/apps_page.js b/chrome/browser/resources/ntp4/apps_page.js index 5420f19..6c7ffae 100644 --- a/chrome/browser/resources/ntp4/apps_page.js +++ b/chrome/browser/resources/ntp4/apps_page.js
@@ -49,10 +49,7 @@ this.launch_.addEventListener('activate', this.onLaunch_.bind(this)); menu.appendChild(cr.ui.MenuItem.createSeparator()); - if (loadTimeData.getBoolean('enableNewBookmarkApps')) - this.launchRegularTab_ = this.appendMenuItem_('applaunchtypetab'); - else - this.launchRegularTab_ = this.appendMenuItem_('applaunchtyperegular'); + this.launchRegularTab_ = this.appendMenuItem_('applaunchtyperegular'); this.launchPinnedTab_ = this.appendMenuItem_('applaunchtypepinned'); if (loadTimeData.getBoolean('enableNewBookmarkApps') || !cr.isMac) this.launchNewWindow_ = this.appendMenuItem_('applaunchtypewindow'); @@ -131,14 +128,14 @@ this.launch_.textContent = app.appData.title; - var launchTypeRegularTab = this.launchRegularTab_; + var launchTypeWindow = this.launchNewWindow_; this.forAllLaunchTypes_(function(launchTypeButton, id) { launchTypeButton.disabled = false; launchTypeButton.checked = app.appData.launch_type == id; - // If bookmark apps are enabled, only show the "Open as tab" button. + // If bookmark apps are enabled, only show the "Open as window" button. launchTypeButton.hidden = app.appData.packagedApp || (loadTimeData.getBoolean('enableNewBookmarkApps') && - launchTypeButton != launchTypeRegularTab); + launchTypeButton != launchTypeWindow); }); this.launchTypeMenuSeparator_.hidden = app.appData.packagedApp; @@ -171,8 +168,8 @@ // When bookmark apps are enabled, hosted apps can only toggle between // open as window and open as tab. if (loadTimeData.getBoolean('enableNewBookmarkApps')) { - targetLaunchType = this.launchRegularTab_.checked ? - this.launchNewWindow_ : this.launchRegularTab_; + targetLaunchType = this.launchNewWindow_.checked ? + this.launchRegularTab_ : this.launchNewWindow_; } this.forAllLaunchTypes_(function(launchTypeButton, id) { if (launchTypeButton == targetLaunchType) {
diff --git a/chrome/browser/resources/ntp4/new_tab.css b/chrome/browser/resources/ntp4/new_tab.css index 187059f..de911ba9 100644 --- a/chrome/browser/resources/ntp4/new_tab.css +++ b/chrome/browser/resources/ntp4/new_tab.css
@@ -299,8 +299,8 @@ #trash { -webkit-padding-start: 10px; - -webkit-transition: top 200ms, opacity 0; - -webkit-transition-delay: 0, 200ms; + -webkit-transition: top 200ms, opacity 0ms; + -webkit-transition-delay: 0ms, 200ms; color: #222; height: 100%; opacity: 0; @@ -316,8 +316,8 @@ } #footer.showing-trash-mode #trash { - -webkit-transition-delay: 0, 0; - -webkit-transition-duration: 0, 200ms; + -webkit-transition-delay: 0ms, 0ms; + -webkit-transition-duration: 0ms, 200ms; opacity: 0.75; top: 0; } @@ -433,7 +433,7 @@ /* In trash mode, hide the menus and web store link. */ #footer.showing-trash-mode .menu-container { - -webkit-transition-delay: 0; + -webkit-transition-delay: 0ms; opacity: 0; visibility: hidden; }
diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js index e77f4e8a..05aeabf 100644 --- a/chrome/browser/resources/ntp4/new_tab.js +++ b/chrome/browser/resources/ntp4/new_tab.js
@@ -298,8 +298,6 @@ startTime = Date.now(); }); - - cr.ui.FocusManager.disableMouseFocusOnButtons(); } /**
diff --git a/chrome/browser/resources/options/autofill_options_list.js b/chrome/browser/resources/options/autofill_options_list.js index 902fdcd..e62ff099 100644 --- a/chrome/browser/resources/options/autofill_options_list.js +++ b/chrome/browser/resources/options/autofill_options_list.js
@@ -210,17 +210,23 @@ if (this.isPlaceholder) { // It is important that updateIndex is done before validateAndSave. // Otherwise we can not be sure about AddRow index. - this.list.dataModel.updateIndex(i); + this.list.ignoreChangeEvents(function() { + this.list.dataModel.updateIndex(i); + }.bind(this)); this.list.validateAndSave(i, 0, value); } else { this.list.validateAndSave(i, 1, value); } } else { // Reject empty values and duplicates. - if (!this.isPlaceholder) - this.list.dataModel.splice(i, 1); - else + if (!this.isPlaceholder) { + this.list.ignoreChangeEvents(function() { + this.list.dataModel.splice(i, 1); + }.bind(this)); + this.list.selectIndexWithoutFocusing(i); + } else { this.clearValue_(); + } } }, }; @@ -444,7 +450,10 @@ * @param {string} value The value of the item to insert. */ validateAndSave: function(index, remove, value) { - this.dataModel.splice(index, remove, value); + this.ignoreChangeEvents(function() { + this.dataModel.splice(index, remove, value); + }.bind(this)); + this.selectIndexWithoutFocusing(index); }, }; @@ -515,8 +524,6 @@ while (this.validationPromiseResolvers_.length) { this.validationPromiseResolvers_.pop()(); } - // List has been repopulated. Focus the placeholder. - this.focusPlaceholder(); } },
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 86a5adfe..de4235c 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html
@@ -574,7 +574,7 @@ <section id="easy-unlock-section" guest-visibility="hidden" hidden> <h3 i18n-content="easyUnlockSectionTitle"></h3> <!-- Options shown when the user has not set up Easy Unlock --> - <div id="easy-unlock-setup" hidden> + <div id="easy-unlock-disabled" hidden> <div class="settings-row"> <span i18n-content="easyUnlockSetupIntro"></span> <a target="_blank" i18n-content="learnMore" @@ -584,7 +584,7 @@ i18n-content="easyUnlockSetupButton"></button> </div> <!-- Options shown when the user has set up Easy Unlock --> - <div id="easy-unlock-enable" hidden> + <div id="easy-unlock-enabled" hidden> <div class="settings-row"> <span i18n-content="easyUnlockDescription"></span> <a target="_blank" i18n-content="learnMore"
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index b0ee2354..8ed022f 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js
@@ -1097,14 +1097,15 @@ }, /** - * Update the UI depending on whether the current profile has a pairing for - * Easy Unlock. - * @param {boolean} hasPairing True if the current profile has a pairing. + * Update the UI depending on whether Easy Unlock is enabled for the current + * profile. + * @param {boolean} isEnabled True if the feature is enabled for the current + * profile. */ - updateEasyUnlock_: function(hasPairing) { - $('easy-unlock-setup').hidden = hasPairing; - $('easy-unlock-enable').hidden = !hasPairing; - if (!hasPairing && EasyUnlockTurnOffOverlay.getInstance().visible) { + updateEasyUnlock_: function(isEnabled) { + $('easy-unlock-disabled').hidden = isEnabled; + $('easy-unlock-enabled').hidden = !isEnabled; + if (!isEnabled && EasyUnlockTurnOffOverlay.getInstance().visible) { EasyUnlockTurnOffOverlay.dismiss(); } },
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js index 94538be..36a6e8e 100644 --- a/chrome/browser/resources/options/chromeos/internet_detail.js +++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -7,8 +7,7 @@ // NOTE(stevenjb): This code is in the process of being converted to be // compatible with the networkingPrivate extension API: // * The network property dictionaries are being converted to use ONC values. -// * chrome.send calls will be replaced with an API object that simulates the -// networkingPrivate API. See network_config.js. +// * chrome.send calls will be replaced with chrome.networkingPrivate calls. // See crbug.com/279351 for more info. cr.define('options.internet', function() {
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js index f4ffbcc3..c2db84a 100644 --- a/chrome/browser/resources/options/inline_editable_list.js +++ b/chrome/browser/resources/options/inline_editable_list.js
@@ -85,7 +85,8 @@ /** @override */ selectionChanged: function() { - this.updateEditState(); + if (!this.parentNode.ignoreChangeEvents_) + this.updateEditState(); }, /** @@ -576,6 +577,15 @@ __proto__: DeletableItemList.prototype, /** + * Whether to ignore list change events. + * Used to modify the list without processing selection change and lead + * change events. + * @type {boolean} + * @private + */ + ignoreChangeEvents_: false, + + /** * Focuses the input element of the placeholder if true. * @type {boolean} * @private @@ -624,6 +634,9 @@ /** @override */ handleLeadChange: function(e) { + if (this.ignoreChangeEvents_) + return; + DeletableItemList.prototype.handleLeadChange.call(this, e); var focusedColumnIndex = -1; @@ -662,6 +675,54 @@ }, /** + * Execute |callback| with list change events disabled. Selection change and + * lead change events will not be processed. + * @param {!Function} callback The function to execute. + * @protected + */ + ignoreChangeEvents: function(callback) { + assert(!this.ignoreChangeEvents_); + this.ignoreChangeEvents_ = true; + callback(); + this.ignoreChangeEvents_ = false; + }, + + /** + * Set the selected index without changing the focused element on the page. + * Used to change the selected index when the list doesn't have focus (and + * doesn't want to take focus). + * @param {number} index The index to select. + */ + selectIndexWithoutFocusing: function(index) { + // Remove focusability from old item. + var oldItem = this.getListItemByIndex(this.selectionModel.leadIndex) || + this.getInitialFocusableItem(); + if (oldItem) { + oldItem.setEditableValuesFocusable(false); + oldItem.setStaticValuesFocusable(false); + oldItem.setCloseButtonFocusable(false); + oldItem.lead = false; + } + + // Select the new item. + this.ignoreChangeEvents(function() { + this.selectionModel.selectedIndex = index; + }.bind(this)); + + // Add focusability to new item. + var newItem = this.getListItemByIndex(index); + if (newItem) { + if (newItem.isPlaceholder) + newItem.setEditableValuesFocusable(true); + else + newItem.setStaticValuesFocusable(true); + + newItem.setCloseButtonFocusable(true); + newItem.lead = true; + } + }, + + /** * Focus the placeholder's first input field. * Should only be called immediately after the list has been repopulated. */
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js index 7b46bec..e060024 100644 --- a/chrome/browser/resources/options/options.js +++ b/chrome/browser/resources/options/options.js
@@ -239,7 +239,6 @@ CertificateManager.getInstance()); } - cr.ui.FocusManager.disableMouseFocusOnButtons(); OptionsFocusManager.getInstance().initialize(); Preferences.getInstance().initialize(); ResetProfileSettingsBanner.getInstance().initialize();
diff --git a/chrome/browser/resources/pdf/index-material.css b/chrome/browser/resources/pdf/index-material.css index f38941a..d42bdef 100644 --- a/chrome/browser/resources/pdf/index-material.css +++ b/chrome/browser/resources/pdf/index-material.css
@@ -52,8 +52,9 @@ } #plugin { + height: 100%; position: fixed; - top: 56px; + width: 100%; z-index: 1; }
diff --git a/chrome/browser/resources/pdf/index.css b/chrome/browser/resources/pdf/index.css index ed5a4ba..06ca8fc2 100644 --- a/chrome/browser/resources/pdf/index.css +++ b/chrome/browser/resources/pdf/index.css
@@ -34,7 +34,9 @@ } #plugin { + height: 100%; position: fixed; + width: 100%; z-index: 1; }
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index c1c9931..c6df1a1 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js
@@ -86,7 +86,6 @@ this.passwordScreen_.addEventListener('password-submitted', this.onPasswordSubmitted_.bind(this)); this.errorScreen_ = $('error-screen'); - this.toolbarHeight_ = this.isMaterial_ ? $('pdf-toolbar').clientHeight : 0; this.bookmarksPane = $('bookmarks-pane'); // Create the viewport. @@ -95,8 +94,7 @@ this.viewportChanged_.bind(this), this.beforeZoom_.bind(this), this.afterZoom_.bind(this), - getScrollbarWidth(), - this.toolbarHeight_); + getScrollbarWidth()); // Create the plugin object dynamically so we can set its src. The plugin // element is sized to fill the entire window and is set to be fixed // positioning, acting as a viewport. The plugin renders into this viewport @@ -108,9 +106,6 @@ this.plugin_.type = 'application/x-google-chrome-pdf'; this.plugin_.addEventListener('message', this.handlePluginMessage_.bind(this), false); - this.plugin_.style.height = - (window.innerHeight - this.toolbarHeight_) + 'px'; - this.plugin_.style.width = window.innerWidth + 'px'; if (this.isMaterial_) this.plugin_.setAttribute('is-material', ''); @@ -580,16 +575,6 @@ * A callback that's called after the viewport changes. */ viewportChanged_: function() { - var hasScrollbars = this.viewport_.documentHasScrollbars(); - var scrollbarWidth = this.viewport_.scrollbarWidth; - var verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0; - var horizontalScrollbarWidth = - hasScrollbars.horizontal ? scrollbarWidth : 0; - this.plugin_.style.width = - (window.innerWidth - verticalScrollbarWidth) + 'px'; - this.plugin_.style.height = (window.innerHeight - - horizontalScrollbarWidth - this.toolbarHeight_) + 'px'; - if (!this.documentDimensions_) return; @@ -604,6 +589,11 @@ } // Offset the toolbar position so that it doesn't move if scrollbars appear. + var hasScrollbars = this.viewport_.documentHasScrollbars(); + var scrollbarWidth = this.viewport_.scrollbarWidth; + var verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0; + var horizontalScrollbarWidth = + hasScrollbars.horizontal ? scrollbarWidth : 0; var toolbarRight = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth); var toolbarBottom = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth); toolbarRight -= verticalScrollbarWidth;
diff --git a/chrome/browser/resources/pdf/pdf_scripting_api.js b/chrome/browser/resources/pdf/pdf_scripting_api.js index 03f14de6..c0b06d19 100644 --- a/chrome/browser/resources/pdf/pdf_scripting_api.js +++ b/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -263,6 +263,8 @@ iframe.setAttribute( 'src', 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html?' + src); + // Prevent the frame from being tab-focusable. + iframe.setAttribute('tabindex', '-1'); var client = new PDFScriptingAPI(window); iframe.onload = function() { client.setPlugin(iframe.contentWindow);
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js index 981555f..29b86ce 100644 --- a/chrome/browser/resources/pdf/viewport.js +++ b/chrome/browser/resources/pdf/viewport.js
@@ -24,15 +24,13 @@ * @param {Function} beforeZoomCallback is run before a change in zoom * @param {Function} afterZoomCallback is run after a change in zoom * @param {number} scrollbarWidth the width of scrollbars on the page - * @param {number} yPos the offset of the viewport from the top of the window */ function Viewport(window, sizer, viewportChangedCallback, beforeZoomCallback, afterZoomCallback, - scrollbarWidth, - yPos) { + scrollbarWidth) { this.window_ = window; this.sizer_ = sizer; this.viewportChangedCallback_ = viewportChangedCallback; @@ -44,7 +42,6 @@ this.pageDimensions_ = []; this.scrollbarWidth_ = scrollbarWidth; this.fittingType_ = Viewport.FittingType.NONE; - this.yPos = yPos; window.addEventListener('scroll', this.updateViewport_.bind(this)); window.addEventListener('resize', this.resize_.bind(this)); @@ -140,7 +137,7 @@ this.sizer_.style.width = this.documentDimensions_.width * this.zoom_ + 'px'; this.sizer_.style.height = - this.documentDimensions_.height * this.zoom_ + this.yPos + 'px'; + this.documentDimensions_.height * this.zoom_ + 'px'; } },
diff --git a/chrome/browser/resources/plugin_metadata/plugins_mac.json b/chrome/browser/resources/plugin_metadata/plugins_mac.json index 1a91f4a..1f1195f 100644 --- a/chrome/browser/resources/plugin_metadata/plugins_mac.json +++ b/chrome/browser/resources/plugin_metadata/plugins_mac.json
@@ -1,5 +1,5 @@ { - "x-version": 7, + "x-version": 8, "google-talk": { "mime_types": [ ], @@ -115,9 +115,9 @@ ], "versions": [ { - "version": "16.0.0.235", + "version": "16.0.0.305", "status": "requires_authorization", - "reference": "https://helpx.adobe.com/security/products/flash-player/apsb14-27.html" + "reference": "https://helpx.adobe.com/security/products/flash-player/apsb15-04.html" } ], "lang": "en-US",
diff --git a/chrome/browser/resources/plugin_metadata/plugins_win.json b/chrome/browser/resources/plugin_metadata/plugins_win.json index 2157178..579a402 100644 --- a/chrome/browser/resources/plugin_metadata/plugins_win.json +++ b/chrome/browser/resources/plugin_metadata/plugins_win.json
@@ -1,5 +1,5 @@ { - "x-version": 16, + "x-version": 17, "google-talk": { "mime_types": [ ], @@ -137,9 +137,9 @@ ], "versions": [ { - "version": "16.0.0.235", + "version": "16.0.0.305", "status": "requires_authorization", - "reference": "https://helpx.adobe.com/security/products/flash-player/apsb14-27.html" + "reference": "https://helpx.adobe.com/security/products/flash-player/apsb15-04.html" } ], "lang": "en-US",
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.css b/chrome/browser/resources/security_warnings/interstitial_v2.css index 7c1ee10..78bd05d8 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2.css +++ b/chrome/browser/resources/security_warnings/interstitial_v2.css
@@ -14,7 +14,7 @@ body { background-color: #f7f7f7; - color: #585858; + color: #646464; } body.safe-browsing { @@ -50,6 +50,10 @@ box-shadow: 0 1px 3px rgba(0, 0, 0, .50); } +#debugging { + overflow: auto; +} + .debugging-content { line-height: 1em; margin-bottom: 0; @@ -69,18 +73,33 @@ margin-top: 20px; } +#details-button { + background: inherit; + border: 0; + float: none; + margin: -6px 0 0; + padding: 0; + text-decoration: underline; +} + +#details-button:hover { + box-shadow: inherit; +} + #error-code { color: black; + font-size: .825em; opacity: .35; text-transform: uppercase; } #error-debugging-info { font-size: 0.8em; + overflow: auto; } h1 { - color: #585858; + color: #333; font-size: 1.6em; font-weight: normal; line-height: 1.25em; @@ -97,6 +116,7 @@ } html { + -webkit-text-size-adjust: 100%; font-size: 125%; } @@ -147,13 +167,11 @@ } .safe-browsing button { - background-color: rgb(206, 52, 38); - border: 1px solid white; + background-color: rgba(255, 255, 255, .15); } .safe-browsing button:active { - background-color: rgb(206, 52, 38); - border-color: rgba(255, 255, 255, .6); + background-color: rgba(255, 255, 255, .25); } .safe-browsing button:hover { @@ -207,7 +225,7 @@ width: 14px; } -.styled-checkbox label::after { +.styled-checkbox .checkbox-tick { background: transparent; border: 2px solid white; border-right-width: 0; @@ -222,7 +240,7 @@ width: 9px; } -.styled-checkbox input[type=checkbox]:checked + label::after { +.styled-checkbox input[type=checkbox]:checked ~ .checkbox-tick { opacity: 1; } @@ -238,11 +256,14 @@ } } -@media (max-width: 400px) { +@media (max-width: 420px) { button, - [dir='rtl'] button { + [dir='rtl'] button, + .small-link { float: none; - font-size: 1em; + font-size: .825em; + font-weight: 400; + text-transform: uppercase; width: 100%; } @@ -256,7 +277,6 @@ #details-button { display: block; - padding-top: 14px; text-align: center; width: 100%; } @@ -272,8 +292,345 @@ .nav-wrapper { margin-top: 30px; } +} + +/** + * Mobile specific styling. + * Navigation buttons are anchored to the bottom of the screen. + * Details message replaces the top content in its own scrollable area. + */ + +@media (max-width: 420px) and (orientation: portrait) { + #details-button { + border: 0; + margin: 20px 0 0; + } +} + +/* Fixed nav. */ +@media (min-width: 300px) and (max-width: 420px) and + (min-height: 400px) and (orientation:portrait), + (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and + (max-height: 420px) and (orientation:landscape) { + + body:not(.offline) .nav-wrapper { + background: #f7f7f7; + bottom: 0; + left: 0; + position: fixed; + z-index: 1; + } + + body.safe-browsing .nav-wrapper { + background: rgb(206, 52, 38); + } +} + +@media (max-width: 420px) and (orientation: portrait), + (max-width: 736px) and (max-height: 420px) and (orientation: landscape) { + body { + margin: 0 auto; + } + + button, + [dir='rtl'] button, + button.small-link { + font-family: Roboto-Regular,Helvetica; + font-size: .933em; + font-weight: 600; + text-transform: uppercase; + } + + .nav-wrapper { + box-sizing: border-box; + padding: 16px 24px 8px; + width: 100%; + } + + #details { + box-sizing: border-box; + height: auto; + margin: 0; + opacity: 1; + transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1); + } + + #details.hidden, + #main-content.hidden { + display: block; + height: 0; + opacity: 0; + overflow: hidden; + } + + #details-button { + height: 48px; + } + + h1 { + font-size: 1.5em; + margin-bottom: 8px; + } + + .icon { + margin-bottom: 12px; + } + + .interstitial-wrapper { + box-sizing: border-box; + margin: 24px 0 12px; + max-width: initial; + overflow: auto; + padding: 0 24px; + position: relative; + } + + .interstitial-wrapper p { + font-size: .95em; + line-height: 1.61em; + margin-top: 8px; + } + + #main-content { + margin: 0; + transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1); + } .small-link { + border: 0; + } + + .suggested-left > #control-buttons, + .suggested-right > #control-buttons { + float: none; + margin: 0; + } +} + +@media (min-height: 400px) and (orientation:portrait) { + body:not(.safe-browsing-has-checkbox):not(.offline) .interstitial-wrapper { + margin-bottom: 145px; + } +} + +@media (min-height: 299px) and (orientation:portrait) { + .nav-wrapper { + padding-bottom: 16px; + } +} + +@media (min-height: 405px) and (orientation:portrait) { + .icon { + margin-bottom: 24px; + } + + .interstitial-wrapper { + margin-top: 64px; + } +} + +@media (min-height: 480px) and (max-width: 420px) and (orientation: portrait), + (min-height: 338px) and (max-height: 420px) and (max-width: 736px) and + (orientation: landscape) { + .icon { + margin-bottom: 24px; + } + + .nav-wrapper { + padding: 16px 24px 24px; + } +} + +@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) { + :not(.safe-browsing-has-checkbox) .interstitial-wrapper { + margin-top: 96px; + } +} + +/* Phablet sizing */ +@media (min-width: 375px) and (min-height: 641px) and + (max-width: 414px) and (orientation: portrait) { + button, + [dir='rtl'] button, + .small-link { font-size: 1em; + height: 40px; + } + + body:not(.neterror) .icon { + height: 80px; + width: 80px; + } + + #details-button { + margin-top: 28px; + } + + h1 { + font-size: 1.7em; + } + + .icon { + margin-bottom: 28px; + } + + .interstitial-wrapper { + padding: 28px; + } + + .interstitial-wrapper p { + font-size: 1.05em; + } + + .nav-wrapper { + padding: 28px; + } + + .neterror .icon { + height: 80px; + width: 65.6px; + } +} + +@media (min-width: 420px) and (max-width: 736px) and + (min-height: 240px) and (max-height: 298px) and + (orientation:landscape) { + body:not(.neterror) .icon { + height: 50px; + width: 50px; + } + + .icon { + padding-top: 0; + } + + .interstitial-wrapper { + margin-top: 16px; + } + + .nav-wrapper { + padding: 0 24px 8px; + } +} + +@media (min-width: 420px) and (max-width: 736px) and + (min-height: 240px) and (max-height: 420px) and + (orientation:landscape) { + #details-button { + margin: 0; + } + + .interstitial-wrapper { + margin-bottom: 70px; + } + + .nav-wrapper { + margin-top: 0; + } + + #malware-opt-in { + margin-top: 0; + } + + #reload-button, + #primary-button { + margin: 6px 0; + } +} + +/* Phablet landscape */ +@media (min-width: 680px) and (max-height: 414px) { + .interstitial-wrapper { + margin: 24px auto; + } + + .nav-wrapper { + margin: 0 auto; + } +} + +@media (max-height: 404px) { + button { + margin-top: 0; + } + + #details-button { + height: 32px; + margin: 8px 0; + } +} + +@media (max-height: 240px) and (orientation: landscape), + (max-height: 480px) and (orientation: portrait), + (max-width: 419px) and (max-height: 323px) { + body:not(.neterror) .icon { + height: 56px; + width: 56px; + } + + .icon { + margin-bottom: 16px; + } +} + +/* Small mobile screens. No fixed nav. */ +@media (max-height: 400px) and (orientation: portrait), + (max-height: 240px) and (orientation: landscape) { + .interstitial-wrapper { + display: flex; + flex-direction: column; + margin-bottom: 0; + } + + #details { + flex: 1 1 auto; + order: 0; + } + + #main-content { + flex: 1 1 auto; + order: 0; + } + + .nav-wrapper { + flex: 0 1 auto; + margin-top: 0; + order: 1; + padding-left: 0; + padding-right: 0; + position: relative; + } +} + +/* Malware opt-in. No fixed nav. */ +@media (max-height: 600px) and (orientation: portrait), + (max-height: 360px) and (orientation: landscape) { + .safe-browsing-has-checkbox .interstitial-wrapper { + display: flex; + flex-direction: column; + margin-bottom: 0; + } + + .safe-browsing-has-checkbox #details { + flex: 1 1 auto; + order: 0; + } + + .safe-browsing-has-checkbox #main-content { + flex: 1 1 auto; + order: 0; + } + + .safe-browsing-has-checkbox #malware-opt-in { + margin-bottom: 8px; + } + + body.safe-browsing-has-checkbox .nav-wrapper { + flex: 0 1 auto; + margin-top: 0; + order: 1; + padding-left: 0; + padding-right: 0; + position: relative; } }
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.html b/chrome/browser/resources/security_warnings/interstitial_v2.html index 370beb5..cc347b2 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2.html +++ b/chrome/browser/resources/security_warnings/interstitial_v2.html
@@ -10,35 +10,40 @@ <script src="captive_portal.js"></script> <script src="ssl.js"></script> <script src="safe_browsing.js"></script> + <script src="interstitial_v2_mobile.js"></script> <script src="interstitial_v2.js"></script> </head> <body id="body"> <div class="interstitial-wrapper"> - <div class="icon" id="icon"></div> - <div id="main-message"> - <h1 i18n-content="heading"></h1> - <p i18n-values=".innerHTML:primaryParagraph"></p> - </div> - <div id="malware-opt-in" class="hidden"> - <div class="styled-checkbox"> - <input type="checkbox" id="opt-in-checkbox"> - <label for="opt-in-checkbox"></label> + <div id="main-content"> + <div class="icon" id="icon"></div> + <div id="main-message"> + <h1 i18n-content="heading"></h1> + <p i18n-values=".innerHTML:primaryParagraph"></p> </div> - <div id="opt-in-label"></div> + <div id="malware-opt-in" class="hidden"> + <div class="styled-checkbox"> + <label> + <input type="checkbox" id="opt-in-checkbox"> + <span class="checkbox-tick"></span> + </label> + </div> + <div id="opt-in-label"></div> + </div> </div> <div class="nav-wrapper"> <button i18n-content="primaryButtonText" id="primary-button"></button> - <a href="#" id="details-button" class="small-link" - i18n-content="openDetails"></a> + <button id="details-button" class="small-link" + i18n-content="openDetails"></button> </div> <div id="details" class="hidden"> <p i18n-values=".innerHTML:explanationParagraph"></p> <p i18n-values=".innerHTML:finalParagraph" id="final-paragraph"></p> - </div> - <div id="debugging"> - <p id="error-code"></p> - <div id="error-debugging-info" class="hidden"></div> + <div id="debugging"> + <p id="error-code"></p> + <div id="error-debugging-info" class="hidden"></div> + </div> </div> </div> </body> -</html> +</html> \ No newline at end of file
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.js b/chrome/browser/resources/security_warnings/interstitial_v2.js index e9a846a..fe96d024 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2.js +++ b/chrome/browser/resources/security_warnings/interstitial_v2.js
@@ -139,6 +139,14 @@ } else { $('details-button').addEventListener('click', function(event) { var hiddenDetails = $('details').classList.toggle('hidden'); + + if (mobileNav) { + // Details appear over the main content on small screens. + $('main-content').classList.toggle('hidden', !hiddenDetails); + } else { + $('main-content').classList.remove('hidden'); + } + $('details-button').innerText = hiddenDetails ? loadTimeData.getString('openDetails') : loadTimeData.getString('closeDetails');
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js b/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js new file mode 100644 index 0000000..d524779 --- /dev/null +++ b/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js
@@ -0,0 +1,31 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var mobileNav = false; + +/** + * For small screen mobile the navigation buttons are moved + * below the advanced text. + */ +function onResize() { + var helpOuterBox = document.querySelector('#details'); + var mainContent = document.querySelector('#main-content'); + var mediaQuery = '(max-width: 420px) and (orientation: portrait),' + + '(max-width: 736px) and (max-height: 420px) and (orientation: landscape)'; + + // Check for change in nav status. + if (mobileNav != window.matchMedia(mediaQuery).matches) { + // Show the top content and reset the details section to hidden. + mainContent.classList.toggle('hidden', false); + helpOuterBox.classList.toggle('hidden', true); + mobileNav = !mobileNav; + } +} + +function setupMobileNav() { + window.addEventListener('resize', onResize); + onResize(); +} + +document.addEventListener('DOMContentLoaded', setupMobileNav);
diff --git a/chrome/browser/resources/security_warnings/safe_browsing.js b/chrome/browser/resources/security_warnings/safe_browsing.js index c39aaf2b..3673da5c 100644 --- a/chrome/browser/resources/security_warnings/safe_browsing.js +++ b/chrome/browser/resources/security_warnings/safe_browsing.js
@@ -26,6 +26,7 @@ $('opt-in-label').innerHTML = loadTimeData.getString('optInLink'); $('opt-in-checkbox').checked = loadTimeData.getBoolean(SB_BOX_CHECKED); $('malware-opt-in').classList.remove('hidden'); + $('body').classList.add('safe-browsing-has-checkbox'); $('opt-in-checkbox').addEventListener('click', function() { sendCommand(
diff --git a/chrome/browser/resources/set_as_default_browser.css b/chrome/browser/resources/set_as_default_browser.css index 835590fc..21d7a9de 100644 --- a/chrome/browser/resources/set_as_default_browser.css +++ b/chrome/browser/resources/set_as_default_browser.css
@@ -95,7 +95,7 @@ } #metro-action-box button:hover { - -webkit-transition: all 0; + -webkit-transition: all 0ms; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); }
diff --git a/chrome/browser/resources/uber/uber_frame.js b/chrome/browser/resources/uber/uber_frame.js index 069ce98..6016c45 100644 --- a/chrome/browser/resources/uber/uber_frame.js +++ b/chrome/browser/resources/uber/uber_frame.js
@@ -27,7 +27,6 @@ document.documentElement.addEventListener('mousewheel', onMouseWheel); document.documentElement.addEventListener('mousedown', onMouseDown); - cr.ui.FocusManager.disableMouseFocusOnButtons(); } /**
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/last_download_finder_unittest.cc index b6bcba7..7c4726a09 100644 --- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder_unittest.cc
@@ -57,6 +57,7 @@ HistoryService* history_service = new HistoryService( ChromeHistoryClientFactory::GetForProfile(profile), profile); if (history_service->Init( + profile->GetPrefs()->GetString(prefs::kAcceptLanguages), history::HistoryDatabaseParamsForPath(profile->GetPath()))) { return history_service; }
diff --git a/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector_unittest.cc index 5f6afe4d..cbc03fa 100644 --- a/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector_unittest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/safe_browsing/database_manager.h" #include "chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_pref_service_syncable.h" #include "chrome/test/base/testing_profile.h" @@ -69,6 +70,7 @@ HistoryService* history_service = new HistoryService( ChromeHistoryClientFactory::GetForProfile(profile), profile); if (history_service->Init( + profile->GetPrefs()->GetString(prefs::kAcceptLanguages), history::HistoryDatabaseParamsForPath(profile->GetPath()))) { return history_service; }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 358cfa2..04690dc9 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -15,6 +15,7 @@ #include "base/path_service.h" #include "base/prefs/pref_change_registrar.h" #include "base/prefs/pref_service.h" +#include "base/profiler/scoped_tracker.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/threading/thread.h" @@ -462,18 +463,34 @@ return; enabled_ = true; + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455469 SafeBrowsingService::GetProtocolConfig")); SafeBrowsingProtocolConfig config = GetProtocolConfig(); #if defined(FULL_SAFE_BROWSING) + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455469 SafeBrowsingDatabaseManager::StartOnIOThread")); DCHECK(database_manager_.get()); database_manager_->StartOnIOThread(); + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455469 SafeBrowsingProtocolManager::Create")); DCHECK(!protocol_manager_); protocol_manager_ = SafeBrowsingProtocolManager::Create( database_manager_.get(), url_request_context_getter, config); protocol_manager_->Initialize(); #endif + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed. + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455469 SafeBrowsingPingManager::Create")); DCHECK(!ping_manager_); ping_manager_ = SafeBrowsingPingManager::Create( url_request_context_getter, config);
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc index a1d5a710..6c39f23 100644 --- a/chrome/browser/search/search.cc +++ b/chrome/browser/search/search.cc
@@ -486,8 +486,7 @@ if (!instant_url.SchemeIsSecure() && !google_util::StartsWithCommandLineGoogleBaseURL(instant_url)) { GURL::Replacements replacements; - const std::string secure_scheme(url::kHttpsScheme); - replacements.SetSchemeStr(secure_scheme); + replacements.SetSchemeStr(url::kHttpsScheme); instant_url = instant_url.ReplaceComponents(replacements); }
diff --git a/chrome/browser/service_process/service_process_control_browsertest.cc b/chrome/browser/service_process/service_process_control_browsertest.cc index 097b8f59..a159f38 100644 --- a/chrome/browser/service_process/service_process_control_browsertest.cc +++ b/chrome/browser/service_process/service_process_control_browsertest.cc
@@ -95,12 +95,10 @@ service_process_ = base::Process::OpenWithAccess(service_pid, SYNCHRONIZE | PROCESS_QUERY_INFORMATION); - EXPECT_TRUE(service_process_.IsValid()); #else - base::ProcessHandle service_process_handle; - EXPECT_TRUE(base::OpenProcessHandle(service_pid, &service_process_handle)); - service_process_ = base::Process(service_process_handle); + service_process_ = base::Process::Open(service_pid); #endif + EXPECT_TRUE(service_process_.IsValid()); // Quit the current message. Post a QuitTask instead of just calling Quit() // because this can get invoked in the context of a Launch() call and we // may not be in Run() yet.
diff --git a/chrome/browser/services/gcm/gcm_profile_service.cc b/chrome/browser/services/gcm/gcm_profile_service.cc index fba052a0d..df86051 100644 --- a/chrome/browser/services/gcm/gcm_profile_service.cc +++ b/chrome/browser/services/gcm/gcm_profile_service.cc
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "base/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" #include "components/gcm_driver/gcm_driver.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -26,6 +25,7 @@ #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/chrome_constants.h" +#include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/gcm_driver/gcm_client_factory.h" #include "components/gcm_driver/gcm_driver_desktop.h" #include "components/signin/core/browser/signin_manager.h" @@ -120,16 +120,16 @@ // static bool GCMProfileService::IsGCMEnabled(Profile* profile) { - return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled); +#if defined(OS_ANDROID) + return true; +#else + return profile->GetPrefs()->GetBoolean(gcm::prefs::kGCMChannelStatus); +#endif // defined(OS_ANDROID) } // static void GCMProfileService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref( - prefs::kGCMChannelEnabled, - true, - user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); PushMessagingServiceImpl::RegisterProfilePrefs(registry); }
diff --git a/chrome/browser/services/gcm/push_messaging_browsertest.cc b/chrome/browser/services/gcm/push_messaging_browsertest.cc index b244392d..42a3221 100644 --- a/chrome/browser/services/gcm/push_messaging_browsertest.cc +++ b/chrome/browser/services/gcm/push_messaging_browsertest.cc
@@ -499,39 +499,34 @@ browser()->tab_strip_model()->GetActiveWebContents(); // If the site is visible in an active tab, we should not force a notification - // to be shown. + // to be shown. Try it twice, since we allow one mistake per 10 push events. GCMClient::IncomingMessage message; - message.data["data"] = "testdata"; - push_service()->OnMessage(app_id.ToString(), message); - ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result)); - EXPECT_EQ("testdata", script_result); - ASSERT_EQ(0u, notification_manager()->GetNotificationCount()); + for (int n = 0; n < 2; n++) { + message.data["data"] = "testdata"; + push_service()->OnMessage(app_id.ToString(), message); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result)); + EXPECT_EQ("testdata", script_result); + EXPECT_EQ(0u, notification_manager()->GetNotificationCount()); + } // Open a blank foreground tab so site is no longer visible. ui_test_utils::NavigateToURLWithDisposition( browser(), GURL("about:blank"), NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); - // If the Service Worker push event handler shows a notification, we should - // not show a forced one. - message.data["data"] = "shownotification"; - push_service()->OnMessage(app_id.ToString(), message); - ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); - EXPECT_EQ("shownotification", script_result); - ASSERT_EQ(1u, notification_manager()->GetNotificationCount()); - EXPECT_EQ(base::ASCIIToUTF16("push_test_tag"), - notification_manager()->GetNotificationAt(0).replace_id()); - - notification_manager()->CancelAll(); - ASSERT_EQ(0u, notification_manager()->GetNotificationCount()); - - // However if the Service Worker push event handler does not show a - // notification, we should show a forced one. + // If the Service Worker push event handler does not show a notification, we + // should show a forced one, but only on the 2nd occurrence since we allow one + // mistake per 10 push events. message.data["data"] = "testdata"; push_service()->OnMessage(app_id.ToString(), message); ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); EXPECT_EQ("testdata", script_result); - ASSERT_EQ(1u, notification_manager()->GetNotificationCount()); + EXPECT_EQ(0u, notification_manager()->GetNotificationCount()); + message.data["data"] = "testdata"; + push_service()->OnMessage(app_id.ToString(), message); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); + EXPECT_EQ("testdata", script_result); + EXPECT_EQ(1u, notification_manager()->GetNotificationCount()); EXPECT_EQ(base::ASCIIToUTF16(kPushMessagingForcedNotificationTag), notification_manager()->GetNotificationAt(0).replace_id()); @@ -541,7 +536,31 @@ push_service()->OnMessage(app_id.ToString(), message); ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); EXPECT_EQ("shownotification", script_result); - ASSERT_EQ(2u, notification_manager()->GetNotificationCount()); + EXPECT_EQ(2u, notification_manager()->GetNotificationCount()); + + notification_manager()->CancelAll(); + EXPECT_EQ(0u, notification_manager()->GetNotificationCount()); + + // However if the Service Worker push event handler shows a notification, we + // should not show a forced one. + message.data["data"] = "shownotification"; + for (int n = 0; n < 9; n++) { + push_service()->OnMessage(app_id.ToString(), message); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); + EXPECT_EQ("shownotification", script_result); + EXPECT_EQ(1u, notification_manager()->GetNotificationCount()); + EXPECT_EQ(base::ASCIIToUTF16("push_test_tag"), + notification_manager()->GetNotificationAt(0).replace_id()); + notification_manager()->CancelAll(); + } + + // Now that 10 push messages in a row have shown notifications, we should + // allow the next one to mistakenly not show a notification. + message.data["data"] = "testdata"; + push_service()->OnMessage(app_id.ToString(), message); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); + EXPECT_EQ("testdata", script_result); + EXPECT_EQ(0u, notification_manager()->GetNotificationCount()); } #endif
diff --git a/chrome/browser/services/gcm/push_messaging_permission_context.cc b/chrome/browser/services/gcm/push_messaging_permission_context.cc index 0cb23dab..bb39adce 100644 --- a/chrome/browser/services/gcm/push_messaging_permission_context.cc +++ b/chrome/browser/services/gcm/push_messaging_permission_context.cc
@@ -63,6 +63,12 @@ #endif } +void PushMessagingPermissionContext::CancelPermissionRequest( + content::WebContents* web_contents, const PermissionRequestID& id) { + // TODO(peter): consider implementing this method. + NOTIMPLEMENTED() << "CancelPermission not implemented for push messaging"; +} + // Unlike other permissions, push is decided by the following algorithm // - You need to request it from a top level domain // - You need to have notification permission granted.
diff --git a/chrome/browser/services/gcm/push_messaging_permission_context.h b/chrome/browser/services/gcm/push_messaging_permission_context.h index d85f5a1..0b4a49fb 100644 --- a/chrome/browser/services/gcm/push_messaging_permission_context.h +++ b/chrome/browser/services/gcm/push_messaging_permission_context.h
@@ -25,6 +25,9 @@ const GURL& requesting_origin, const GURL& embedding_origin) const override; + void CancelPermissionRequest(content::WebContents* web_contents, + const PermissionRequestID& id) override; + protected: // PermissionContextBase: void DecidePermission(content::WebContents* web_contents,
diff --git a/chrome/browser/services/gcm/push_messaging_service_impl.cc b/chrome/browser/services/gcm/push_messaging_service_impl.cc index 6722e11..e8d111b 100644 --- a/chrome/browser/services/gcm/push_messaging_service_impl.cc +++ b/chrome/browser/services/gcm/push_messaging_service_impl.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/services/gcm/push_messaging_service_impl.h" +#include <bitset> #include <vector> #include "base/bind.h" @@ -29,6 +30,8 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/service_worker_context.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" #include "content/public/common/content_switches.h" @@ -106,7 +109,7 @@ static_cast<PushMessagingServiceImpl*>( gcm_service->push_messaging_service()); - push_service->IncreasePushRegistrationCount(count); + push_service->IncreasePushRegistrationCount(count, false /* is_pending */); } PushMessagingServiceImpl::PushMessagingServiceImpl( @@ -115,6 +118,7 @@ : gcm_profile_service_(gcm_profile_service), profile_(profile), push_registration_count_(0), + pending_push_registration_count_(0), weak_factory_(this) { } @@ -123,24 +127,35 @@ // then we should call RemoveAppHandler. } -void PushMessagingServiceImpl::IncreasePushRegistrationCount(int add) { +void PushMessagingServiceImpl::IncreasePushRegistrationCount(int add, + bool is_pending) { DCHECK(add > 0); - if (push_registration_count_ == 0) { + if (push_registration_count_ + pending_push_registration_count_ == 0) { gcm_profile_service_->driver()->AddAppHandler( kPushMessagingApplicationIdPrefix, this); } - push_registration_count_ += add; - profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, - push_registration_count_); + if (is_pending) { + pending_push_registration_count_ += add; + } else { + push_registration_count_ += add; + profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, + push_registration_count_); + } } -void PushMessagingServiceImpl::DecreasePushRegistrationCount(int subtract) { +void PushMessagingServiceImpl::DecreasePushRegistrationCount(int subtract, + bool was_pending) { DCHECK(subtract > 0); - push_registration_count_ -= subtract; - DCHECK(push_registration_count_ >= 0); - profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, - push_registration_count_); - if (push_registration_count_ == 0) { + if (was_pending) { + pending_push_registration_count_ -= subtract; + DCHECK(pending_push_registration_count_ >= 0); + } else { + push_registration_count_ -= subtract; + DCHECK(push_registration_count_ >= 0); + profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, + push_registration_count_); + } + if (push_registration_count_ + pending_push_registration_count_ == 0) { gcm_profile_service_->driver()->RemoveAppHandler( kPushMessagingApplicationIdPrefix); } @@ -250,78 +265,136 @@ // is supported. int notification_count = notification_service->GetNotificationUIManager()-> GetAllIdsByProfileAndSourceOrigin(profile_, application_id.origin).size(); - if (notification_count > 0) - return; + // TODO(johnme): Hiding an existing notification should also count as a useful + // user-visible action done in response to a push message - but make sure that + // sending two messages in rapid succession which show then hide a + // notification doesn't count. + bool notification_shown = notification_count > 0; - // Sites with a currently visible tab don't need to show notifications. + bool notification_needed = true; + if (!notification_shown) { + // Sites with a currently visible tab don't need to show notifications. #if defined(OS_ANDROID) - for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { - Profile* profile = (*it)->GetProfile(); - content::WebContents* active_web_contents = - (*it)->GetActiveWebContents(); + for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { + Profile* profile = (*it)->GetProfile(); + content::WebContents* active_web_contents = + (*it)->GetActiveWebContents(); #else - for (chrome::BrowserIterator it; !it.done(); it.Next()) { - Profile* profile = it->profile(); - content::WebContents* active_web_contents = - it->tab_strip_model()->GetActiveWebContents(); + for (chrome::BrowserIterator it; !it.done(); it.Next()) { + Profile* profile = it->profile(); + content::WebContents* active_web_contents = + it->tab_strip_model()->GetActiveWebContents(); #endif - if (!active_web_contents) - continue; + if (!active_web_contents) + continue; - // Don't leak information from other profiles. - if (profile != profile_) - continue; + // Don't leak information from other profiles. + if (profile != profile_) + continue; - // Ignore minimized windows etc. - switch (active_web_contents->GetMainFrame()->GetVisibilityState()) { - case blink::WebPageVisibilityStateHidden: - case blink::WebPageVisibilityStatePrerender: - continue; - case blink::WebPageVisibilityStateVisible: - break; - } + // Ignore minimized windows etc. + switch (active_web_contents->GetMainFrame()->GetVisibilityState()) { + case blink::WebPageVisibilityStateHidden: + case blink::WebPageVisibilityStatePrerender: + continue; + case blink::WebPageVisibilityStateVisible: + break; + } - // Use the visible URL since that's the one the user is aware of (and it - // doesn't matter whether the page loaded successfully). - const GURL& active_url = active_web_contents->GetVisibleURL(); + // Use the visible URL since that's the one the user is aware of (and it + // doesn't matter whether the page loaded successfully). + const GURL& active_url = active_web_contents->GetVisibleURL(); - // Allow https://foo.example.com Service Worker to not show notification if - // an https://bar.example.com tab is visible (and hence might conceivably - // be showing UI in response to the push message); but http:// doesn't count - // as the Service Worker can't talk to it, even with navigator.connect. - if (application_id.origin.scheme() != active_url.scheme()) - continue; - if (net::registry_controlled_domains::SameDomainOrHost( - application_id.origin, active_url, - net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) { - return; + // Allow https://foo.example.com Service Worker to not show notification + // if an https://bar.example.com tab is visible (and hence might + // conceivably be showing UI in response to the push message); but http:// + // doesn't count as the Service Worker can't talk to it, even with + // navigator.connect. + if (application_id.origin.scheme() != active_url.scheme()) + continue; + if (net::registry_controlled_domains::SameDomainOrHost( + application_id.origin, active_url, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) { + notification_needed = false; + break; + } } } - // If we haven't returned yet, the site failed to show a notification, so we - // will show a generic notification. See https://crbug.com/437277 - // TODO(johnme): The generic notification should probably automatically close - // itself when the next push message arrives? - content::PlatformNotificationData notification_data; - // TODO(johnme): Switch to FormatOriginForDisplay from crbug.com/402698 - notification_data.title = l10n_util::GetStringFUTF16( - IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_TITLE, - base::UTF8ToUTF16(application_id.origin.host())); - notification_data.direction = - content::PlatformNotificationData::NotificationDirectionLeftToRight; - notification_data.body = - l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY); - notification_data.tag = - base::ASCIIToUTF16(kPushMessagingForcedNotificationTag); - notification_data.icon = GURL(); // TODO(johnme): Better icon? - notification_service->DisplayPersistentNotification( - profile_, - application_id.service_worker_registration_id, - application_id.origin, - SkBitmap() /* icon */, - notification_data, - content::ChildProcessHost::kInvalidUniqueID /* render_process_id */); -#endif + // Don't track push messages that didn't show a notification but were exempt + // from needing to do so. + if (notification_shown || notification_needed) { + content::ServiceWorkerContext* service_worker_context = + content::BrowserContext::GetStoragePartitionForSite( + profile_, application_id.origin)->GetServiceWorkerContext(); + + PushMessagingService::GetNotificationsShownByLastFewPushes( + service_worker_context, application_id.service_worker_registration_id, + base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShown, + weak_factory_.GetWeakPtr(), + application_id, notification_shown, notification_needed)); + } +#endif // defined(ENABLE_NOTIFICATIONS) +} + +static void IgnoreResult(bool unused) { +} + +void PushMessagingServiceImpl::DidGetNotificationsShown( + const PushMessagingApplicationId& application_id, + bool notification_shown, bool notification_needed, + const std::string& data, bool success, bool not_found) { + content::ServiceWorkerContext* service_worker_context = + content::BrowserContext::GetStoragePartitionForSite( + profile_, application_id.origin)->GetServiceWorkerContext(); + + // We remember whether the last (up to) 10 pushes showed notifications. + const size_t MISSED_NOTIFICATIONS_LENGTH = 10; + // data is a string like "0001000", where '0' means shown, and '1' means + // needed but not shown. We manipulate it in bitset form. + std::bitset<MISSED_NOTIFICATIONS_LENGTH> missed_notifications(data); + + bool needed_but_not_shown = notification_needed && !notification_shown; + + // New entries go at the end, and old ones are shifted off the beginning once + // the history length is exceeded. + missed_notifications <<= 1; + missed_notifications[0] = needed_but_not_shown; + std::string updated_data(missed_notifications. + to_string<char, std::string::traits_type, std::string::allocator_type>()); + PushMessagingService::SetNotificationsShownByLastFewPushes( + service_worker_context, application_id.service_worker_registration_id, + application_id.origin, updated_data, + base::Bind(&IgnoreResult)); // This is a heuristic; ignore failure. + + if (needed_but_not_shown && missed_notifications.count() >= 2) { + // The site failed to show a notification when one was needed, and they have + // already failed once in the previous 10 push messages, so we will show a + // generic notification. See https://crbug.com/437277. + // TODO(johnme): The generic notification should probably automatically + // close itself when the next push message arrives? + content::PlatformNotificationData notification_data; + // TODO(johnme): Switch to FormatOriginForDisplay from crbug.com/402698 + notification_data.title = l10n_util::GetStringFUTF16( + IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_TITLE, + base::UTF8ToUTF16(application_id.origin.host())); + notification_data.direction = + content::PlatformNotificationData::NotificationDirectionLeftToRight; + notification_data.body = + l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY); + notification_data.tag = + base::ASCIIToUTF16(kPushMessagingForcedNotificationTag); + notification_data.icon = GURL(); // TODO(johnme): Better icon? + PlatformNotificationServiceImpl* notification_service = + PlatformNotificationServiceImpl::GetInstance(); + notification_service->DisplayPersistentNotification( + profile_, + application_id.service_worker_registration_id, + application_id.origin, + SkBitmap() /* icon */, + notification_data, + content::ChildProcessHost::kInvalidUniqueID /* render_process_id */); + } } void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) { @@ -362,7 +435,8 @@ requesting_origin, service_worker_registration_id); DCHECK(application_id.IsValid()); - if (push_registration_count_ >= kMaxRegistrations) { + if (push_registration_count_ + pending_push_registration_count_ + >= kMaxRegistrations) { RegisterEnd(callback, std::string(), content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); @@ -439,6 +513,7 @@ return; } + IncreasePushRegistrationCount(1, true /* is_pending */); std::vector<std::string> sender_ids(1, sender_id); gcm_profile_service_->driver()->Register( application_id.ToString(), sender_ids, @@ -460,8 +535,6 @@ const std::string& registration_id, content::PushRegistrationStatus status) { callback.Run(registration_id, status); - if (status == content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE) - IncreasePushRegistrationCount(1); } void PushMessagingServiceImpl::DidRegister( @@ -469,10 +542,13 @@ const std::string& registration_id, GCMClient::Result result) { content::PushRegistrationStatus status = - result == GCMClient::SUCCESS - ? content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE - : content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; + content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; + if (result == GCMClient::SUCCESS) { + status = content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE; + IncreasePushRegistrationCount(1, false /* is_pending */); + } RegisterEnd(callback, registration_id, status); + DecreasePushRegistrationCount(1, true /* was_pending */); } void PushMessagingServiceImpl::DidRequestPermission( @@ -491,8 +567,8 @@ if (!gcm_profile_service_->driver()) return; + IncreasePushRegistrationCount(1, true /* is_pending */); std::vector<std::string> sender_ids(1, sender_id); - gcm_profile_service_->driver()->Register( application_id.ToString(), sender_ids, @@ -553,7 +629,7 @@ } if (result == GCMClient::SUCCESS) - DecreasePushRegistrationCount(1); + DecreasePushRegistrationCount(1, false /* was_pending */); } bool PushMessagingServiceImpl::HasPermission(const GURL& origin) {
diff --git a/chrome/browser/services/gcm/push_messaging_service_impl.h b/chrome/browser/services/gcm/push_messaging_service_impl.h index f09674e9..b9fb57a 100644 --- a/chrome/browser/services/gcm/push_messaging_service_impl.h +++ b/chrome/browser/services/gcm/push_messaging_service_impl.h
@@ -11,7 +11,7 @@ #include "components/gcm_driver/gcm_client.h" #include "content/public/browser/push_messaging_service.h" #include "content/public/common/push_messaging_status.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" class Profile; @@ -75,8 +75,9 @@ void SetProfileForTesting(Profile* profile); private: - void IncreasePushRegistrationCount(int add); - void DecreasePushRegistrationCount(int subtract); + // A registration is pending until it has succeeded or failed. + void IncreasePushRegistrationCount(int add, bool is_pending); + void DecreasePushRegistrationCount(int subtract, bool was_pending); void DeliverMessageCallback(const PushMessagingApplicationId& application_id, const GCMClient::IncomingMessage& message, @@ -87,6 +88,13 @@ // happened in the background. When they forget to do so, display a default // notification on their behalf. void RequireUserVisibleUX(const PushMessagingApplicationId& application_id); + void DidGetNotificationsShown( + const PushMessagingApplicationId& application_id, + bool notification_shown, + bool notification_needed, + const std::string& data, + bool success, + bool not_found); void RegisterEnd( const content::PushMessagingService::RegisterCallback& callback, @@ -113,15 +121,12 @@ // Helper method that checks if a given origin is allowed to use Push. bool HasPermission(const GURL& origin); - // Adds this service as an app handler to the GCMDriver if it has not been - // added yet. - void AddAppHandlerIfNecessary(); - GCMProfileService* gcm_profile_service_; // It owns us. Profile* profile_; // It owns our owner. int push_registration_count_; + int pending_push_registration_count_; base::WeakPtrFactory<PushMessagingServiceImpl> weak_factory_;
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc b/chrome/browser/signin/easy_unlock_metrics.cc similarity index 74% rename from chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc rename to chrome/browser/signin/easy_unlock_metrics.cc index afb95e0..14f788a 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc +++ b/chrome/browser/signin/easy_unlock_metrics.cc
@@ -2,12 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h" +#include "chrome/browser/signin/easy_unlock_metrics.h" #include "base/logging.h" -#include "base/metrics/histogram.h" - -namespace chromeos { +#include "base/metrics/histogram_macros.h" void RecordEasyUnlockLoginEvent(EasyUnlockLoginEvent event) { DCHECK_LT(event, EASY_SIGN_IN_LOGIN_EVENT_COUNT); @@ -16,5 +14,3 @@ event, EASY_SIGN_IN_LOGIN_EVENT_COUNT); } - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h b/chrome/browser/signin/easy_unlock_metrics.h similarity index 88% rename from chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h rename to chrome/browser/signin/easy_unlock_metrics.h index b1779169..f1f1a3d 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h +++ b/chrome/browser/signin/easy_unlock_metrics.h
@@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_ - -namespace chromeos { +#ifndef CHROME_BROWSER_SIGNIN_EASY_UNLOCK_METRICS_H_ +#define CHROME_BROWSER_SIGNIN_EASY_UNLOCK_METRICS_H_ // Tracking login events for Easy unlock metrics. // This enum is used to define the buckets for an enumerated UMA histogram. @@ -43,7 +41,7 @@ PASSWORD_SIGN_IN_RSSI_TOO_LOW = 12, // Password is used for sign-in because phone is not supported. PASSWORD_SIGN_IN_PHONE_UNSUPPORTED = 13, - // Password is used for sign-in because user types in passowrd. This is + // Password is used for sign-in because user types in password. This is // unlikely to happen though. PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE = 14, // Password is used for sign-in because phone is not right next to the @@ -62,11 +60,9 @@ // right next to the Chromebook. PASSWORD_SIGN_IN_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH = 19, - EASY_SIGN_IN_LOGIN_EVENT_COUNT // Must be the last. + EASY_SIGN_IN_LOGIN_EVENT_COUNT // Must be the last entry. }; void RecordEasyUnlockLoginEvent(EasyUnlockLoginEvent event); -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_ +#endif // CHROME_BROWSER_SIGNIN_EASY_UNLOCK_METRICS_H_
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc index ed1b8b0..a9005303 100644 --- a/chrome/browser/signin/easy_unlock_service.cc +++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -313,6 +313,12 @@ #endif } +bool EasyUnlockService::IsEnabled() const { + // The feature is enabled iff there are any paired devices. + const base::ListValue* devices = GetRemoteDevices(); + return devices && !devices->empty(); +} + void EasyUnlockService::SetHardlockState( EasyUnlockScreenlockStateHandler::HardlockState state) { const std::string user_id = GetUserEmail();
diff --git a/chrome/browser/signin/easy_unlock_service.h b/chrome/browser/signin/easy_unlock_service.h index caaa4605..df6a2134 100644 --- a/chrome/browser/signin/easy_unlock_service.h +++ b/chrome/browser/signin/easy_unlock_service.h
@@ -131,6 +131,9 @@ // permitted either the flag is enabled or its field trial is enabled. bool IsAllowed(); + // Whether Easy Unlock is currently enabled for this user. + bool IsEnabled() const; + // Sets the hardlock state for the associated user. void SetHardlockState(EasyUnlockScreenlockStateHandler::HardlockState state); @@ -192,7 +195,7 @@ // Service type specific tests for whether the service is allowed. Returns // false if service is not allowed. If true is returned, the service may still // not be allowed if common tests fail (e.g. if Bluetooth is not available). - virtual bool IsAllowedInternal() = 0; + virtual bool IsAllowedInternal() const = 0; // KeyedService override: void Shutdown() override;
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc index e043bb4..3f79771 100644 --- a/chrome/browser/signin/easy_unlock_service_regular.cc +++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -273,7 +273,7 @@ registrar_.RemoveAll(); } -bool EasyUnlockServiceRegular::IsAllowedInternal() { +bool EasyUnlockServiceRegular::IsAllowedInternal() const { #if defined(OS_CHROMEOS) if (!user_manager::UserManager::Get()->IsLoggedInAsUserWithGaiaAccount()) return false;
diff --git a/chrome/browser/signin/easy_unlock_service_regular.h b/chrome/browser/signin/easy_unlock_service_regular.h index 4ae4342..9bcf90a 100644 --- a/chrome/browser/signin/easy_unlock_service_regular.h +++ b/chrome/browser/signin/easy_unlock_service_regular.h
@@ -59,7 +59,7 @@ void RecordPasswordLoginEvent(const std::string& user_id) const override; void InitializeInternal() override; void ShutdownInternal() override; - bool IsAllowedInternal() override; + bool IsAllowedInternal() const override; // Opens the component packaged app responsible for setting up Smart Lock. void OpenSetupApp();
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc index 5a16da9..42dbac9 100644 --- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc +++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -13,8 +13,8 @@ #include "base/thread_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" -#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" +#include "chrome/browser/signin/easy_unlock_metrics.h" #include "chromeos/login/auth/user_context.h" #include "chromeos/tpm/tpm_token_loader.h" @@ -174,9 +174,8 @@ bool success) const { DCHECK_EQ(GetUserEmail(), user_id); - chromeos::RecordEasyUnlockLoginEvent(success - ? chromeos::EASY_SIGN_IN_SUCCESS - : chromeos::EASY_SIGN_IN_FAILURE); + RecordEasyUnlockLoginEvent( + success ? EASY_SIGN_IN_SUCCESS : EASY_SIGN_IN_FAILURE); DVLOG(1) << "Easy sign-in " << (success ? "success" : "failure"); } @@ -186,11 +185,10 @@ if (GetUserEmail() != user_id) return; - chromeos::EasyUnlockLoginEvent event = - chromeos::EASY_SIGN_IN_LOGIN_EVENT_COUNT; + EasyUnlockLoginEvent event = EASY_SIGN_IN_LOGIN_EVENT_COUNT; if (!GetRemoteDevices() || GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) { - event = chromeos::PASSWORD_SIGN_IN_NO_PAIRING; + event = PASSWORD_SIGN_IN_NO_PAIRING; } else if (GetHardlockState() != EasyUnlockScreenlockStateHandler::NO_HARDLOCK) { switch (GetHardlockState()) { @@ -199,63 +197,63 @@ NOTREACHED(); break; case EasyUnlockScreenlockStateHandler::USER_HARDLOCK: - event = chromeos::PASSWORD_SIGN_IN_USER_HARDLOCK; + event = PASSWORD_SIGN_IN_USER_HARDLOCK; break; case EasyUnlockScreenlockStateHandler::PAIRING_CHANGED: - event = chromeos::PASSWORD_SIGN_IN_PAIRING_CHANGED; + event = PASSWORD_SIGN_IN_PAIRING_CHANGED; break; case EasyUnlockScreenlockStateHandler::LOGIN_FAILED: - event = chromeos::PASSWORD_SIGN_IN_LOGIN_FAILED; + event = PASSWORD_SIGN_IN_LOGIN_FAILED; break; case EasyUnlockScreenlockStateHandler::PAIRING_ADDED: - event = chromeos::PASSWORD_SIGN_IN_PAIRING_ADDED; + event = PASSWORD_SIGN_IN_PAIRING_ADDED; break; } } else if (!screenlock_state_handler()) { - event = chromeos::PASSWORD_SIGN_IN_NO_SCREENLOCK_STATE_HANDLER; + event = PASSWORD_SIGN_IN_NO_SCREENLOCK_STATE_HANDLER; } else { switch (screenlock_state_handler()->state()) { case EasyUnlockScreenlockStateHandler::STATE_INACTIVE: - event = chromeos::PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE; + event = PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE; break; case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH: - event = chromeos::PASSWORD_SIGN_IN_NO_BLUETOOTH; + event = PASSWORD_SIGN_IN_NO_BLUETOOTH; break; case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING: - event = chromeos::PASSWORD_SIGN_IN_BLUETOOTH_CONNECTING; + event = PASSWORD_SIGN_IN_BLUETOOTH_CONNECTING; break; case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE: - event = chromeos::PASSWORD_SIGN_IN_NO_PHONE; + event = PASSWORD_SIGN_IN_NO_PHONE; break; case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED: - event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_AUTHENTICATED; + event = PASSWORD_SIGN_IN_PHONE_NOT_AUTHENTICATED; break; case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED: - event = chromeos::PASSWORD_SIGN_IN_PHONE_LOCKED; + event = PASSWORD_SIGN_IN_PHONE_LOCKED; break; case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE: - event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_LOCKABLE; + event = PASSWORD_SIGN_IN_PHONE_NOT_LOCKABLE; break; case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED: - event = chromeos::PASSWORD_SIGN_IN_PHONE_UNSUPPORTED; + event = PASSWORD_SIGN_IN_PHONE_UNSUPPORTED; break; case EasyUnlockScreenlockStateHandler::STATE_RSSI_TOO_LOW: - event = chromeos::PASSWORD_SIGN_IN_RSSI_TOO_LOW; + event = PASSWORD_SIGN_IN_RSSI_TOO_LOW; break; case EasyUnlockScreenlockStateHandler::STATE_TX_POWER_TOO_HIGH: - event = chromeos::PASSWORD_SIGN_IN_TX_POWER_TOO_HIGH; + event = PASSWORD_SIGN_IN_TX_POWER_TOO_HIGH; break; case EasyUnlockScreenlockStateHandler:: STATE_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH: - event = chromeos::PASSWORD_SIGN_IN_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH; + event = PASSWORD_SIGN_IN_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH; break; case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED: - event = chromeos::PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE; + event = PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE; break; } } - chromeos::RecordEasyUnlockLoginEvent(event); + RecordEasyUnlockLoginEvent(event); DVLOG(1) << "EasySignIn password login event, event=" << event; } @@ -284,7 +282,7 @@ user_data_.clear(); } -bool EasyUnlockServiceSignin::IsAllowedInternal() { +bool EasyUnlockServiceSignin::IsAllowedInternal() const { return service_active_ && !user_id_.empty() && !chromeos::LoginState::Get()->IsUserLoggedIn();
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.h b/chrome/browser/signin/easy_unlock_service_signin_chromeos.h index a04ee0af..45b4352d 100644 --- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.h +++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.h
@@ -74,7 +74,7 @@ void RecordPasswordLoginEvent(const std::string& user_id) const override; void InitializeInternal() override; void ShutdownInternal() override; - bool IsAllowedInternal() override; + bool IsAllowedInternal() const override; // ScreenlockBridge::Observer implementation: void OnScreenDidLock() override;
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 4d1ffdc..15e727d 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -508,8 +508,7 @@ // cross-site navigation so we can test http://crbug.com/5800 is gone. ASSERT_EQ("127.0.0.1", cross_site_url.host()); GURL::Replacements replacements; - std::string new_host("localhost"); - replacements.SetHostStr(new_host); + replacements.SetHostStr("localhost"); cross_site_url = cross_site_url.ReplaceComponents(replacements); // Now go to a bad HTTPS page. @@ -714,9 +713,8 @@ watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); // Visit bad HTTPS page. - std::string scheme("https"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("https"); ui_test_utils::NavigateToURL( browser(), wss_server_expired_.GetURL( @@ -787,9 +785,8 @@ options, net::GetWebSocketTestDataDirectory()); ASSERT_TRUE(wss_server.Start()); - std::string scheme("https"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("https"); GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents( replacements); @@ -1764,9 +1761,8 @@ watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); // Visit bad HTTPS page. - std::string scheme("https"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("https"); ui_test_utils::NavigateToURL( browser(), wss_server_expired_.GetURL(
diff --git a/chrome/browser/supervised_user/experimental/supervised_user_async_url_checker.cc b/chrome/browser/supervised_user/experimental/supervised_user_async_url_checker.cc index b9180d8..8475088d 100644 --- a/chrome/browser/supervised_user/experimental/supervised_user_async_url_checker.cc +++ b/chrome/browser/supervised_user/experimental/supervised_user_async_url_checker.cc
@@ -10,6 +10,7 @@ #include "base/json/json_reader.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" @@ -45,21 +46,16 @@ GURL GetNormalizedURL(const GURL& url) { GURL::Replacements replacements; // Set scheme to http. - const std::string scheme(url::kHttpScheme); - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr(url::kHttpScheme); // Strip leading "www." (if any). const std::string www("www."); - std::string new_host; - if (StartsWithASCII(url.host(), www, true)) { - new_host = url.host().substr(www.size()); - replacements.SetHostStr(new_host); - } + const std::string host(url.host()); + if (StartsWithASCII(host, www, true)) + replacements.SetHostStr(base::StringPiece(host).substr(www.size())); // Strip trailing slash (if any). - std::string new_path; - if (EndsWith(url.path(), "/", true)) { - new_path = url.path().substr(0, url.path().size() - 1); - replacements.SetPathStr(new_path); - } + const std::string path(url.path()); + if (EndsWith(path, "/", true)) + replacements.SetPathStr(base::StringPiece(path).substr(0, path.size() - 1)); return url.ReplaceComponents(replacements); }
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc index 89c0d01..559eabe4 100644 --- a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc +++ b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc
@@ -9,6 +9,8 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/metrics/histogram.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/strings/string_split.h" @@ -61,6 +63,7 @@ bool new_installation = false; RegisterWhitelist(it.key(), name, new_installation); } + UMA_HISTOGRAM_COUNTS_100("ManagedUsers.Whitelist.Count", whitelists->size()); // Register whitelists specified on the command line. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -257,6 +260,8 @@ void SupervisedUserWhitelistService::AddNewWhitelist( base::DictionaryValue* pref_dict, const sync_pb::ManagedUserWhitelistSpecifics& whitelist) { + base::RecordAction(base::UserMetricsAction("ManagedUsers_Whitelist_Added")); + bool new_installation = true; RegisterWhitelist(whitelist.id(), whitelist.name(), new_installation); scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); @@ -273,8 +278,10 @@ void SupervisedUserWhitelistService::RemoveWhitelist( base::DictionaryValue* pref_dict, const std::string& id) { + base::RecordAction(base::UserMetricsAction("ManagedUsers_Whitelist_Removed")); + pref_dict->RemoveWithoutPathExpansion(id, NULL); - installer_->UnregisterWhitelist(id); + installer_->UninstallWhitelist(id); UnloadWhitelist(id); }
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc index ae34bcd..58a8675c 100644 --- a/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc +++ b/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc
@@ -56,10 +56,10 @@ ready_callbacks_[crx_id] = callback; } - void UnregisterWhitelist(const std::string& crx_id) override { + void UninstallWhitelist(const std::string& crx_id) override { EXPECT_TRUE(WhitelistIsRegistered(crx_id)) << crx_id; registered_whitelists_.erase(crx_id); - // Don't remove the callback (see above). + // Don't remove the ready callback (see above). } private:
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.cc b/chrome/browser/sync/glue/bookmark_change_processor.cc index ecd8ce6..ce9ae91 100644 --- a/chrome/browser/sync/glue/bookmark_change_processor.cc +++ b/chrome/browser/sync/glue/bookmark_change_processor.cc
@@ -37,6 +37,7 @@ #include "ui/gfx/image/image_util.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; using syncer::ChangeRecord; using syncer::ChangeRecordList; @@ -844,6 +845,9 @@ (*meta_info_map)[specifics.meta_info(i).key()] = specifics.meta_info(i).value(); } + // Verifies that all entries had unique keys. + DCHECK_EQ(static_cast<size_t>(specifics.meta_info_size()), + meta_info_map->size()); return meta_info_map.Pass(); } @@ -852,8 +856,34 @@ const BookmarkNode* node, syncer::WriteNode* sync_node) { sync_pb::BookmarkSpecifics specifics = sync_node->GetBookmarkSpecifics(); - specifics.clear_meta_info(); const BookmarkNode::MetaInfoMap* meta_info_map = node->GetMetaInfoMap(); + + // Compare specifics meta info to node meta info before making the change. + // Please note that the original specifics meta info is unordered while + // meta_info_map is ordered by key. Setting the meta info blindly into + // the specifics might cause an unnecessary change. + size_t size = meta_info_map ? meta_info_map->size() : 0; + if (static_cast<size_t>(specifics.meta_info_size()) == size) { + size_t index = 0; + for (; index < size; index++) { + const sync_pb::MetaInfo& meta_info = specifics.meta_info(index); + BookmarkNode::MetaInfoMap::const_iterator it = + meta_info_map->find(meta_info.key()); + if (it == meta_info_map->end() || it->second != meta_info.value()) { + // One of original meta info entries is missing in |meta_info_map| or + // different. + break; + } + } + if (index == size) { + // The original meta info from the sync model is already equivalent to + // |meta_info_map|. + return; + } + } + + // Clear and reset meta info in bookmark specifics. + specifics.clear_meta_info(); if (meta_info_map) { for (BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map->begin(); it != meta_info_map->end(); ++it) { @@ -862,6 +892,7 @@ meta_info->set_value(it->second); } } + sync_node->SetBookmarkSpecifics(specifics); }
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.h b/chrome/browser/sync/glue/bookmark_change_processor.h index f72ebd2e..e23c6e0 100644 --- a/chrome/browser/sync/glue/bookmark_change_processor.h +++ b/chrome/browser/sync/glue/bookmark_change_processor.h
@@ -46,28 +46,29 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkMetaInfoChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; // The change processor implementation, responsible for applying changes from // the sync model to the bookmarks model. @@ -83,24 +84,25 @@ // with data taken from the |sync_node| sync node. static void UpdateBookmarkWithSyncData(const syncer::BaseNode& sync_node, bookmarks::BookmarkModel* model, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, Profile* profile); // Creates a bookmark node under the given parent node from the given sync // node. Returns the newly created node. The created node is placed at the // specified index among the parent's children. - static const BookmarkNode* CreateBookmarkNode(syncer::BaseNode* sync_node, - const BookmarkNode* parent, - bookmarks::BookmarkModel* model, - Profile* profile, - int index); + static const bookmarks::BookmarkNode* CreateBookmarkNode( + syncer::BaseNode* sync_node, + const bookmarks::BookmarkNode* parent, + bookmarks::BookmarkModel* model, + Profile* profile, + int index); // Sets the favicon of the given bookmark node from the given sync node. // Returns whether the favicon was set in the bookmark node. // |profile| is the profile that contains the HistoryService and BookmarkModel // for the bookmark in question. static bool SetBookmarkFavicon(const syncer::BaseNode* sync_node, - const BookmarkNode* bookmark_node, + const bookmarks::BookmarkNode* bookmark_node, bookmarks::BookmarkModel* model, Profile* profile); @@ -108,13 +110,13 @@ // |profile| is the profile that contains the HistoryService and BookmarkModel // for the bookmark in question. static void ApplyBookmarkFavicon( - const BookmarkNode* bookmark_node, + const bookmarks::BookmarkNode* bookmark_node, Profile* profile, const GURL& icon_url, const scoped_refptr<base::RefCountedMemory>& bitmap_data); // Sets the favicon of the given sync node from the given bookmark node. - static void SetSyncNodeFavicon(const BookmarkNode* bookmark_node, + static void SetSyncNodeFavicon(const bookmarks::BookmarkNode* bookmark_node, bookmarks::BookmarkModel* model, syncer::WriteNode* sync_node); @@ -123,7 +125,7 @@ // will be transferred to the new node. A node corresponding to |parent| // must already exist and be associated for this call to succeed. Returns // the ID of the just-created node, or if creation fails, kInvalidID. - static int64 CreateSyncNode(const BookmarkNode* parent, + static int64 CreateSyncNode(const bookmarks::BookmarkNode* parent, bookmarks::BookmarkModel* model, int index, syncer::WriteTransaction* trans, @@ -131,7 +133,7 @@ sync_driver::DataTypeErrorHandler* error_handler); // Update |bookmark_node|'s sync node. - static int64 UpdateSyncNode(const BookmarkNode* bookmark_node, + static int64 UpdateSyncNode(const bookmarks::BookmarkNode* bookmark_node, bookmarks::BookmarkModel* model, syncer::WriteTransaction* trans, BookmarkModelAssociator* associator, @@ -142,7 +144,7 @@ static void UpdateTransactionVersion( int64 new_version, bookmarks::BookmarkModel* model, - const std::vector<const BookmarkNode*>& nodes); + const std::vector<const bookmarks::BookmarkNode*>& nodes); protected: void StartImpl() override; @@ -154,11 +156,11 @@ }; // Retrieves the meta info from the given sync node. - static scoped_ptr<BookmarkNode::MetaInfoMap> GetBookmarkMetaInfo( + static scoped_ptr<bookmarks::BookmarkNode::MetaInfoMap> GetBookmarkMetaInfo( const syncer::BaseNode* sync_node); // Sets the meta info of the given sync node from the given bookmark node. - static void SetSyncNodeMetaInfo(const BookmarkNode* node, + static void SetSyncNodeMetaInfo(const bookmarks::BookmarkNode* node, syncer::WriteNode* sync_node); // Helper function used to fix the position of a sync node so that it matches @@ -170,19 +172,19 @@ // SetPosition(). |trans| is the transaction to which |dst| belongs. Returns // false on failure. static bool PlaceSyncNode(MoveOrCreate operation, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index, syncer::WriteTransaction* trans, syncer::WriteNode* dst, BookmarkModelAssociator* associator); // Copy properties (but not position) from |src| to |dst|. - static void UpdateSyncNodeProperties(const BookmarkNode* src, + static void UpdateSyncNodeProperties(const bookmarks::BookmarkNode* src, bookmarks::BookmarkModel* model, syncer::WriteNode* dst); // Helper function to encode a bookmark's favicon into raw PNG data. - static void EncodeFavicon(const BookmarkNode* src, + static void EncodeFavicon(const bookmarks::BookmarkNode* src, bookmarks::BookmarkModel* model, scoped_refptr<base::RefCountedMemory>* dst); @@ -198,13 +200,13 @@ const int64& topmost_node_id); // Remove all the sync nodes associated with |node| and its children. - void RemoveSyncNodeHierarchy(const BookmarkNode* node); + void RemoveSyncNodeHierarchy(const bookmarks::BookmarkNode* node); // Creates or updates a sync node associated with |node|. - void CreateOrUpdateSyncNode(const BookmarkNode* node); + void CreateOrUpdateSyncNode(const bookmarks::BookmarkNode* node); // Returns false if |node| should not be synced. - bool CanSyncNode(const BookmarkNode* node); + bool CanSyncNode(const bookmarks::BookmarkNode* node); // The bookmark model we are processing changes from. Non-NULL when // |running_| is true.
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc index eb8ae19..2932597 100644 --- a/chrome/browser/sync/glue/bookmark_model_associator.cc +++ b/chrome/browser/sync/glue/bookmark_model_associator.cc
@@ -37,6 +37,7 @@ #include "sync/util/data_type_histogram.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; namespace browser_sync {
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.h b/chrome/browser/sync/glue/bookmark_model_associator.h index 2820597..ad1ff71 100644 --- a/chrome/browser/sync/glue/bookmark_model_associator.h +++ b/chrome/browser/sync/glue/bookmark_model_associator.h
@@ -17,11 +17,11 @@ #include "components/sync_driver/model_associator.h" #include "sync/internal_api/public/util/unrecoverable_error_handler.h" -class BookmarkNode; class Profile; namespace bookmarks { class BookmarkModel; +class BookmarkNode; } namespace syncer { @@ -37,7 +37,8 @@ // * Methods to get a bookmark node for a given sync node and vice versa. // * Persisting model associations and loading them back. class BookmarkModelAssociator - : public sync_driver::PerDataTypeAssociatorInterface<BookmarkNode, int64> { + : public sync_driver:: + PerDataTypeAssociatorInterface<bookmarks::BookmarkNode, int64> { public: static syncer::ModelType model_type() { return syncer::BOOKMARKS; } // |expect_mobile_bookmarks_folder| controls whether or not we @@ -80,7 +81,8 @@ // Returns the bookmark node for the given sync id. // Returns NULL if no bookmark node is found for the given sync id. - const BookmarkNode* GetChromeNodeFromSyncId(int64 sync_id) override; + const bookmarks::BookmarkNode* GetChromeNodeFromSyncId( + int64 sync_id) override; // Initializes the given sync node from the given bookmark node id. // Returns false if no sync node was found for the given bookmark node id or @@ -89,7 +91,7 @@ syncer::BaseNode* sync_node) override; // Associates the given bookmark node with the given sync id. - void Associate(const BookmarkNode* node, int64 sync_id) override; + void Associate(const bookmarks::BookmarkNode* node, int64 sync_id) override; // Remove the association that corresponds to the given sync id. void Disassociate(int64 sync_id) override; @@ -109,7 +111,8 @@ private: typedef std::map<int64, int64> BookmarkIdToSyncIdMap; - typedef std::map<int64, const BookmarkNode*> SyncIdToBookmarkNodeMap; + typedef std::map<int64, const bookmarks::BookmarkNode*> + SyncIdToBookmarkNodeMap; typedef std::set<int64> DirtyAssociationsSyncIds; // Posts a task to persist dirty associations. @@ -134,11 +137,11 @@ // Bookmarks folder. The sync nodes are server-created. // Returns true on success, false if association failed. bool AssociateTaggedPermanentNode( - const BookmarkNode* permanent_node, + const bookmarks::BookmarkNode* permanent_node, const std::string& tag) WARN_UNUSED_RESULT; // Compare the properties of a pair of nodes from either domain. - bool NodesMatch(const BookmarkNode* bookmark, + bool NodesMatch(const bookmarks::BookmarkNode* bookmark, const syncer::BaseNode* sync_node) const; // Check whether bookmark model and sync model are synced by comparing
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index cb305b5..acbfb7c 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc
@@ -34,8 +34,6 @@ #include "chrome/browser/prefs/chrome_pref_service_factory.h" #include "chrome/browser/prefs/pref_service_syncable.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/services/gcm/gcm_profile_service.h" -#include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/signin/about_signin_internals_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -63,7 +61,6 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/autofill_pref_names.h" -#include "components/gcm_driver/gcm_driver.h" #include "components/invalidation/invalidation_service.h" #include "components/invalidation/profile_invalidation_provider.h" #include "components/password_manager/core/browser/password_store.h" @@ -1141,17 +1138,6 @@ current_experiments_ = experiments; - // Handle preference-backed experiments first. - if (experiments.gcm_channel_state == syncer::Experiments::SUPPRESSED) { - profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, false); - gcm::GCMProfileServiceFactory::GetForProfile(profile())->driver() - ->Disable(); - } else { - profile()->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); - gcm::GCMProfileServiceFactory::GetForProfile(profile())->driver() - ->Enable(); - } - profile()->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, experiments.gcm_invalidations_enabled); profile()->GetPrefs()->SetBoolean(
diff --git a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc index 9ad8578..a0c1673 100644 --- a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
@@ -50,6 +50,7 @@ namespace browser_sync { using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using syncer::BaseNode; using testing::_; using testing::InvokeWithoutArgs; @@ -99,6 +100,8 @@ node.SetTitle(title); sync_pb::BookmarkSpecifics specifics(node.GetBookmarkSpecifics()); + const base::Time creation_time(base::Time::Now()); + specifics.set_creation_time_us(creation_time.ToInternalValue()); if (!is_folder) specifics.set_url(url); if (meta_info_map) @@ -257,15 +260,20 @@ void SetNodeMetaInfo(const BookmarkNode::MetaInfoMap& meta_info_map, sync_pb::BookmarkSpecifics* specifics) { specifics->clear_meta_info(); - for (BookmarkNode::MetaInfoMap::const_iterator it = - meta_info_map.begin(); it != meta_info_map.end(); ++it) { + // Deliberatly set MetaInfoMap entries in opposite order (compared + // to the implementation in BookmarkChangeProcessor) to ensure that + // (a) the implementation isn't sensitive to the order and + // (b) the original meta info isn't blindly overwritten by + // BookmarkChangeProcessor unless there is a real change. + BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map.end(); + while (it != meta_info_map.begin()) { + --it; sync_pb::MetaInfo* meta_info = specifics->add_meta_info(); meta_info->set_key(it->first); meta_info->set_value(it->second); } } - // The transaction on which everything happens. syncer::WriteTransaction *trans_; @@ -2022,6 +2030,58 @@ ExpectModelMatch(); } +// Tests that node's specifics doesn't get unnecessarily overwritten (causing +// a subsequent commit) when BookmarkChangeProcessor handles a notification +// (such as BookmarkMetaInfoChanged) without an actual data change. +TEST_F(ProfileSyncServiceBookmarkTestWithData, MetaInfoPreservedOnNonChange) { + LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE); + WriteTestDataToBookmarkModel(); + StartSync(); + + std::string orig_specifics; + int64 sync_id; + const BookmarkNode* bookmark; + + // Create bookmark folder node containing meta info. + { + syncer::WriteTransaction trans(FROM_HERE, test_user_share_.user_share()); + FakeServerChange adds(&trans); + + int64 folder_id = adds.AddFolder("folder title", bookmark_bar_id(), 0); + + BookmarkNode::MetaInfoMap node_meta_info; + node_meta_info["one"] = "1"; + node_meta_info["two"] = "2"; + node_meta_info["three"] = "3"; + + sync_id = adds.AddURLWithMetaInfo("node title", "http://www.foo.com/", + &node_meta_info, folder_id, 0); + + // Verify that the node propagates to the bookmark model + adds.ApplyPendingChanges(change_processor_.get()); + + bookmark = model_->bookmark_bar_node()->GetChild(0)->GetChild(0); + EXPECT_EQ(node_meta_info, *bookmark->GetMetaInfoMap()); + + syncer::ReadNode sync_node(&trans); + EXPECT_EQ(BaseNode::INIT_OK, sync_node.InitByIdLookup(sync_id)); + orig_specifics = sync_node.GetBookmarkSpecifics().SerializeAsString(); + } + + // Force change processor to update the sync node. + change_processor_->BookmarkMetaInfoChanged(model_, bookmark); + + // Read bookmark specifics again and verify that there is no change. + { + syncer::ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); + syncer::ReadNode sync_node(&trans); + EXPECT_EQ(BaseNode::INIT_OK, sync_node.InitByIdLookup(sync_id)); + std::string new_specifics = + sync_node.GetBookmarkSpecifics().SerializeAsString(); + ASSERT_EQ(orig_specifics, new_specifics); + } +} + void ProfileSyncServiceBookmarkTestWithData::GetTransactionVersions( const BookmarkNode* root, BookmarkNodeVersionMap* node_versions) {
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc new file mode 100644 index 0000000..e3c2da1a --- /dev/null +++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -0,0 +1,27 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/base/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + +class ProfileSyncServiceFactoryTest : public testing::Test { + protected: + ProfileSyncServiceFactoryTest() {} + + void SetUp() override { + profile_.reset(new TestingProfile()); + } + + scoped_ptr<Profile> profile_; +}; + +// Verify that the disable sync flag disables creation of the sync service. +TEST_F(ProfileSyncServiceFactoryTest, DisableSyncFlag) { + base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync); + EXPECT_EQ(nullptr, ProfileSyncServiceFactory::GetForProfile(profile_.get())); +}
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc index 566b369..044542c8 100644 --- a/chrome/browser/sync/profile_sync_service_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -639,5 +639,16 @@ service()->GetLastSyncedTimeString()); } +// Verify that the disable sync flag disables sync. +TEST_F(ProfileSyncServiceTest, DisableSyncFlag) { + base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync); + EXPECT_FALSE(ProfileSyncService::IsSyncEnabled()); +} + +// Verify that no disable sync flag enables sync. +TEST_F(ProfileSyncServiceTest, NoDisableSyncFlag) { + EXPECT_TRUE(ProfileSyncService::IsSyncEnabled()); +} + } // namespace } // namespace browser_sync
diff --git a/chrome/browser/sync/test/integration/DEPS b/chrome/browser/sync/test/integration/DEPS index aba01a77f..bed88891 100644 --- a/chrome/browser/sync/test/integration/DEPS +++ b/chrome/browser/sync/test/integration/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/onc", # wifi_credentials tests # TODO(akalin): Figure out finer-grained dependencies. "+sync", ] \ No newline at end of file
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc index eae9c43..035d3c2 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.cc +++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/sync/test/integration/bookmarks_helper.h" +#include <set> +#include <vector> + #include "base/bind.h" #include "base/compiler_specific.h" #include "base/files/file_util.h" @@ -43,6 +46,7 @@ #include "ui/gfx/image/image_skia.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.h b/chrome/browser/sync/test/integration/bookmarks_helper.h index 7968d9b..a229760488 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.h +++ b/chrome/browser/sync/test/integration/bookmarks_helper.h
@@ -5,90 +5,91 @@ #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_BOOKMARKS_HELPER_H_ #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_BOOKMARKS_HELPER_H_ -#include <set> #include <string> -#include <vector> #include "base/compiler_specific.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "url/gurl.h" +#include "third_party/skia/include/core/SkColor.h" class GURL; +namespace bookmarks { +class BookmarkModel; +class BookmarkNode; +} + +namespace gfx { +class Image; +} + namespace bookmarks_helper { // Used to access the bookmark model within a particular sync profile. bookmarks::BookmarkModel* GetBookmarkModel(int index) WARN_UNUSED_RESULT; // Used to access the bookmark bar within a particular sync profile. -const BookmarkNode* GetBookmarkBarNode(int index) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* GetBookmarkBarNode(int index) WARN_UNUSED_RESULT; // Used to access the "other bookmarks" node within a particular sync profile. -const BookmarkNode* GetOtherNode(int index) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* GetOtherNode(int index) WARN_UNUSED_RESULT; // Used to access the "Synced Bookmarks" node within a particular sync profile. -const BookmarkNode* GetSyncedBookmarksNode(int index) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* GetSyncedBookmarksNode(int index) + WARN_UNUSED_RESULT; // Used to access the "Managed Bookmarks" node for the given profile. -const BookmarkNode* GetManagedNode(int index) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* GetManagedNode(int index) WARN_UNUSED_RESULT; // Used to access the bookmarks within the verifier sync profile. bookmarks::BookmarkModel* GetVerifierBookmarkModel() WARN_UNUSED_RESULT; // Adds a URL with address |url| and title |title| to the bookmark bar of // profile |profile|. Returns a pointer to the node that was added. -const BookmarkNode* AddURL( - int profile, - const std::string& title, - const GURL& url) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddURL(int profile, + const std::string& title, + const GURL& url) WARN_UNUSED_RESULT; // Adds a URL with address |url| and title |title| to the bookmark bar of // profile |profile| at position |index|. Returns a pointer to the node that // was added. -const BookmarkNode* AddURL( - int profile, - int index, - const std::string& title, - const GURL& url) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddURL(int profile, + int index, + const std::string& title, + const GURL& url) WARN_UNUSED_RESULT; // Adds a URL with address |url| and title |title| under the node |parent| of // profile |profile| at position |index|. Returns a pointer to the node that // was added. -const BookmarkNode* AddURL( - int profile, - const BookmarkNode* parent, - int index, - const std::string& title, - const GURL& url) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddURL(int profile, + const bookmarks::BookmarkNode* parent, + int index, + const std::string& title, + const GURL& url) WARN_UNUSED_RESULT; // Adds a folder named |title| to the bookmark bar of profile |profile|. // Returns a pointer to the folder that was added. -const BookmarkNode* AddFolder( - int profile, - const std::string& title) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddFolder(int profile, const std::string& title) + WARN_UNUSED_RESULT; // Adds a folder named |title| to the bookmark bar of profile |profile| at // position |index|. Returns a pointer to the folder that was added. -const BookmarkNode* AddFolder( - int profile, - int index, - const std::string& title) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddFolder(int profile, + int index, + const std::string& title) + WARN_UNUSED_RESULT; // Adds a folder named |title| to the node |parent| in the bookmark model of // profile |profile| at position |index|. Returns a pointer to the node that // was added. -const BookmarkNode* AddFolder( - int profile, - const BookmarkNode* parent, - int index, - const std::string& title) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* AddFolder(int profile, + const bookmarks::BookmarkNode* parent, + int index, + const std::string& title) + WARN_UNUSED_RESULT; // Changes the title of the node |node| in the bookmark model of profile // |profile| to |new_title|. void SetTitle(int profile, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::string& new_title); // The source of the favicon. @@ -100,40 +101,38 @@ // Sets the |icon_url| and |image| data for the favicon for |node| in the // bookmark model for |profile|. void SetFavicon(int profile, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const GURL& icon_url, const gfx::Image& image, FaviconSource source); // Changes the url of the node |node| in the bookmark model of profile // |profile| to |new_url|. Returns a pointer to the node with the changed url. -const BookmarkNode* SetURL( - int profile, - const BookmarkNode* node, - const GURL& new_url) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* SetURL(int profile, + const bookmarks::BookmarkNode* node, + const GURL& new_url) WARN_UNUSED_RESULT; // Moves the node |node| in the bookmark model of profile |profile| so it ends // up under the node |new_parent| at position |index|. -void Move( - int profile, - const BookmarkNode* node, - const BookmarkNode* new_parent, - int index); +void Move(int profile, + const bookmarks::BookmarkNode* node, + const bookmarks::BookmarkNode* new_parent, + int index); // Removes the node in the bookmark model of profile |profile| under the node // |parent| at position |index|. -void Remove(int profile, const BookmarkNode* parent, int index); +void Remove(int profile, const bookmarks::BookmarkNode* parent, int index); // Removes all non-permanent nodes in the bookmark model of profile |profile|. void RemoveAll(int profile); // Sorts the children of the node |parent| in the bookmark model of profile // |profile|. -void SortChildren(int profile, const BookmarkNode* parent); +void SortChildren(int profile, const bookmarks::BookmarkNode* parent); // Reverses the order of the children of the node |parent| in the bookmark // model of profile |profile|. -void ReverseChildOrder(int profile, const BookmarkNode* parent); +void ReverseChildOrder(int profile, const bookmarks::BookmarkNode* parent); // Checks if the bookmark model of profile |profile| matches the verifier // bookmark model. Returns true if they match. @@ -167,9 +166,8 @@ // Gets the node in the bookmark model of profile |profile| that has the url // |url|. Note: Only one instance of |url| is assumed to be present. -const BookmarkNode* GetUniqueNodeByURL( - int profile, - const GURL& url) WARN_UNUSED_RESULT; +const bookmarks::BookmarkNode* GetUniqueNodeByURL(int profile, const GURL& url) + WARN_UNUSED_RESULT; // Returns the number of bookmarks in bookmark model of profile |profile|. int CountAllBookmarks(int profile) WARN_UNUSED_RESULT;
diff --git a/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc b/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc index bf4dcf3..a6bf1b17 100644 --- a/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc +++ b/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/sync/test/integration/performance/sync_timing_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/bookmarks/browser/bookmark_node.h" using bookmarks_helper::AddURL; using bookmarks_helper::AllModelsMatch;
diff --git a/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc b/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc index 881cc44..5492ee3 100644 --- a/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc +++ b/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc
@@ -21,6 +21,7 @@ #include "sync/test/fake_server/fake_server_verifier.h" #include "sync/util/time.h" +using bookmarks::BookmarkNode; using bookmarks_helper::AddFolder; using bookmarks_helper::AddURL; using bookmarks_helper::GetOtherNode;
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index 86c165f..f342813 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -15,6 +15,7 @@ #include "ui/base/layout.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks_helper::AddFolder; using bookmarks_helper::AddURL; using bookmarks_helper::CountBookmarksWithTitlesMatching;
diff --git a/chrome/browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc index f8c68aa..ab01c6f 100644 --- a/chrome/browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc
@@ -4,20 +4,41 @@ #include "base/command_line.h" #include "base/macros.h" +#include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/wifi_credentials_helper.h" #include "chrome/common/chrome_switches.h" +#include "components/wifi_sync/wifi_credential.h" +#include "components/wifi_sync/wifi_security_class.h" + +using sync_integration_test_util::AwaitCommitActivityCompletion; +using wifi_sync::WifiCredential; + +using WifiCredentialSet = wifi_sync::WifiCredential::CredentialSet; class SingleClientWifiCredentialsSyncTest : public SyncTest { public: SingleClientWifiCredentialsSyncTest() : SyncTest(SINGLE_CLIENT) {} ~SingleClientWifiCredentialsSyncTest() override {} + // SyncTest implementation. + void SetUp() override { + wifi_credentials_helper::SetUp(); + SyncTest::SetUp(); + } + void SetUpCommandLine(base::CommandLine* command_line) override { SyncTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kEnableWifiCredentialSync); } + bool SetupClients() override { + if (!SyncTest::SetupClients()) + return false; + wifi_credentials_helper::SetupClients(); + return true; + } + private: DISALLOW_COPY_AND_ASSIGN(SingleClientWifiCredentialsSyncTest); }; @@ -27,3 +48,26 @@ ASSERT_TRUE(wifi_credentials_helper::VerifierIsEmpty()); ASSERT_TRUE(wifi_credentials_helper::ProfileMatchesVerifier(0)); } + +IN_PROC_BROWSER_TEST_F(SingleClientWifiCredentialsSyncTest, SingleCredential) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + const char ssid[] = "fake-ssid"; + scoped_ptr<WifiCredential> credential = + wifi_credentials_helper::MakeWifiCredential( + ssid, wifi_sync::SECURITY_CLASS_PSK, "fake_passphrase"); + ASSERT_TRUE(credential); + + const size_t profile_index = 0; + wifi_credentials_helper::AddWifiCredential( + profile_index, "fake_id", *credential); + + const WifiCredentialSet verifier_credentials = + wifi_credentials_helper::GetWifiCredentialsForProfile(verifier()); + EXPECT_EQ(1U, verifier_credentials.size()); + EXPECT_EQ(WifiCredential::MakeSsidBytesForTest(ssid), + verifier_credentials.begin()->ssid()); + + ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((profile_index)))); + EXPECT_TRUE(wifi_credentials_helper::ProfileMatchesVerifier(profile_index)); +}
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc index b763f75..4937d95a7 100644 --- a/chrome/browser/sync/test/integration/sync_errors_test.cc +++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -16,6 +16,7 @@ #include "google_apis/gaia/google_service_auth_error.h" #include "sync/protocol/sync_protocol_error.h" +using bookmarks::BookmarkNode; using bookmarks_helper::AddFolder; using bookmarks_helper::SetTitle; using sync_integration_test_util::AwaitCommitActivityCompletion;
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc index 41b0e94f..e574eec2 100644 --- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/bookmarks/browser/bookmark_node.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" #include "policy/policy_constants.h" @@ -19,6 +20,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/layout.h" +using bookmarks::BookmarkNode; using bookmarks_helper::AddFolder; using bookmarks_helper::AddURL; using bookmarks_helper::AllModelsMatch; @@ -1141,8 +1143,7 @@ ASSERT_TRUE(AddURL(0, folder, i, title, url) != NULL); } std::string title = IndexedFolderName(level); - folder = AddFolder( - 0, folder, folder->child_count(), title); + folder = AddFolder(0, folder, folder->child_count(), title); ASSERT_TRUE(folder != NULL); if (level == 5) folder_L5 = folder; }
diff --git a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc index 8dea54c..0b9279c 100644 --- a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc
@@ -14,6 +14,7 @@ #include "components/history/core/browser/history_types.h" using base::ASCIIToUTF16; +using bookmarks::BookmarkNode; using sync_integration_test_util::AwaitCommitActivityCompletion; using typed_urls_helper::AddUrlToHistory; using typed_urls_helper::AddUrlToHistoryWithTimestamp;
diff --git a/chrome/browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc b/chrome/browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc index db17020..0d74a0e 100644 --- a/chrome/browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc
@@ -4,20 +4,40 @@ #include "base/command_line.h" #include "base/macros.h" +#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/wifi_credentials_helper.h" #include "chrome/common/chrome_switches.h" +#include "components/wifi_sync/wifi_credential.h" +#include "components/wifi_sync/wifi_security_class.h" + +using wifi_sync::WifiCredential; + +using WifiCredentialSet = wifi_sync::WifiCredential::CredentialSet; class TwoClientWifiCredentialsSyncTest : public SyncTest { public: TwoClientWifiCredentialsSyncTest() : SyncTest(TWO_CLIENT) {} ~TwoClientWifiCredentialsSyncTest() override {} + // SyncTest implementation. + void SetUp() override { + wifi_credentials_helper::SetUp(); + SyncTest::SetUp(); + } + void SetUpCommandLine(base::CommandLine* command_line) override { SyncTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kEnableWifiCredentialSync); } + bool SetupClients() override { + if (!SyncTest::SetupClients()) + return false; + wifi_credentials_helper::SetupClients(); + return true; + } + private: DISALLOW_COPY_AND_ASSIGN(TwoClientWifiCredentialsSyncTest); }; @@ -27,3 +47,29 @@ ASSERT_TRUE(wifi_credentials_helper::VerifierIsEmpty()); ASSERT_TRUE(wifi_credentials_helper::AllProfilesMatch()); } + +IN_PROC_BROWSER_TEST_F(TwoClientWifiCredentialsSyncTest, SingleCredential) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + const char ssid[] = "fake-ssid"; + scoped_ptr<WifiCredential> credential = + wifi_credentials_helper::MakeWifiCredential( + ssid, wifi_sync::SECURITY_CLASS_PSK, "fake_passphrase"); + ASSERT_TRUE(credential); + + const size_t profile_a_index = 0; + wifi_credentials_helper::AddWifiCredential( + profile_a_index, "fake_id", *credential); + + const WifiCredentialSet verifier_credentials = + wifi_credentials_helper::GetWifiCredentialsForProfile(verifier()); + EXPECT_EQ(1U, verifier_credentials.size()); + EXPECT_EQ(WifiCredential::MakeSsidBytesForTest(ssid), + verifier_credentials.begin()->ssid()); + + const size_t profile_b_index = 1; + ASSERT_TRUE(GetClient(profile_a_index)->AwaitMutualSyncCycleCompletion( + GetClient(profile_b_index))); + EXPECT_FALSE(wifi_credentials_helper::VerifierIsEmpty()); + EXPECT_TRUE(wifi_credentials_helper::AllProfilesMatch()); +}
diff --git a/chrome/browser/sync/test/integration/wifi_credentials_helper.cc b/chrome/browser/sync/test/integration/wifi_credentials_helper.cc index d29765f..7472aa1 100644 --- a/chrome/browser/sync/test/integration/wifi_credentials_helper.cc +++ b/chrome/browser/sync/test/integration/wifi_credentials_helper.cc
@@ -9,14 +9,17 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" -#include "components/wifi_sync/wifi_credential.h" -#include "components/wifi_sync/wifi_security_class.h" +#include "components/wifi_sync/wifi_credential_syncable_service.h" +#include "components/wifi_sync/wifi_credential_syncable_service_factory.h" #if defined(OS_CHROMEOS) #include "chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.h" #endif using wifi_sync::WifiCredential; +using wifi_sync::WifiCredentialSyncableService; +using wifi_sync::WifiCredentialSyncableServiceFactory; +using wifi_sync::WifiSecurityClass; using sync_datatype_helper::test; using WifiCredentialSet = wifi_sync::WifiCredential::CredentialSet; @@ -25,12 +28,31 @@ namespace { -WifiCredentialSet GetWifiCredentialsForProfile(const Profile* profile) { +void SetupClientForProfile(Profile* profile) { #if defined(OS_CHROMEOS) - return GetWifiCredentialsForProfileChromeOs(profile); + wifi_credentials_helper::chromeos::SetupClientForProfileChromeOs(profile); #else - NOTIMPLEMENTED(); - return WifiCredential::MakeSet(); + NOTREACHED(); +#endif +} + +WifiCredentialSyncableService* GetServiceForBrowserContext( + content::BrowserContext* context) { + return WifiCredentialSyncableServiceFactory::GetForBrowserContext( + context); +} + +WifiCredentialSyncableService* GetServiceForProfile(int profile_index) { + return GetServiceForBrowserContext(test()->GetProfile(profile_index)); +} + +void AddWifiCredentialToProfile( + Profile* profile, const WifiCredential& credential) { +#if defined(OS_CHROMEOS) + wifi_credentials_helper::chromeos::AddWifiCredentialToProfileChromeOs( + profile, credential); +#else + NOTREACHED(); #endif } @@ -43,7 +65,7 @@ return false; } - for (const auto &credential : a_credentials) { + for (const WifiCredential& credential : a_credentials) { if (b_credentials.find(credential) == b_credentials.end()) { LOG(ERROR) << "Network from a not found in b. " @@ -61,6 +83,20 @@ } // namespace +void SetUp() { +#if defined(OS_CHROMEOS) + wifi_credentials_helper::chromeos::SetUpChromeOs(); +#else + NOTREACHED(); +#endif +} + +void SetupClients() { + SetupClientForProfile(test()->verifier()); + for (int i = 0; i < test()->num_clients(); ++i) + SetupClientForProfile(test()->GetProfile(i)); +} + bool VerifierIsEmpty() { return GetWifiCredentialsForProfile(test()->verifier()).empty(); } @@ -92,4 +128,36 @@ return true; } +scoped_ptr<WifiCredential> MakeWifiCredential(const std::string& ssid, + WifiSecurityClass security_class, + const std::string& passphrase) { + return WifiCredential::Create(WifiCredential::MakeSsidBytesForTest(ssid), + security_class, + passphrase); +} + +void AddWifiCredential(int profile_index, + const std::string& sync_id, + const WifiCredential& credential) { + AddWifiCredentialToProfile(test()->GetProfile(profile_index), credential); + if (test()->use_verifier()) + AddWifiCredentialToProfile(test()->verifier(), credential); + + // TODO(quiche): Remove this, once we have plumbing to route + // NetworkConfigurationObserver events to + // WifiCredentialSyncableService instances. + GetServiceForProfile(profile_index) + ->AddToSyncedNetworks(sync_id, credential); +} + +WifiCredentialSet GetWifiCredentialsForProfile(const Profile* profile) { +#if defined(OS_CHROMEOS) + return wifi_credentials_helper::chromeos:: + GetWifiCredentialsForProfileChromeOs(profile); +#else + NOTREACHED(); + return WifiCredential::MakeSet(); +#endif +} + } // namespace wifi_credentials_helper
diff --git a/chrome/browser/sync/test/integration/wifi_credentials_helper.h b/chrome/browser/sync/test/integration/wifi_credentials_helper.h index 31cc1568..6d81149 100644 --- a/chrome/browser/sync/test/integration/wifi_credentials_helper.h +++ b/chrome/browser/sync/test/integration/wifi_credentials_helper.h
@@ -5,11 +5,28 @@ #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_WIFI_CREDENTIALS_HELPER_H_ #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_WIFI_CREDENTIALS_HELPER_H_ +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "components/wifi_sync/wifi_credential.h" +#include "components/wifi_sync/wifi_security_class.h" + +class Profile; + // Functions needed by multiple wifi_credentials integration // tests. This module is platfrom-agnostic, and calls out to // platform-specific code as needed. namespace wifi_credentials_helper { +// Performs common setup steps, such as configuring factories. Should +// be called before SyncTest::SetUp. +void SetUp(); + +// Initializes the clients. This includes associating their Chrome +// Profiles with platform-specific networking state. Should be called +// before adding/removing/modifying WiFi credentials. +void SetupClients(); + // Checks if the verifier has any items in it. Returns true iff the // verifier has no items. bool VerifierIsEmpty(); @@ -21,6 +38,23 @@ // Returns true iff all BrowserContexts match with the verifier. bool AllProfilesMatch(); +// Returns a new WifiCredential constructed from the given parameters. +scoped_ptr<wifi_sync::WifiCredential> MakeWifiCredential( + const std::string& ssid, + wifi_sync::WifiSecurityClass security_class, + const std::string& passphrase); + +// Adds a WiFi credential to the service at index |profile_index|, +// and the verifier (if the SyncTest uses a verifier). +void AddWifiCredential(int profile_index, + const std::string& sync_id, + const wifi_sync::WifiCredential& credential); + +// Returns the set of WifiCredentials configured in local network +// settings, for |profile|. +wifi_sync::WifiCredential::CredentialSet GetWifiCredentialsForProfile( + const Profile* profile); + } // namespace wifi_credentials_helper #endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_WIFI_CREDENTIALS_HELPER_H_
diff --git a/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.cc b/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.cc index 8e540024..7117f198 100644 --- a/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.cc +++ b/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.cc
@@ -6,14 +6,24 @@ #include <string> +#include "base/bind.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "chrome/browser/profiles/profile.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/shill_profile_client.h" +#include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_handler.h" -#include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "components/onc/onc_constants.h" #include "components/wifi_sync/network_state_helper_chromeos.h" -#include "components/wifi_sync/wifi_security_class.h" +#include "components/wifi_sync/wifi_credential_syncable_service_factory.h" +#include "content/public/browser/browser_context.h" + +using wifi_sync::WifiCredential; using WifiCredentialSet = wifi_sync::WifiCredential::CredentialSet; @@ -23,27 +33,98 @@ const char kProfilePrefix[] = "/profile/"; +void LogCreateConfigurationFailure( + const std::string& debug_hint, + const std::string& /* network_config_error_message */, + scoped_ptr<base::DictionaryValue> /* network_config_error_data */) { + LOG(FATAL) << debug_hint; +} + std::string ChromeOsUserHashForBrowserContext( const content::BrowserContext& context) { return context.GetPath().BaseName().value(); } +// Return value is distinct per |context|, but otherwise arbitrary. std::string ShillProfilePathForBrowserContext( const content::BrowserContext& context) { return kProfilePrefix + ChromeOsUserHashForBrowserContext(context); } -chromeos::NetworkStateHandler* GetNetworkStateHandler() { - DCHECK(chromeos::NetworkHandler::Get()->network_state_handler()); - return chromeos::NetworkHandler::Get()->network_state_handler(); +::chromeos::ShillProfileClient::TestInterface* +GetShillProfileClientTestInterface() { + DCHECK(::chromeos::DBusThreadManager::Get()->GetShillProfileClient()); + DCHECK(::chromeos::DBusThreadManager::Get()->GetShillProfileClient() + ->GetTestInterface()); + return ::chromeos::DBusThreadManager::Get()->GetShillProfileClient() + ->GetTestInterface(); +} + +::chromeos::ManagedNetworkConfigurationHandler* +GetManagedNetworkConfigurationHandler() { + DCHECK(::chromeos::NetworkHandler::Get() + ->managed_network_configuration_handler()); + return ::chromeos::NetworkHandler::Get() + ->managed_network_configuration_handler(); +} + +::chromeos::NetworkStateHandler* GetNetworkStateHandler() { + DCHECK(::chromeos::NetworkHandler::Get()->network_state_handler()); + return ::chromeos::NetworkHandler::Get()->network_state_handler(); } } // namespace -WifiCredentialSet GetWifiCredentialsForProfileChromeOs(const Profile* profile) { - DCHECK(profile); - return wifi_sync::GetWifiCredentialsForShillProfile( - GetNetworkStateHandler(), ShillProfilePathForBrowserContext(*profile)); +namespace chromeos { + +void SetUpChromeOs() { + wifi_sync::WifiCredentialSyncableServiceFactory::GetInstance() + ->set_ignore_login_state_for_test(true); } +void SetupClientForProfileChromeOs( + const content::BrowserContext* browser_context) { + DCHECK(browser_context); + GetShillProfileClientTestInterface() + ->AddProfile(ShillProfilePathForBrowserContext(*browser_context), + ChromeOsUserHashForBrowserContext(*browser_context)); + + const base::ListValue policy_network_configs; + const base::DictionaryValue policy_global_config; + GetManagedNetworkConfigurationHandler() + ->SetPolicy(onc::ONC_SOURCE_UNKNOWN, + ChromeOsUserHashForBrowserContext(*browser_context), + policy_network_configs, + policy_global_config); +} + +void AddWifiCredentialToProfileChromeOs( + const content::BrowserContext* browser_context, + const WifiCredential& credential) { + DCHECK(browser_context); + scoped_ptr<base::DictionaryValue> onc_properties = + credential.ToOncProperties(); + CHECK(onc_properties) << "Failed to generate ONC properties for " + << credential.ToString(); + GetManagedNetworkConfigurationHandler() + ->CreateConfiguration( + ChromeOsUserHashForBrowserContext(*browser_context), + *onc_properties, + ::chromeos::network_handler::StringResultCallback(), + base::Bind(LogCreateConfigurationFailure, + base::StringPrintf("Failed to add credential %s", + credential.ToString().c_str()))); + base::MessageLoop::current()->RunUntilIdle(); +} + +WifiCredentialSet GetWifiCredentialsForProfileChromeOs( + const content::BrowserContext* browser_context) { + DCHECK(browser_context); + return wifi_sync::GetWifiCredentialsForShillProfile( + GetNetworkStateHandler(), + ShillProfilePathForBrowserContext(*browser_context)); +} + +} // namespace chromeos + } // namespace wifi_credentials_helper
diff --git a/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.h b/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.h index dc10c3f..834e37e 100644 --- a/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.h +++ b/chrome/browser/sync/test/integration/wifi_credentials_helper_chromeos.h
@@ -7,13 +7,34 @@ #include "components/wifi_sync/wifi_credential.h" -class Profile; +namespace content { +class BrowserContext; +} namespace wifi_credentials_helper { -// Returns the ChromeOS WiFi credentials associated with |profile|. +namespace chromeos { + +// Performs ChromeOS-specific setup. +void SetUpChromeOs(); + +// Performs ChromeOS-specific setup for a given sync client, given +// that client's BrowserContext. Should be called only after SetUpChromeOs. +void SetupClientForProfileChromeOs( + const content::BrowserContext* browser_context); + +// Adds a WiFi credential to the ChromeOS networking backend, +// associating the credential with the ChromeOS networking state that +// corresponds to |browser_context|. +void AddWifiCredentialToProfileChromeOs( + const content::BrowserContext* browser_context, + const wifi_sync::WifiCredential& credential); + +// Returns the ChromeOS WiFi credentials associated with |browser_context|. wifi_sync::WifiCredential::CredentialSet GetWifiCredentialsForProfileChromeOs( - const Profile* profile); + const content::BrowserContext* profile); + +} // namespace chromeos } // namespace wifi_credentials_helper
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc index 6d345e9..fee6fe1 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.cc +++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -323,7 +323,7 @@ void SyncFileSystemService::GetFileSyncStatus( const FileSystemURL& url, const SyncFileStatusCallback& callback) { DCHECK(local_service_); - DCHECK(GetRemoteService(url.origin())); + DCHECK(remote_service_); // It's possible to get an invalid FileEntry. if (!url.is_valid()) { @@ -352,7 +352,7 @@ LocalChangeProcessor* SyncFileSystemService::GetLocalChangeProcessor( const GURL& origin) { - return GetRemoteService(origin)->GetLocalChangeProcessor(); + return remote_service_->GetLocalChangeProcessor(); } void SyncFileSystemService::OnSyncIdle() { @@ -525,7 +525,7 @@ if (status == SYNC_STATUS_FAILED) { // If we got generic error return the service status information. - switch (GetRemoteService(app_origin)->GetCurrentState()) { + switch (remote_service_->GetCurrentState()) { case REMOTE_SERVICE_AUTHENTICATION_REQUIRED: callback.Run(SYNC_STATUS_AUTHENTICATION_FAILED); return; @@ -556,7 +556,7 @@ return; } - GetRemoteService(origin)->DumpFiles( + remote_service_->DumpFiles( origin, base::Bind( &SyncFileSystemService::DidDumpFiles, @@ -682,7 +682,7 @@ DVLOG(1) << "Handle extension notification for UNLOAD(DISABLE): " << app_origin; - GetRemoteService(app_origin)->DisableOrigin( + remote_service_->DisableOrigin( app_origin, base::Bind(&DidHandleUnloadedEvent, app_origin)); local_service_->SetOriginEnabled(app_origin, false); @@ -705,7 +705,7 @@ GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id()); DVLOG(1) << "Handle extension notification for UNINSTALLED: " << app_origin; - GetRemoteService(app_origin)->UninstallOrigin( + remote_service_->UninstallOrigin( app_origin, flag, base::Bind(&DidHandleUninstalledEvent, app_origin)); local_service_->SetOriginEnabled(app_origin, false); @@ -716,7 +716,7 @@ const Extension* extension) { GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id()); DVLOG(1) << "Handle extension notification for LOADED: " << app_origin; - GetRemoteService(app_origin)->EnableOrigin( + remote_service_->EnableOrigin( app_origin, base::Bind(&DidHandleLoadEvent, app_origin)); local_service_->SetOriginEnabled(app_origin, true); @@ -764,9 +764,4 @@ ((*iter)->*method)(); } -RemoteFileSyncService* SyncFileSystemService::GetRemoteService( - const GURL& origin) { - return remote_service_.get(); -} - } // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.h b/chrome/browser/sync_file_system/sync_file_system_service.h index bf085f4f..e41d1e7 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.h +++ b/chrome/browser/sync_file_system/sync_file_system_service.h
@@ -163,10 +163,6 @@ // and Remote sync). void RunForEachSyncRunners(void(SyncProcessRunner::*method)()); - // Returns the appropriate RemoteFileSyncService for the given origin/app. - // (crbug.com/324215) - RemoteFileSyncService* GetRemoteService(const GURL& origin); - Profile* profile_; scoped_ptr<LocalFileSyncService> local_service_;
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc index 3a79f59..2cd1796 100644 --- a/chrome/browser/task_manager/task_manager_browsertest.cc +++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -606,8 +606,7 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); GURL::Replacements replace_host; - std::string host_str("localhost"); // must stay in scope with replace_host - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL base_url = embedded_test_server()->GetURL( "/extensions/api_test/app_process/"); base_url = base_url.ReplaceComponents(replace_host); @@ -671,8 +670,7 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); GURL::Replacements replace_host; - std::string host_str("localhost"); // must stay in scope with replace_host - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL base_url = embedded_test_server()->GetURL("/extensions/api_test/app_process/"); base_url = base_url.ReplaceComponents(replace_host); @@ -707,8 +705,7 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); GURL::Replacements replace_host; - std::string host_str("localhost"); // must stay in scope with replace_host - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL base_url = embedded_test_server()->GetURL("/extensions/api_test/app_process/"); base_url = base_url.ReplaceComponents(replace_host);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 611ca04..bd77d85f 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -113,6 +113,7 @@ "//third_party/npapi", "//third_party/libjingle", "//third_party/re2", + "//ui/base/ime", "//ui/compositor", "//ui/surface", "//ui/web_dialogs", @@ -509,6 +510,8 @@ "pdf/pdf_browsertest_base.h", "test/test_confirm_bubble_model.cc", "test/test_confirm_bubble_model.h", + "toolbar/test_toolbar_action_view_controller.cc", + "toolbar/test_toolbar_action_view_controller.h", "website_settings/mock_permission_bubble_request.cc", "website_settings/mock_permission_bubble_request.h", ]
diff --git a/chrome/browser/ui/android/infobars/app_banner_infobar.cc b/chrome/browser/ui/android/infobars/app_banner_infobar.cc index 367586f..e207489 100644 --- a/chrome/browser/ui/android/infobars/app_banner_infobar.cc +++ b/chrome/browser/ui/android/infobars/app_banner_infobar.cc
@@ -8,10 +8,19 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" -#include "jni/AppBannerInfoBarDelegate_jni.h" +#include "jni/AppBannerInfoBar_jni.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/image/image.h" + +AppBannerInfoBar::AppBannerInfoBar( + scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, + const base::android::ScopedJavaGlobalRef<jobject>& japp_data) + : ConfirmInfoBar(delegate.Pass()), + japp_data_(japp_data) { +} + AppBannerInfoBar::AppBannerInfoBar( scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, const GURL& app_url) @@ -24,33 +33,53 @@ base::android::ScopedJavaLocalRef<jobject> AppBannerInfoBar::CreateRenderInfoBar(JNIEnv* env) { - java_delegate_.Reset(Java_AppBannerInfoBarDelegate_create(env)); + ConfirmInfoBarDelegate* app_banner_infobar_delegate = GetDelegate(); - base::android::ScopedJavaLocalRef<jstring> ok_button_text = - base::android::ConvertUTF16ToJavaString( - env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK)); - - ConfirmInfoBarDelegate* delegate = GetDelegate(); base::android::ScopedJavaLocalRef<jstring> app_title = base::android::ConvertUTF16ToJavaString( - env, delegate->GetMessageText()); + env, app_banner_infobar_delegate->GetMessageText()); - base::android::ScopedJavaLocalRef<jstring> app_url = - base::android::ConvertUTF8ToJavaString(env, app_url_.spec()); - - ScopedJavaLocalRef<jobject> java_bitmap; - if (!delegate->GetIcon().IsEmpty()) { - java_bitmap = gfx::ConvertToJavaBitmap(delegate->GetIcon().ToSkBitmap()); + base::android::ScopedJavaLocalRef<jobject> java_bitmap; + if (!app_banner_infobar_delegate->GetIcon().IsEmpty()) { + java_bitmap = gfx::ConvertToJavaBitmap( + app_banner_infobar_delegate->GetIcon().ToSkBitmap()); } - return Java_AppBannerInfoBarDelegate_showInfoBar( - env, - java_delegate_.obj(), - reinterpret_cast<intptr_t>(this), - app_title.obj(), - java_bitmap.obj(), - ok_button_text.obj(), - app_url.obj()); + base::android::ScopedJavaLocalRef<jobject> infobar; + if (!japp_data_.is_null()) { + infobar.Reset(Java_AppBannerInfoBar_createNativeAppInfoBar( + env, + reinterpret_cast<intptr_t>(this), + app_title.obj(), + java_bitmap.obj(), + japp_data_.obj())); + } else { + // Trim down the app URL to the domain and registry. + std::string trimmed_url = + net::registry_controlled_domains::GetDomainAndRegistry( + app_url_, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + + base::android::ScopedJavaLocalRef<jstring> app_url = + base::android::ConvertUTF8ToJavaString(env, trimmed_url); + + infobar.Reset(Java_AppBannerInfoBar_createWebAppInfoBar( + env, + reinterpret_cast<intptr_t>(this), + app_title.obj(), + java_bitmap.obj(), + app_url.obj())); + } + + java_infobar_.Reset(env, infobar.obj()); + return infobar; +} + +void AppBannerInfoBar::OnInstallStateChanged(int new_state) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_AppBannerInfoBar_onInstallStateChanged(env, + java_infobar_.obj(), + new_state); } // Native JNI methods ---------------------------------------------------------
diff --git a/chrome/browser/ui/android/infobars/app_banner_infobar.h b/chrome/browser/ui/android/infobars/app_banner_infobar.h index b43462c..6845a3c9 100644 --- a/chrome/browser/ui/android/infobars/app_banner_infobar.h +++ b/chrome/browser/ui/android/infobars/app_banner_infobar.h
@@ -17,6 +17,11 @@ class AppBannerInfoBar : public ConfirmInfoBar { public: + // Constructs an AppBannerInfoBar promoting a native app. + AppBannerInfoBar( + scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, + const base::android::ScopedJavaGlobalRef<jobject>& japp_data); + // Constructs an AppBannerInfoBar promoting a web app. AppBannerInfoBar( scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, @@ -24,16 +29,23 @@ ~AppBannerInfoBar() override; + // Called when the installation state of the app may have changed. + // Updates the InfoBar visuals to match the new state and re-enables controls + // that may have been disabled. + void OnInstallStateChanged(int new_state); + private: // InfoBarAndroid overrides. base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( JNIEnv* env) override; + // Native app: Details about the app. + base::android::ScopedJavaGlobalRef<jobject> japp_data_; + // Web app: URL for the app. GURL app_url_; - // Java delegate for creating AppBannerInfoBars. - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; + base::android::ScopedJavaGlobalRef<jobject> java_infobar_; DISALLOW_COPY_AND_ASSIGN(AppBannerInfoBar); };
diff --git a/chrome/browser/ui/android/infobars/confirm_infobar.h b/chrome/browser/ui/android/infobars/confirm_infobar.h index 68e305d3..72a78618 100644 --- a/chrome/browser/ui/android/infobars/confirm_infobar.h +++ b/chrome/browser/ui/android/infobars/confirm_infobar.h
@@ -18,13 +18,13 @@ protected: base::string16 GetTextFor(ConfirmInfoBarDelegate::InfoBarButton button); ConfirmInfoBarDelegate* GetDelegate(); + void OnLinkClicked(JNIEnv* env, jobject obj) override; // InfoBarAndroid overrides. base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( JNIEnv* env) override; private: - void OnLinkClicked(JNIEnv* env, jobject obj) override; void ProcessButton(int action, const std::string& action_value) override; base::android::ScopedJavaGlobalRef<jobject> java_confirm_delegate_;
diff --git a/chrome/browser/ui/app_list/app_context_menu.cc b/chrome/browser/ui/app_list/app_context_menu.cc index 8634f4c9c..43d805e 100644 --- a/chrome/browser/ui/app_list/app_context_menu.cc +++ b/chrome/browser/ui/app_list/app_context_menu.cc
@@ -118,9 +118,8 @@ // When bookmark apps are enabled, hosted apps can only toggle between // USE_LAUNCH_TYPE_WINDOW and USE_LAUNCH_TYPE_REGULAR. if (extensions::util::IsNewBookmarkAppsEnabled()) { - menu_model_->AddCheckItemWithStringId( - USE_LAUNCH_TYPE_REGULAR, - IDS_APP_CONTEXT_MENU_OPEN_TAB); + menu_model_->AddCheckItemWithStringId(USE_LAUNCH_TYPE_WINDOW, + IDS_APP_CONTEXT_MENU_OPEN_WINDOW); } else { menu_model_->AddCheckItemWithStringId( USE_LAUNCH_TYPE_REGULAR, @@ -195,9 +194,9 @@ // USE_LAUNCH_TYPE_REGULAR is checked, as USE_LAUNCH_TYPE_PINNED (i.e. open // as pinned tab) and fullscreen-by-default windows do not exist. if (extensions::util::IsNewBookmarkAppsEnabled()) { - return IsCommandIdChecked(USE_LAUNCH_TYPE_REGULAR) ? - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_TAB) : - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW); + return IsCommandIdChecked(USE_LAUNCH_TYPE_WINDOW) + ? l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW) + : l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_TAB); } #if defined(OS_MACOSX) @@ -274,9 +273,9 @@ // LAUNCH_TYPE_WINDOW and LAUNCH_TYPE_REGULAR. if (extensions::util::IsNewBookmarkAppsEnabled()) { launch_type = (controller_->GetExtensionLaunchType(profile_, app_id_) == - extensions::LAUNCH_TYPE_REGULAR) ? - extensions::LAUNCH_TYPE_WINDOW : - extensions::LAUNCH_TYPE_REGULAR; + extensions::LAUNCH_TYPE_WINDOW) + ? extensions::LAUNCH_TYPE_REGULAR + : extensions::LAUNCH_TYPE_WINDOW; } controller_->SetExtensionLaunchType(profile_, app_id_, launch_type); } else if (command_id == OPTIONS) {
diff --git a/chrome/browser/ui/app_list/app_list_service_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_service_impl_browsertest.cc index f7dc7903..7d282a4 100644 --- a/chrome/browser/ui/app_list/app_list_service_impl_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_service_impl_browsertest.cc
@@ -57,21 +57,6 @@ DISALLOW_COPY_AND_ASSIGN(AppListServiceImplBrowserTest); }; -class AppListServiceImplBrowserTestWithBookmarkAppsEnabled - : public AppListServiceImplBrowserTest { - public: - AppListServiceImplBrowserTestWithBookmarkAppsEnabled() {} - - // Overridden from BrowserTestBase: - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(switches::kEnableNewBookmarkApps); - } - - private: - DISALLOW_COPY_AND_ASSIGN( - AppListServiceImplBrowserTestWithBookmarkAppsEnabled); -}; - // Test that showing a loaded profile for the first time is lazy and // synchronous. Then tests that showing a second loaded profile without // dismissing correctly switches profiles. @@ -172,8 +157,7 @@ // Test that all the items in the context menu for a hosted app have valid // labels. -IN_PROC_BROWSER_TEST_F(AppListServiceImplBrowserTestWithBookmarkAppsEnabled, - ShowContextMenu) { +IN_PROC_BROWSER_TEST_F(AppListServiceImplBrowserTest, ShowContextMenu) { AppListService* service = test::GetAppListService(); EXPECT_TRUE(service);
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc index 833d3bbe..c65a3e0 100644 --- a/chrome/browser/ui/app_list/start_page_service.cc +++ b/chrome/browser/ui/app_list/start_page_service.cc
@@ -12,6 +12,7 @@ #include "base/memory/singleton.h" #include "base/metrics/user_metrics.h" #include "base/prefs/pref_service.h" +#include "base/strings/string_piece.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/media/media_stream_infobar_delegate.h" @@ -558,11 +559,8 @@ } void StartPageService::FetchDoodleJson() { - // SetPathStr() requires its argument to stay in scope as long as - // |replacements| is, so a std::string is needed, instead of a char*. - std::string path = kDoodleJsonPath; GURL::Replacements replacements; - replacements.SetPathStr(path); + replacements.SetPathStr(kDoodleJsonPath); GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()); GURL doodle_url = google_base_url.ReplaceComponents(replacements); @@ -579,10 +577,11 @@ // Remove XSSI guard for JSON parsing. size_t json_start_index = json_data.find("{"); + base::StringPiece json_data_substr(json_data); if (json_start_index != std::string::npos) - json_data.erase(0, json_start_index); + json_data_substr.remove_prefix(json_start_index); - JSONStringValueSerializer deserializer(json_data); + JSONStringValueSerializer deserializer(json_data_substr); deserializer.set_allow_trailing_comma(true); int error_code = 0; scoped_ptr<base::Value> doodle_json(
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc index 86e62738..5764d37f 100644 --- a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc +++ b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
@@ -110,9 +110,8 @@ // With bookmark apps enabled, hosted apps launch in a window by // default. This menu item is re-interpreted as a single, toggle-able // option to launch the hosted app as a tab. - AddCheckItemWithStringId( - LAUNCH_TYPE_REGULAR_TAB, - IDS_APP_CONTEXT_MENU_OPEN_TAB); + AddCheckItemWithStringId(LAUNCH_TYPE_WINDOW, + IDS_APP_CONTEXT_MENU_OPEN_WINDOW); } else { AddCheckItemWithStringId( LAUNCH_TYPE_REGULAR_TAB, @@ -310,23 +309,22 @@ case LAUNCH_TYPE_PINNED_TAB: controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_PINNED); break; - case LAUNCH_TYPE_REGULAR_TAB: { - extensions::LaunchType launch_type = - extensions::LAUNCH_TYPE_REGULAR; + case LAUNCH_TYPE_REGULAR_TAB: + controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_REGULAR); + break; + case LAUNCH_TYPE_WINDOW: { + extensions::LaunchType launch_type = extensions::LAUNCH_TYPE_WINDOW; // With bookmark apps enabled, hosted apps can only toggle between // LAUNCH_WINDOW and LAUNCH_REGULAR. if (extensions::util::IsNewBookmarkAppsEnabled()) { launch_type = controller_->GetLaunchType(item_.id) == - extensions::LAUNCH_TYPE_REGULAR - ? extensions::LAUNCH_TYPE_WINDOW - : extensions::LAUNCH_TYPE_REGULAR; + extensions::LAUNCH_TYPE_WINDOW + ? extensions::LAUNCH_TYPE_REGULAR + : extensions::LAUNCH_TYPE_WINDOW; } controller_->SetLaunchType(item_.id, launch_type); break; } - case LAUNCH_TYPE_WINDOW: - controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_WINDOW); - break; case LAUNCH_TYPE_FULLSCREEN: controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_FULLSCREEN); break;
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc index c890d6a..0f2ee6d 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -368,8 +368,7 @@ // Whitelist iframe URL instead. GURL::Replacements replace_host; - std::string host_str("www.a.com"); // Must stay in scope with replace_host - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("www.a.com"); GURL frame_url(embedded_test_server() ->GetURL("/popup_blocker/popup-frames-iframe.html") .ReplaceComponents(replace_host)); @@ -625,7 +624,8 @@ } // Tests that Ctrl+Enter/Cmd+Enter keys on a link open the backgournd tab. -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, CtrlEnterKey) { +// Failing due to Blink r189541 http://crbug.com/455691 +IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, DISABLED_CtrlEnterKey) { WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); GURL url(embedded_test_server()->GetURL(
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc index d26aca4ac..eb4e794a 100644 --- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc +++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc
@@ -31,6 +31,7 @@ #include "ui/base/l10n/l10n_util.h" using base::UserMetricsAction; +using bookmarks::BookmarkNode; using content::PageNavigator; BookmarkContextMenuController::BookmarkContextMenuController(
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h index 55b4bd60..e3b42fe8 100644 --- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h +++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h
@@ -32,7 +32,7 @@ // Sent before any command from the menu is executed. virtual void WillExecuteCommand( int command_id, - const std::vector<const BookmarkNode*>& bookmarks) {} + const std::vector<const bookmarks::BookmarkNode*>& bookmarks) {} // Sent after any command from the menu is executed. virtual void DidExecuteCommand(int command_id) {} @@ -56,8 +56,8 @@ Browser* browser, Profile* profile, content::PageNavigator* navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection); + const bookmarks::BookmarkNode* parent, + const std::vector<const bookmarks::BookmarkNode*>& selection); ~BookmarkContextMenuController() override; ui::SimpleMenuModel* menu_model() { return menu_model_.get(); } @@ -95,8 +95,8 @@ Browser* browser_; Profile* profile_; content::PageNavigator* navigator_; - const BookmarkNode* parent_; - std::vector<const BookmarkNode*> selection_; + const bookmarks::BookmarkNode* parent_; + std::vector<const bookmarks::BookmarkNode*> selection_; bookmarks::BookmarkModel* model_; scoped_ptr<ui::SimpleMenuModel> menu_model_;
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc index 204a9c8..fa3dea4 100644 --- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc +++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
@@ -27,6 +27,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; using content::OpenURLParams; using content::PageNavigator;
diff --git a/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc b/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc index ac7a8b8..9f126aa 100644 --- a/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc +++ b/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc
@@ -16,6 +16,7 @@ #include "ui/base/dragdrop/drag_drop_types.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; namespace chrome {
diff --git a/chrome/browser/ui/bookmarks/bookmark_drag_drop.h b/chrome/browser/ui/bookmarks/bookmark_drag_drop.h index 8b7885c8..2720d6c 100644 --- a/chrome/browser/ui/bookmarks/bookmark_drag_drop.h +++ b/chrome/browser/ui/bookmarks/bookmark_drag_drop.h
@@ -10,10 +10,10 @@ #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/gfx/native_widget_types.h" -class BookmarkNode; class Profile; namespace bookmarks { +class BookmarkNode; struct BookmarkNodeData; } @@ -21,7 +21,7 @@ // Starts the process of dragging a folder of bookmarks. void DragBookmarks(Profile* profile, - const std::vector<const BookmarkNode*>& nodes, + const std::vector<const bookmarks::BookmarkNode*>& nodes, gfx::NativeView view, ui::DragDropTypes::DragEventSource source); @@ -31,7 +31,7 @@ // Returns the drop type used. int DropBookmarks(Profile* profile, const bookmarks::BookmarkNodeData& data, - const BookmarkNode* parent_node, + const bookmarks::BookmarkNode* parent_node, int index, bool copy);
diff --git a/chrome/browser/ui/bookmarks/bookmark_editor.cc b/chrome/browser/ui/bookmarks/bookmark_editor.cc index b7c7877..5ce450f 100644 --- a/chrome/browser/ui/bookmarks/bookmark_editor.cc +++ b/chrome/browser/ui/bookmarks/bookmark_editor.cc
@@ -9,6 +9,7 @@ #include "components/bookmarks/browser/bookmark_model.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/bookmarks/bookmark_editor.h b/chrome/browser/ui/bookmarks/bookmark_editor.h index 04fe4aa..6e6366b 100644 --- a/chrome/browser/ui/bookmarks/bookmark_editor.h +++ b/chrome/browser/ui/bookmarks/bookmark_editor.h
@@ -35,25 +35,26 @@ class EditDetails { public: // Returns the type of the existing or new node. - BookmarkNode::Type GetNodeType() const; + bookmarks::BookmarkNode::Type GetNodeType() const; // Returns the resource id for the string resource to use on the window // title for this edit operation. int GetWindowTitleId() const; // Returns an EditDetails instance for the user editing the given bookmark. - static EditDetails EditNode(const BookmarkNode* node); + static EditDetails EditNode(const bookmarks::BookmarkNode* node); // Returns an EditDetails instance for the user adding a bookmark within // a given parent node with a specified index. - static EditDetails AddNodeInFolder(const BookmarkNode* parent_node, - int index, - const GURL& url, - const base::string16& title); + static EditDetails AddNodeInFolder( + const bookmarks::BookmarkNode* parent_node, + int index, + const GURL& url, + const base::string16& title); // Returns an EditDetails instance for the user adding a folder within a // given parent node with a specified index. - static EditDetails AddFolder(const BookmarkNode* parent_node, + static EditDetails AddFolder(const bookmarks::BookmarkNode* parent_node, int index); enum Type { @@ -77,11 +78,11 @@ const Type type; // If type == EXISTING_NODE this gives the existing node. - const BookmarkNode* existing_node; + const bookmarks::BookmarkNode* existing_node; // If type == NEW_URL or type == NEW_FOLDER this gives the initial parent // node to place the new node in. - const BookmarkNode* parent_node; + const bookmarks::BookmarkNode* parent_node; // If type == NEW_URL or type == NEW_FOLDER this gives the index to insert // the new node at. @@ -111,9 +112,9 @@ // done regarding moving from one folder to another). If a new node is // explicitly being added, returns a pointer to the new node that was created. // Otherwise the return value is identically |node|. - static const BookmarkNode* ApplyEditsWithNoFolderChange( + static const bookmarks::BookmarkNode* ApplyEditsWithNoFolderChange( bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, const EditDetails& details, const base::string16& new_title, const GURL& new_url); @@ -122,9 +123,9 @@ // changed and the node will need to be removed and reinserted. If a new node // is explicitly being added, returns a pointer to the new node that was // created. Otherwise the return value is identically |node|. - static const BookmarkNode* ApplyEditsWithPossibleFolderChange( + static const bookmarks::BookmarkNode* ApplyEditsWithPossibleFolderChange( bookmarks::BookmarkModel* model, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, const EditDetails& details, const base::string16& new_title, const GURL& new_url);
diff --git a/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc index ca3c8eef..1f51ee7f 100644 --- a/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc +++ b/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc
@@ -11,6 +11,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc index 92009f43..0d390aa 100644 --- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc +++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/web_contents.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace { @@ -86,7 +87,7 @@ bookmark_drag_(NULL) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); - bookmark_model_= BookmarkModelFactory::GetForProfile(profile); + bookmark_model_ = BookmarkModelFactory::GetForProfile(profile); if (bookmark_model_) bookmark_model_->AddObserver(this); }
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h index 3982070..b182f12 100644 --- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h +++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
@@ -70,17 +70,17 @@ void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; // Overridden from content::WebContentsObserver: void DidNavigateMainFrame(
diff --git a/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc index fe684e8..770be539 100644 --- a/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc +++ b/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc
@@ -14,6 +14,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.cc b/chrome/browser/ui/bookmarks/bookmark_utils.cc index f05929d..ff6b06e 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils.cc +++ b/chrome/browser/ui/bookmarks/bookmark_utils.cc
@@ -39,6 +39,7 @@ #endif using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace chrome {
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.h b/chrome/browser/ui/bookmarks/bookmark_utils.h index b146f76..dbd7d0f7 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils.h +++ b/chrome/browser/ui/bookmarks/bookmark_utils.h
@@ -12,13 +12,13 @@ #include "ui/base/window_open_disposition.h" #include "ui/gfx/native_widget_types.h" -class BookmarkNode; class Browser; class GURL; class PrefService; class Profile; namespace bookmarks { +class BookmarkNode; struct BookmarkNodeData; } @@ -28,11 +28,6 @@ class WebContents; } -namespace extensions { -class CommandService; -class Extension; -} - namespace ui { class DropTargetEvent; } @@ -52,19 +47,19 @@ // background tabs. |navigator| is used to open the URLs. void OpenAll(gfx::NativeWindow parent, content::PageNavigator* navigator, - const std::vector<const BookmarkNode*>& nodes, + const std::vector<const bookmarks::BookmarkNode*>& nodes, WindowOpenDisposition initial_disposition, content::BrowserContext* browser_context); // Convenience for OpenAll() with a single BookmarkNode. void OpenAll(gfx::NativeWindow parent, content::PageNavigator* navigator, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, WindowOpenDisposition initial_disposition, content::BrowserContext* browser_context); // Asks the user before deleting a non-empty bookmark folder. -bool ConfirmDeleteBookmarkNode(const BookmarkNode* node, +bool ConfirmDeleteBookmarkNode(const bookmarks::BookmarkNode* node, gfx::NativeWindow window); // Shows the bookmark all tabs dialog. @@ -72,12 +67,13 @@ // Returns true if OpenAll() can open at least one bookmark of type url // in |selection|. -bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection); +bool HasBookmarkURLs( + const std::vector<const bookmarks::BookmarkNode*>& selection); // Returns true if OpenAll() can open at least one bookmark of type url // in |selection| with incognito mode. bool HasBookmarkURLsAllowedInIncognitoMode( - const std::vector<const BookmarkNode*>& selection, + const std::vector<const bookmarks::BookmarkNode*>& selection, content::BrowserContext* browser_context); // Returns the bookmarkable URL for |web_contents|. @@ -124,7 +120,7 @@ // Returns the drag operations for the specified node. int GetBookmarkDragOperation(content::BrowserContext* browser_context, - const BookmarkNode* node); + const bookmarks::BookmarkNode* node); // Calculates the drop operation given |source_operations| and the ideal // set of drop operations (|operations|). This prefers the following ordering: @@ -137,7 +133,7 @@ int GetBookmarkDropOperation(Profile* profile, const ui::DropTargetEvent& event, const bookmarks::BookmarkNodeData& data, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index); // Returns true if the bookmark data can be dropped on |drop_parent| at @@ -147,7 +143,7 @@ // a child of |drop_parent| at |index|. bool IsValidBookmarkDropLocation(Profile* profile, const bookmarks::BookmarkNodeData& data, - const BookmarkNode* drop_parent, + const bookmarks::BookmarkNode* drop_parent, int index); } // namespace chrome
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc index 4c279d5..8df3292 100644 --- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc +++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc
@@ -12,6 +12,7 @@ #include "ui/base/models/combobox_model_observer.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h index 2f22ec80..9f6c7e83 100644 --- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h +++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h
@@ -13,10 +13,9 @@ #include "components/bookmarks/browser/bookmark_model_observer.h" #include "ui/base/models/combobox_model.h" -class BookmarkNode; - namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // Model for the combobox showing the list of folders to choose from. The @@ -27,7 +26,7 @@ public bookmarks::BookmarkModelObserver { public: RecentlyUsedFoldersComboModel(bookmarks::BookmarkModel* model, - const BookmarkNode* node); + const bookmarks::BookmarkNode* node); ~RecentlyUsedFoldersComboModel() override; // Overridden from ui::ComboboxModel: @@ -43,41 +42,43 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void OnWillRemoveBookmarks(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; // If necessary this function moves |node| into the corresponding folder for // the given |selected_index|. - void MaybeChangeParent(const BookmarkNode* node, int selected_index); + void MaybeChangeParent(const bookmarks::BookmarkNode* node, + int selected_index); private: // Returns the node at the specified |index|. - const BookmarkNode* GetNodeAt(int index); + const bookmarks::BookmarkNode* GetNodeAt(int index); // Removes |node| from |items_|. Does nothing if |node| is not in |items_|. - void RemoveNode(const BookmarkNode* node); + void RemoveNode(const bookmarks::BookmarkNode* node); struct Item; std::vector<Item> items_;
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc index 42db38c..88691b0 100644 --- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc +++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
@@ -16,6 +16,7 @@ #include "ui/base/models/combobox_model_observer.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; // Implementation of ComboboxModelObserver that records when
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 0b47a1a..d0c8e57 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -66,6 +66,7 @@ #include "ash/shell.h" #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" +#include "chrome/browser/ui/browser_commands_chromeos.h" #endif #if defined(OS_LINUX) && !defined(OS_CHROMEOS) @@ -695,6 +696,11 @@ case IDC_TASK_MANAGER: OpenTaskManager(browser_); break; +#if defined(OS_CHROMEOS) + case IDC_TAKE_SCREENSHOT: + TakeScreenshot(); + break; +#endif #if defined(GOOGLE_CHROME_BUILD) case IDC_FEEDBACK: OpenFeedbackDialog(browser_); @@ -966,6 +972,7 @@ !profile()->IsOffTheRecord()); command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); #if defined(OS_CHROMEOS) + command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true); command_updater_.UpdateCommandEnabled(IDC_TOUCH_HUD_PROJECTION_TOGGLE, true); #else // Chrome OS uses the system tray menu to handle multi-profiles.
diff --git a/chrome/browser/ui/browser_commands_chromeos.cc b/chrome/browser/ui/browser_commands_chromeos.cc new file mode 100644 index 0000000..d6e6dbb --- /dev/null +++ b/chrome/browser/ui/browser_commands_chromeos.cc
@@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/browser_commands_chromeos.h" + +#include "ash/accelerators/accelerator_controller.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/screenshot_delegate.h" +#include "ash/shell.h" +#include "base/metrics/user_metrics_action.h" +#include "content/public/browser/user_metrics.h" + +using base::UserMetricsAction; + +void TakeScreenshot() { + content::RecordAction(UserMetricsAction("Menu_Take_Screenshot")); + ash::ScreenshotDelegate* screenshot_delegate = ash::Shell::GetInstance()-> + accelerator_controller()->screenshot_delegate(); + if (screenshot_delegate && + screenshot_delegate->CanTakeScreenshot()) { + screenshot_delegate->HandleTakeScreenshotForAllRootWindows(); + } +}
diff --git a/chrome/browser/ui/browser_commands_chromeos.h b/chrome/browser/ui/browser_commands_chromeos.h new file mode 100644 index 0000000..ab457f1 --- /dev/null +++ b/chrome/browser/ui/browser_commands_chromeos.h
@@ -0,0 +1,11 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BROWSER_COMMANDS_CHROMEOS_H_ +#define CHROME_BROWSER_UI_BROWSER_COMMANDS_CHROMEOS_H_ + +// Takes a screenshot of the entire desktop (not just the browser window). +void TakeScreenshot(); + +#endif // CHROME_BROWSER_UI_BROWSER_COMMANDS_CHROMEOS_H_
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index d4e6aa80..13a0dab 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -221,14 +221,20 @@ // |already_bookmarked| is true if the url is already bookmarked. virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) = 0; + // Callback type used with the ShowBookmarkAppBubble() method. The boolean + // parameter is true when the user accepts the dialog. The WebApplicationInfo + // parameter contains the WebApplicationInfo as edited by the user. + typedef base::Callback<void(bool, const WebApplicationInfo&)> + ShowBookmarkAppBubbleCallback; + // Shows the Bookmark App bubble. // See Extension::InitFromValueFlags::FROM_BOOKMARK for a description of // bookmark apps. // // |web_app_info| is the WebApplicationInfo being converted into an app. - // |extension_id| is the id of the bookmark app. - virtual void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info, - const std::string& extension_id) = 0; + virtual void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const ShowBookmarkAppBubbleCallback& callback) = 0; // Shows the translate bubble. //
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm index f56722c..5b218989 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
@@ -10,6 +10,7 @@ #include "components/bookmarks/test/bookmark_test_helpers.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @implementation FakeAppDelegate
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm index e0db2eb..b0cacec7 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
@@ -14,6 +14,7 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @implementation BookmarkFolderAppleScript
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h index b84365d..c6d7833 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h
@@ -19,7 +19,7 @@ } // Assigns a node, sets its unique ID and also copies temporary values. -- (void)setBookmarkNode:(const BookmarkNode*)aBookmarkNode; +- (void)setBookmarkNode:(const bookmarks::BookmarkNode*)aBookmarkNode; // Returns the URL that the bookmark item holds. - (NSString*)URL;
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm index 210bc70..86a0aa6f 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm
@@ -10,6 +10,7 @@ #include "components/bookmarks/browser/bookmark_model.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkItemAppleScript() @property (nonatomic, copy) NSString* tempURL;
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h index d92e7867..4556e0b7 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h
@@ -9,17 +9,16 @@ #import "chrome/browser/ui/cocoa/applescript/element_applescript.h" -class BookmarkNode; - namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // Contains all the elements that are common to both a bookmark folder and // bookmark item. @interface BookmarkNodeAppleScript : ElementAppleScript { @protected - const BookmarkNode* bookmarkNode_; // weak. + const bookmarks::BookmarkNode* bookmarkNode_; // weak. // Contains the temporary title when a scripter creates a new folder/item with // title specified like // |make new bookmark folder with properties {title:"foo"}|. @@ -31,10 +30,10 @@ - (id)init; // Does not make a folder/item but instead uses an existing one. -- (id)initWithBookmarkNode:(const BookmarkNode*)aBookmarkNode; +- (id)initWithBookmarkNode:(const bookmarks::BookmarkNode*)aBookmarkNode; // Assigns a node, sets its unique ID and also copies temporary values. -- (void)setBookmarkNode:(const BookmarkNode*)aBookmarkNode; +- (void)setBookmarkNode:(const bookmarks::BookmarkNode*)aBookmarkNode; // Get and Set title. - (NSString*)title;
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm index 1d45904..ca63ab2 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm
@@ -16,6 +16,7 @@ #include "components/bookmarks/browser/bookmark_model.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkNodeAppleScript() @property (nonatomic, copy) NSString* tempTitle;
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h index 51508ce6..f7428c4 100644 --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h
@@ -27,6 +27,7 @@ base::scoped_nsobject<DoppelgangerMenuItem> quitDoppelganger_; base::scoped_nsobject<DoppelgangerMenuItem> newDoppelganger_; base::scoped_nsobject<DoppelgangerMenuItem> openDoppelganger_; + base::scoped_nsobject<DoppelgangerMenuItem> closeWindowDoppelganger_; base::scoped_nsobject<DoppelgangerMenuItem> allToFrontDoppelganger_; // Menu items for the currently focused packaged app. base::scoped_nsobject<NSMenuItem> appMenuItem_;
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm index f0f47f94..f809da5 100644 --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
@@ -140,6 +140,14 @@ resourceId:(int)resourceId action:(SEL)action keyEquivalent:(NSString*)keyEquivalent; +// Retain the source item given |menuTag| and |sourceItemTag|. Copy +// the menu item given |menuTag| and |targetItemTag|. +// This is useful when we want a doppelganger with a different source item. +// For example, if there are conflicting key equivalents. +- (id)initWithMenuTag:(NSInteger)menuTag + sourceItemTag:(NSInteger)sourceItemTag + targetItemTag:(NSInteger)targetItemTag + keyEquivalent:(NSString*)keyEquivalent; // Set the title using |resourceId_| and unset the source item's key equivalent. - (void)enableForApp:(const extensions::Extension*)app; // Restore the source item's key equivalent. @@ -173,6 +181,20 @@ return self; } +- (id)initWithMenuTag:(NSInteger)menuTag + sourceItemTag:(NSInteger)sourceItemTag + targetItemTag:(NSInteger)targetItemTag + keyEquivalent:(NSString*)keyEquivalent { + if ((self = [super init])) { + menuItem_.reset([GetItemByTag(menuTag, targetItemTag) copy]); + sourceItem_.reset([GetItemByTag(menuTag, sourceItemTag) retain]); + DCHECK(menuItem_); + DCHECK(sourceItem_); + sourceKeyEquivalent_.reset([[sourceItem_ keyEquivalent] copy]); + } + return self; +} + - (void)enableForApp:(const extensions::Extension*)app { // It seems that two menu items that have the same key equivalent must also // have the same action for the keyboard shortcut to work. (This refers to the @@ -260,6 +282,13 @@ resourceId:0 action:nil keyEquivalent:@"n"]); + // Since the "Close Window" menu item will have the same shortcut as "Close + // Tab" on the Chrome menu, we need to create a doppelganger. + closeWindowDoppelganger_.reset([[DoppelgangerMenuItem alloc] + initWithMenuTag:IDC_FILE_MENU + sourceItemTag:IDC_CLOSE_TAB + targetItemTag:IDC_CLOSE_WINDOW + keyEquivalent:@"w"]); // For apps, the "Window" part of "New Window" is dropped to match the default // menu set given to Cocoa Apps. [[newDoppelganger_ menuItem] setTitle:l10n_util::GetNSString(IDS_NEW_MAC)]; @@ -298,15 +327,7 @@ [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; - AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW); - // Set the expected key equivalent explicitly here because - // -[AppControllerMac adjustCloseWindowMenuItemKeyEquivalent:] sets it to - // "W" (Cmd+Shift+w) when a tabbed window has focus; it will change it back - // to Cmd+w when a non-tabbed window has focus. - NSMenuItem* closeWindowMenuItem = - [[fileMenuItem_ submenu] itemWithTag:IDC_CLOSE_WINDOW]; - [closeWindowMenuItem setKeyEquivalent:@"w"]; - [closeWindowMenuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + [[fileMenuItem_ submenu] addItem:[closeWindowDoppelganger_ menuItem]]; // Edit menu. We copy the menu because the last two items, "Start Dictation" // and "Special Characters" are added by OSX, so we can't copy them @@ -407,6 +428,7 @@ [quitDoppelganger_ enableForApp:app]; [newDoppelganger_ enableForApp:app]; [openDoppelganger_ enableForApp:app]; + [closeWindowDoppelganger_ enableForApp:app]; [appMenuItem_ setTitle:appId]; [[appMenuItem_ submenu] setTitle:title]; @@ -453,6 +475,7 @@ [quitDoppelganger_ disable]; [newDoppelganger_ disable]; [openDoppelganger_ disable]; + [closeWindowDoppelganger_ disable]; } - (void)quitCurrentPlatformApp {
diff --git a/chrome/browser/ui/cocoa/background_gradient_view.mm b/chrome/browser/ui/cocoa/background_gradient_view.mm index fe58356..fdad7a82 100644 --- a/chrome/browser/ui/cocoa/background_gradient_view.mm +++ b/chrome/browser/ui/cocoa/background_gradient_view.mm
@@ -121,10 +121,39 @@ } } +- (void)viewWillStartLiveResize { + [super viewWillStartLiveResize]; + + ui::ThemeProvider* themeProvider = [[self window] themeProvider]; + if (themeProvider && themeProvider->UsingSystemTheme()) { + // The default theme's background image is a subtle texture pattern that + // we can scale without being easily noticed. Optimize this case by + // skipping redraws during live resize. + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawOnSetNeedsDisplay]; + } +} + +- (void)viewDidEndLiveResize { + [super viewDidEndLiveResize]; + + if ([self layerContentsRedrawPolicy] != + NSViewLayerContentsRedrawDuringViewResize) { + // If we have been scaling the layer during live resize, now is the time to + // redraw the layer. + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawDuringViewResize]; + [self setNeedsDisplay:YES]; + } +} + - (void)setFrameOrigin:(NSPoint)origin { // The background color depends on the view's vertical position. This impacts // any child views that draw using this view's functions. - if (NSMinY([self frame]) != origin.y) + // When resizing the window, the view's vertical position (NSMinY) may change + // even though our relative position to the nearest window edge is still the + // same. Don't redraw unnecessarily in this case. + if (![self inLiveResize] && NSMinY([self frame]) != origin.y) [self cr_recursivelySetNeedsDisplay:YES]; [super setFrameOrigin:origin];
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h index 8e62465..ec7f4b9 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h
@@ -26,7 +26,7 @@ - (id)initWithParentWindow:(NSWindow*)parentWindow profile:(Profile*)profile - parent:(const BookmarkNode*)parent + parent:(const bookmarks::BookmarkNode*)parent url:(const GURL&)url title:(const base::string16&)title configuration:(BookmarkEditor::Configuration)configuration;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm index 7079ad71..61de430 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm
@@ -16,6 +16,7 @@ #include "ui/base/l10n/l10n_util_mac.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::WebContents; @implementation BookmarkAllTabsController
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm index 417b84b3..74bdde10 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm
@@ -16,6 +16,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkAllTabsControllerOverride : BookmarkAllTabsController @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h index 587a3b4..09bcef9 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h
@@ -31,26 +31,27 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void ExtensiveBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override; void ExtensiveBookmarkChangesEnded(bookmarks::BookmarkModel* model) override;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm index c08a95b..cac5437 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm
@@ -12,6 +12,7 @@ #include "components/bookmarks/browser/bookmark_model.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; BookmarkBarBridge::BookmarkBarBridge(Profile* profile, BookmarkBarController* controller,
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm index c46c0c3..01b01d7 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
@@ -13,6 +13,7 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // TODO(jrg): use OCMock.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h index 79b1250..83248d2 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h
@@ -25,7 +25,6 @@ @class BookmarkButtonCell; @class BookmarkFolderTarget; @class BookmarkContextMenuCocoaController; -class BookmarkNode; class Browser; class ChromeBookmarkClient; class GURL; @@ -36,6 +35,7 @@ namespace bookmarks { class BookmarkModel; +class BookmarkNode; // Magic numbers from Cole // TODO(jrg): create an objc-friendly version of bookmark_bar_constants.h? @@ -339,7 +339,7 @@ - (void)viewDidMoveToWindow; // Provide a favicon for a bookmark node. May return nil. -- (NSImage*)faviconForNode:(const BookmarkNode*)node; +- (NSImage*)faviconForNode:(const bookmarks::BookmarkNode*)node; // Used for situations where the bookmark bar folder menus should no longer // be actively popping up. Called when the window loses focus, a click has @@ -352,7 +352,7 @@ - (void)closeFolderAndStopTrackingMenus; // Checks if operations such as edit or delete are allowed. -- (BOOL)canEditBookmark:(const BookmarkNode*)node; +- (BOOL)canEditBookmark:(const bookmarks::BookmarkNode*)node; // Checks if bookmark editing is enabled at all. - (BOOL)canEditBookmarks; @@ -373,18 +373,21 @@ - (void)loaded:(bookmarks::BookmarkModel*)model; - (void)beingDeleted:(bookmarks::BookmarkModel*)model; - (void)nodeAdded:(bookmarks::BookmarkModel*)model - parent:(const BookmarkNode*)oldParent index:(int)index; + parent:(const bookmarks::BookmarkNode*)oldParent index:(int)index; - (void)nodeChanged:(bookmarks::BookmarkModel*)model - node:(const BookmarkNode*)node; + node:(const bookmarks::BookmarkNode*)node; - (void)nodeMoved:(bookmarks::BookmarkModel*)model - oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex - newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex; + oldParent:(const bookmarks::BookmarkNode*)oldParent + oldIndex:(int)oldIndex + newParent:(const bookmarks::BookmarkNode*)newParent + newIndex:(int)newIndex; - (void)nodeRemoved:(bookmarks::BookmarkModel*)model - parent:(const BookmarkNode*)oldParent index:(int)index; + parent:(const bookmarks::BookmarkNode*)oldParent + index:(int)index; - (void)nodeFaviconLoaded:(bookmarks::BookmarkModel*)model - node:(const BookmarkNode*)node; + node:(const bookmarks::BookmarkNode*)node; - (void)nodeChildrenReordered:(bookmarks::BookmarkModel*)model - node:(const BookmarkNode*)node; + node:(const bookmarks::BookmarkNode*)node; @end // These APIs should only be used by unit tests (or used internally). @@ -403,7 +406,7 @@ - (int)displayedButtonCount; - (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition; - (void)clearBookmarkBar; -- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node; +- (BookmarkButtonCell*)cellForBookmarkNode:(const bookmarks::BookmarkNode*)node; - (BookmarkButtonCell*)cellForCustomButtonWithText:(NSString*)text image:(NSImage*)image; - (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell xOffset:(int*)xOffset; @@ -415,10 +418,10 @@ - (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point; - (BOOL)isEventAnExitEvent:(NSEvent*)event; - (BOOL)shrinkOrHideView:(NSView*)view forMaxX:(CGFloat)maxViewX; -- (void)unhighlightBookmark:(const BookmarkNode*)node; +- (void)unhighlightBookmark:(const bookmarks::BookmarkNode*)node; // The following are for testing purposes only and are not used internally. -- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node; +- (NSMenu *)menuForFolderNode:(const bookmarks::BookmarkNode*)node; @end #endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm index 36901ce..ea5563b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
@@ -65,6 +65,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; using content::OpenURLParams; using content::Referrer;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm index 06ef982..8ac4371 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -42,6 +42,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // Unit tests don't need time-consuming asynchronous animations. @interface BookmarkBarControllerTestable : BookmarkBarController {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h index c63eedbe..aaa6904e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h
@@ -15,7 +15,7 @@ // Create a button cell which draws without a theme and with a frame // color provided by the ThemeService defaults. -+ (id)buttonCellForNode:(const BookmarkNode*)node ++ (id)buttonCellForNode:(const bookmarks::BookmarkNode*)node text:(NSString*)text image:(NSImage*)image menuController:(BookmarkContextMenuCocoaController*)menuController;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm index 1b6b8b9..9075170 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm
@@ -4,6 +4,8 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h" +using bookmarks::BookmarkNode; + @implementation BookmarkBarFolderButtonCell + (id)buttonCellForNode:(const BookmarkNode*)node
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h index ec27fea3..2d42c81 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h
@@ -164,7 +164,7 @@ // Gets notified when a fav icon asynchronously loads, so we can now use the // real icon instead of a generic placeholder. -- (void)faviconLoadedForNode:(const BookmarkNode*)node; +- (void)faviconLoadedForNode:(const bookmarks::BookmarkNode*)node; - (void)setSelectedButtonByIndex:(int)index;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm index d3fb1df..a0da0c0a 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
@@ -24,6 +24,7 @@ #include "ui/base/theme_provider.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; using bookmarks::kBookmarkBarMenuCornerRadius;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm index e80e3c8..e516169 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
@@ -26,6 +26,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm index 62eb5366..cf12996 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm
@@ -14,6 +14,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; #import "third_party/mozilla/NSPasteboard+Utils.h"
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm index a4a8290..dc3a67f 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
@@ -24,6 +24,7 @@ #import "third_party/ocmock/ocmock_extensions.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // Allows us to verify BookmarkBarFolderView. @interface BookmarkBarFolderView(TestingAPI)
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa.mm index 01e9ec3..ced2de059 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa.mm
@@ -21,6 +21,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkBarView (Private) - (void)themeDidChangeNotification:(NSNotification*)aNotification;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa_unittest.mm index 735106d..d49703355 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_cocoa_unittest.mm
@@ -23,6 +23,7 @@ #import "third_party/mozilla/NSPasteboard+Utils.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h index 06cbf22..708ae71 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h
@@ -9,13 +9,13 @@ #import "chrome/browser/ui/cocoa/base_bubble_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h" -class BookmarkNode; class ChromeBookmarkClient; @class BookmarkBubbleController; @class BookmarkSyncPromoController; namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // Controller for the bookmark bubble. The bookmark bubble is a @@ -28,10 +28,10 @@ // profile. ChromeBookmarkClient* client_; // weak bookmarks::BookmarkModel* model_; // weak - const BookmarkNode* node_; // weak + const bookmarks::BookmarkNode* node_; // weak // The bookmark node whose button we asked to pulse. - const BookmarkNode* pulsingBookmarkNode_; // weak + const bookmarks::BookmarkNode* pulsingBookmarkNode_; // weak BOOL alreadyBookmarked_; @@ -47,7 +47,7 @@ IBOutlet NSView* syncPromoPlaceholder_; } -@property(readonly, nonatomic) const BookmarkNode* node; +@property(readonly, nonatomic) const bookmarks::BookmarkNode* node; // |node| is the bookmark node we edit in this bubble. // |alreadyBookmarked| tells us if the node was bookmarked before the @@ -58,7 +58,7 @@ - (id)initWithParentWindow:(NSWindow*)parentWindow client:(ChromeBookmarkClient*)client model:(bookmarks::BookmarkModel*)model - node:(const BookmarkNode*)node + node:(const bookmarks::BookmarkNode*)node alreadyBookmarked:(BOOL)alreadyBookmarked; // Actions for buttons in the dialog. @@ -78,11 +78,12 @@ @property(nonatomic, readonly) NSView* syncPromoPlaceholder; -- (void)addFolderNodes:(const BookmarkNode*)parent +- (void)addFolderNodes:(const bookmarks::BookmarkNode*)parent toPopUpButton:(NSPopUpButton*)button indentation:(int)indentation; -- (void)setTitle:(NSString*)title parentFolder:(const BookmarkNode*)parent; -- (void)setParentFolderSelection:(const BookmarkNode*)parent; +- (void)setTitle:(NSString*)title + parentFolder:(const bookmarks::BookmarkNode*)parent; +- (void)setParentFolderSelection:(const bookmarks::BookmarkNode*)parent; + (NSString*)chooseAnotherFolderString; - (NSPopUpButton*)folderPopUpButton; @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm index fd1187b9d..5f99e0f 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
@@ -25,6 +25,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // An object to represent the ChooseAnotherFolder item in the pop up. @interface ChooseAnotherFolder : NSObject
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm index 066ef60..d93356f8 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
@@ -28,6 +28,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::WebContents; // Watch for bookmark pulse notifications so we can confirm they were sent.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h index 51bad93..90af2ad1 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h
@@ -10,12 +10,12 @@ @class BookmarkBarFolderController; @class BookmarkButton; -class BookmarkNode; @class BrowserWindowController; class ThemeService; namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // Protocol for a BookmarkButton's delegate, responsible for doing @@ -107,7 +107,7 @@ // Determine if the drag pasteboard has any drag data of type // kBookmarkDictionaryListPboardType and, if so, return those elements // otherwise return an empty vector. -- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData; +- (std::vector<const bookmarks::BookmarkNode*>)retrieveBookmarkNodeData; // Return YES if we should show the drop indicator, else NO. In some // cases (e.g. hover open) we don't want to show the drop indicator. @@ -147,7 +147,7 @@ - (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton; // Open all of the nodes for the given node with disposition. -- (void)openAll:(const BookmarkNode*)node +- (void)openAll:(const bookmarks::BookmarkNode*)node disposition:(WindowOpenDisposition)disposition; // There are several operations which may affect the contents of a bookmark @@ -163,7 +163,7 @@ // Add a button for the given node to the bar or folder menu. This is safe // to call when a folder menu window is open as that window will be updated. // And index of -1 means to append to the end (bottom). -- (void)addButtonForNode:(const BookmarkNode*)node +- (void)addButtonForNode:(const bookmarks::BookmarkNode*)node atIndex:(NSInteger)buttonIndex; // Given a list or |urls| and |titles|, create new bookmark nodes and add @@ -184,7 +184,7 @@ // Determine the controller containing the button representing |node|, if any. - (id<BookmarkButtonControllerProtocol>)controllerForNode: - (const BookmarkNode*)node; + (const bookmarks::BookmarkNode*)node; @end // @protocol BookmarkButtonControllerProtocol @@ -213,7 +213,7 @@ @property(assign, nonatomic) BOOL acceptsTrackIn; // Return the bookmark node associated with this button, or NULL. -- (const BookmarkNode*)bookmarkNode; +- (const bookmarks::BookmarkNode*)bookmarkNode; // Return YES if this is a folder button (the node has subnodes). - (BOOL)isFolder;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm index 449e766..70cfecc 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm
@@ -19,11 +19,11 @@ #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" using base::UserMetricsAction; +using bookmarks::BookmarkNode; // The opacity of the bookmark button drag image. static const CGFloat kDragImageOpacity = 0.7; - namespace bookmark_button { NSString* const kPulseBookmarkButtonNotification =
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h index 0a4b7da..9144e0b2 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h
@@ -8,7 +8,10 @@ #import "chrome/browser/ui/cocoa/gradient_button_cell.h" @class BookmarkContextMenuCocoaController; + +namespace bookmarks { class BookmarkNode; +} // A button cell that handles drawing/highlighting of buttons in the // bookmark bar. This cell forwards mouseEntered/mouseExited events @@ -36,12 +39,13 @@ base::scoped_nsobject<NSColor> textColor_; } -@property(nonatomic, readwrite, assign) const BookmarkNode* bookmarkNode; +@property(nonatomic, readwrite, assign) + const bookmarks::BookmarkNode* bookmarkNode; @property(nonatomic, readwrite, assign) int startingChildIndex; @property(nonatomic, readwrite, assign) BOOL drawFolderArrow; // Create a button cell which draws with a theme. -+ (id)buttonCellForNode:(const BookmarkNode*)node ++ (id)buttonCellForNode:(const bookmarks::BookmarkNode*)node text:(NSString*)text image:(NSImage*)image menuController:(BookmarkContextMenuCocoaController*)menuController; @@ -53,10 +57,10 @@ // Initialize a button cell which draws with a theme. // Designated initializer. -- (id)initForNode:(const BookmarkNode*)node - text:(NSString*)text - image:(NSImage*)image - menuController:(BookmarkContextMenuCocoaController*)menuController; +- (id)initForNode:(const bookmarks::BookmarkNode*)node + text:(NSString*)text + image:(NSImage*)image + menuController:(BookmarkContextMenuCocoaController*)menuController; // Initialize a button cell not attached to any node which draws with a theme. - (id)initWithText:(NSString*)text
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm index 7701d8bd..c861fdc 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
@@ -16,6 +16,7 @@ #include "ui/resources/grit/ui_resources.h" using base::UserMetricsAction; +using bookmarks::BookmarkNode; const int kHierarchyButtonXMargin = 4;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm index ce1bbcd7..4173844a 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm
@@ -17,6 +17,7 @@ #include "ui/resources/grit/ui_resources.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // Simple class to remember how many mouseEntered: and mouseExited: // calls it gets. Only used by BookmarkMouseForwarding but placed
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm index b5d4ee0..d7b8f7e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm
@@ -15,6 +15,7 @@ #import "ui/events/test/cocoa_test_event_utils.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; // Fake BookmarkButton delegate to get a pong on mouse entered/exited @interface FakeButtonDelegate : NSObject<BookmarkButtonDelegate> {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h index e459085..d3b6a16e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h
@@ -14,9 +14,12 @@ @class BookmarkBarController; class BookmarkContextMenuController; class BookmarkContextMenuDelegateBridge; -class BookmarkNode; @class MenuController; +namespace bookmarks { +class BookmarkNode; +} + // A controller to manage bookmark bar context menus. One instance of this // class exists per bookmark bar controller, used for all of its context menus // (including those for items in bookmark bar folder drop downs). @@ -32,7 +35,7 @@ // The current |bookmarkNode_| for which |bookmarkContextMenuController_| and // |menuController_| are initialized. Weak, owned by the BookmarkModel. - const BookmarkNode* bookmarkNode_; + const bookmarks::BookmarkNode* bookmarkNode_; // The cross-platform BookmarkContextMenuController, containing the logic for // which items and corresponding actions exist in the menu. @@ -51,7 +54,7 @@ // only one menu should ever be shown at a time, and thus caches the last // returned menu and re-creates it if a menu for a different node is requested. // Passing in a NULL |node| will return the menu for "empty" placeholder. -- (NSMenu*)menuForBookmarkNode:(const BookmarkNode*)node; +- (NSMenu*)menuForBookmarkNode:(const bookmarks::BookmarkNode*)node; // Returns an NSMenu customized for the bookmark bar. - (NSMenu*)menuForBookmarkBar;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.mm index 95358c7..20362be 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.mm
@@ -14,6 +14,7 @@ #import "ui/base/cocoa/menu_controller.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkContextMenuCocoaController (Private) - (void)willExecuteCommand:(int)command;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm index 89847bfe..1a57eed 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
@@ -23,6 +23,7 @@ #include "ui/base/dragdrop/drag_drop_types.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h index 263bff5..69acb72d 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h
@@ -34,7 +34,7 @@ NSWindow* parentWindow_; // weak Profile* profile_; // weak - const BookmarkNode* parentNode_; // weak; owned by the model + const bookmarks::BookmarkNode* parentNode_; // weak; owned by the model GURL url_; // This and title_ are only used for new urls. base::string16 title_; BookmarkEditor::Configuration configuration_; @@ -61,7 +61,7 @@ - (id)initWithParentWindow:(NSWindow*)parentWindow nibName:(NSString*)nibName profile:(Profile*)profile - parent:(const BookmarkNode*)parent + parent:(const bookmarks::BookmarkNode*)parent url:(const GURL&)url title:(const base::string16&)title configuration:(BookmarkEditor::Configuration)configuration; @@ -97,7 +97,7 @@ // in the bookmark tree view if the tree view is showing, otherwise returns // the original |parentNode_|. If the tree view is showing but nothing is // selected then the root node is returned. -- (const BookmarkNode*)selectedNode; +- (const bookmarks::BookmarkNode*)selectedNode; // Expands the set of BookmarkNodes in |nodes|. - (void)expandNodes:( @@ -108,11 +108,11 @@ // Select/highlight the given node within the browser tree view. If the // node is nil then select the bookmark bar node. Exposed for unit test. -- (void)selectNodeInBrowser:(const BookmarkNode*)node; +- (void)selectNodeInBrowser:(const bookmarks::BookmarkNode*)node; // Notifications called when the BookmarkModel changes out from under me. -- (void)nodeRemoved:(const BookmarkNode*)node - fromParent:(const BookmarkNode*)parent; +- (void)nodeRemoved:(const bookmarks::BookmarkNode*)node + fromParent:(const bookmarks::BookmarkNode*)parent; - (void)modelChangedPreserveSelection:(BOOL)preserve; // Determines if the ok button should be enabled, can be overridden. @@ -121,7 +121,7 @@ // Accessors - (bookmarks::BookmarkModel*)bookmarkModel; - (Profile*)profile; -- (const BookmarkNode*)parentNode; +- (const bookmarks::BookmarkNode*)parentNode; - (const GURL&)url; - (const base::string16&)title; @@ -135,13 +135,13 @@ @interface BookmarkFolderInfo : NSObject { @private NSString* folderName_; - const BookmarkNode* folderNode_; // weak + const bookmarks::BookmarkNode* folderNode_; // weak NSMutableArray* children_; BOOL newFolder_; } @property(nonatomic, copy) NSString* folderName; -@property(nonatomic, assign) const BookmarkNode* folderNode; +@property(nonatomic, assign) const bookmarks::BookmarkNode* folderNode; @property(nonatomic, retain) NSMutableArray* children; @property(nonatomic, assign) BOOL newFolder; @@ -157,7 +157,7 @@ // this session and which have not been committed yet, |newFolder| should be // YES and |folderNode| and |children| should be NULL/nil. - (id)initWithFolderName:(NSString*)folderName - folderNode:(const BookmarkNode*)folderNode + folderNode:(const bookmarks::BookmarkNode*)folderNode children:(NSMutableArray*)children newFolder:(BOOL)newFolder; @@ -165,7 +165,8 @@ // structure. |folderName| and |folderNode| must be provided. |children| // is optional. Private: exposed here for unit testing purposes. + (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName - folderNode:(const BookmarkNode*)folderNode + folderNode: + (const bookmarks::BookmarkNode*)folderNode children:(NSMutableArray*)children; @end @@ -180,7 +181,7 @@ - (void)createNewFolders; // Select the given bookmark node within the tree view. -- (void)selectTestNodeInBrowser:(const BookmarkNode*)node; +- (void)selectTestNodeInBrowser:(const bookmarks::BookmarkNode*)node; // Return the dictionary for the folder selected in the tree. - (BookmarkFolderInfo*)selectedFolder;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm index b5b6ce8c..4034a8b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm
@@ -26,6 +26,7 @@ using bookmarks::BookmarkExpandedStateTracker; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkEditorBaseController ()
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm index 509ea6ca..146dbbc 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm
@@ -21,6 +21,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkExpandedStateTracker; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; class BookmarkEditorBaseControllerTest : public CocoaProfileTest { public:
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h index 0805a6d..6958ddb 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h
@@ -12,7 +12,7 @@ // button. @interface BookmarkEditorController : BookmarkEditorBaseController { @private - const BookmarkNode* node_; // weak; owned by the model + const bookmarks::BookmarkNode* node_; // weak; owned by the model base::scoped_nsobject<NSString> initialUrl_; NSString* displayURL_; // Bound to a text field in the dialog. IBOutlet NSTextField* urlField_; @@ -23,8 +23,8 @@ - (id)initWithParentWindow:(NSWindow*)parentWindow profile:(Profile*)profile - parent:(const BookmarkNode*)parent - node:(const BookmarkNode*)node + parent:(const bookmarks::BookmarkNode*)parent + node:(const bookmarks::BookmarkNode*)node url:(const GURL&)url title:(const base::string16&)title configuration:(BookmarkEditor::Configuration)configuration;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm index acc905f..079e509 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm
@@ -16,6 +16,7 @@ using bookmarks::BookmarkExpandedStateTracker; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface BookmarkEditorController (Private)
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm index e5479dc..6be26984 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm
@@ -18,6 +18,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; class BookmarkEditorControllerTest : public CocoaProfileTest { public:
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h index a7c91009..8c36659 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h
@@ -9,7 +9,6 @@ @class BookmarkButton; @protocol BookmarkButtonControllerProtocol; -class BookmarkNode; class Profile; // Target (in the target/action sense) of a bookmark folder button.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.mm index c8e66ed..c46cbc94 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.mm
@@ -14,6 +14,7 @@ #include "components/bookmarks/browser/bookmark_pasteboard_helper_mac.h" #import "ui/base/cocoa/cocoa_base_utils.h" +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; NSString* kBookmarkButtonDragType = @"ChromiumBookmarkButtonDragType";
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target_unittest.mm index eac0de4..d00cfc81 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target_unittest.mm
@@ -16,6 +16,7 @@ #include "third_party/ocmock/gtest_support.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface OCMockObject(PreventRetainCycle) - (void)clearRecordersAndExpectations;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h index 778127ec..f168282 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h
@@ -26,13 +26,16 @@ #import "chrome/browser/ui/cocoa/main_menu_item.h" #include "components/bookmarks/browser/bookmark_model_observer.h" -class BookmarkNode; class Profile; @class NSImage; @class NSMenu; @class NSMenuItem; @class BookmarkMenuCocoaController; +namespace bookmarks { +class BookmarkNode; +} + class BookmarkMenuBridge : public bookmarks::BookmarkModelObserver, public MainMenuItem { public: @@ -44,26 +47,27 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; // MainMenuItem: void ResetMenu() override; @@ -97,7 +101,7 @@ // If |add_extra_items| is true, also adds extra menu items at bottom of // menu, such as "Open All Bookmarks". void AddNodeAsSubmenu(NSMenu* menu, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, NSImage* image, bool add_extra_items); @@ -106,7 +110,8 @@ // If |add_extra_items| is true, also adds extra menu items at bottom of // menu, such as "Open All Bookmarks". // TODO(jrg): add a counter to enforce maximum nodes added - void AddNodeToMenu(const BookmarkNode* node, NSMenu* menu, + void AddNodeToMenu(const bookmarks::BookmarkNode* node, + NSMenu* menu, bool add_extra_items); // Helper for adding an item to our bookmark menu. An item which has a @@ -114,7 +119,7 @@ // The item is also bound to |node| by tag. |command_id| selects the action. void AddItemToMenu(int command_id, int message_id, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, NSMenu* menu, bool enabled); @@ -124,11 +129,12 @@ // |set_title| is optional since it is only needed when we get a // node changed notification. On initial build of the menu we set // the title as part of alloc/init. - void ConfigureMenuItem(const BookmarkNode* node, NSMenuItem* item, + void ConfigureMenuItem(const bookmarks::BookmarkNode* node, + NSMenuItem* item, bool set_title); // Returns the NSMenuItem for a given BookmarkNode. - NSMenuItem* MenuItemForNode(const BookmarkNode* node); + NSMenuItem* MenuItemForNode(const bookmarks::BookmarkNode* node); // Start watching the bookmarks for changes. void ObserveBookmarkModel(); @@ -147,7 +153,7 @@ // In order to appropriately update items in the bookmark menu, without // forcing a rebuild, map the model's nodes to menu items. - std::map<const BookmarkNode*, NSMenuItem*> bookmark_nodes_; + std::map<const bookmarks::BookmarkNode*, NSMenuItem*> bookmark_nodes_; }; #endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm index e0f938bc..00915f8e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
@@ -25,6 +25,7 @@ #include "ui/resources/grit/ui_resources.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; BookmarkMenuBridge::BookmarkMenuBridge(Profile* profile, NSMenu* menu) : menuIsValid_(false),
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm index 10b1822..1ee0f88b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm
@@ -20,6 +20,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; class TestBookmarkMenuBridge : public BookmarkMenuBridge { public:
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h index 3652a53..2e18f7d 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h
@@ -14,9 +14,12 @@ #import "base/mac/scoped_nsobject.h" #include "ui/base/window_open_disposition.h" -class BookmarkNode; class BookmarkMenuBridge; +namespace bookmarks { +class BookmarkNode; +} + @interface BookmarkMenuCocoaController : NSObject<NSMenuDelegate> { @private BookmarkMenuBridge* bridge_; // weak; owns me @@ -28,10 +31,10 @@ // Return an autoreleased string to be used as a menu title for the // given bookmark node. -+ (NSString*)menuTitleForNode:(const BookmarkNode*)node; ++ (NSString*)menuTitleForNode:(const bookmarks::BookmarkNode*)node; // Make a relevant tooltip string for node. -+ (NSString*)tooltipForNode:(const BookmarkNode*)node; ++ (NSString*)tooltipForNode:(const bookmarks::BookmarkNode*)node; - (id)initWithBridge:(BookmarkMenuBridge *)bridge andMenu:(NSMenu*)menu; @@ -47,8 +50,8 @@ @interface BookmarkMenuCocoaController (ExposedForUnitTests) -- (const BookmarkNode*)nodeForIdentifier:(int)identifier; -- (void)openURLForNode:(const BookmarkNode*)node; +- (const bookmarks::BookmarkNode*)nodeForIdentifier:(int)identifier; +- (void)openURLForNode:(const bookmarks::BookmarkNode*)node; - (void)openAll:(NSInteger)tag withDisposition:(WindowOpenDisposition)disposition; @end // BookmarkMenuCocoaController (ExposedForUnitTests)
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm index 010ec6a..d5734c0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm
@@ -20,6 +20,7 @@ #import "ui/base/cocoa/menu_controller.h" using base::UserMetricsAction; +using bookmarks::BookmarkNode; using content::OpenURLParams; using content::Referrer;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm index 4f02ab63..b702282 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm
@@ -14,6 +14,7 @@ #include "testing/gtest/include/gtest/gtest.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @interface FakeBookmarkMenuController : BookmarkMenuCocoaController { @public
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h index 7d7f1868..cf3e2e2c 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
@@ -42,25 +42,25 @@ // Starts and stops observing a specified |node|; the node must be contained // within the model. - void StartObservingNode(const BookmarkNode* node); - void StopObservingNode(const BookmarkNode* node); + void StartObservingNode(const bookmarks::BookmarkNode* node); + void StopObservingNode(const bookmarks::BookmarkNode* node); // bookmarks::BookmarkModelObserver: void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; // Some notifications we don't care about, but by being pure virtual // in the base class we must implement them. @@ -68,12 +68,14 @@ void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override {} void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override {} - void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override {} - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override {} + void BookmarkNodeFaviconChanged( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override {} + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override {} void ExtensiveBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override {} @@ -83,7 +85,8 @@ private: bookmarks::BookmarkModel* model_; // Weak; it is owned by a Profile. - std::set<const BookmarkNode*> nodes_; // Weak items owned by a BookmarkModel. + std::set<const bookmarks::BookmarkNode*> + nodes_; // Weak items owned by a BookmarkModel. base::mac::ScopedBlock<ChangeCallback> callback_; // Send a notification to the client; |deleted| is YES if an observed node was
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm index 0368e58..d9d6fab 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; BookmarkModelObserverForCocoa::BookmarkModelObserverForCocoa( BookmarkModel* model,
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm index d480f800..58d6f725 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm
@@ -12,6 +12,7 @@ #include "chrome/test/base/testing_profile.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h index 09f7b59..e73aa04 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h
@@ -11,9 +11,12 @@ #include "base/memory/scoped_ptr.h" class BookmarkModelObserverForCocoa; -class BookmarkNode; class Profile; +namespace bookmarks { +class BookmarkNode; +} + // A controller for dialog to let the user create a new folder or // rename an existing folder. Accessible from a context menu on a // bookmark button or the bookmark bar. @@ -28,8 +31,8 @@ // Weak; owned by the model. Can be NULL (see below). Either node_ // is non-NULL (renaming a folder), or parent_ is non-NULL (adding a // new one). - const BookmarkNode* node_; - const BookmarkNode* parent_; + const bookmarks::BookmarkNode* node_; + const bookmarks::BookmarkNode* parent_; int newIndex_; base::scoped_nsobject<NSString> initialName_; @@ -45,10 +48,10 @@ // node. - (id)initWithParentWindow:(NSWindow*)window profile:(Profile*)profile - node:(const BookmarkNode*)node; + node:(const bookmarks::BookmarkNode*)node; - (id)initWithParentWindow:(NSWindow*)window profile:(Profile*)profile - parent:(const BookmarkNode*)parent + parent:(const bookmarks::BookmarkNode*)parent newIndex:(int)newIndex; - (void)runAsModalSheet; - (IBAction)cancel:(id)sender;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm index 5439737..6b47a05 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm
@@ -14,6 +14,7 @@ #include "ui/base/l10n/l10n_util_mac.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; @implementation BookmarkNameFolderController
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm index 69fffc77..7e9a3b0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm
@@ -17,6 +17,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; class BookmarkNameFolderControllerTest : public CocoaProfileTest { };
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h index 7083ed28..25479f9 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h
@@ -7,7 +7,9 @@ #import <Cocoa/Cocoa.h> +namespace bookmarks { class BookmarkNode; +} // Provides a custom cell as used in the BookmarkEditor.xib's folder tree // browser view. This cell customization adds target and action support @@ -16,7 +18,7 @@ // control in which is contained the cell. @interface BookmarkTreeBrowserCell : NSBrowserCell { @private - const BookmarkNode* bookmarkNode_; // weak + const bookmarks::BookmarkNode* bookmarkNode_; // weak NSMatrix* matrix_; // weak id target_; // weak SEL action_; @@ -26,8 +28,8 @@ @property(nonatomic, assign) id target; @property(nonatomic, assign) SEL action; -- (const BookmarkNode*)bookmarkNode; -- (void)setBookmarkNode:(const BookmarkNode*)bookmarkNode; +- (const bookmarks::BookmarkNode*)bookmarkNode; +- (void)setBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode; @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.mm index d914132c..7836801 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.mm
@@ -6,6 +6,8 @@ #include "components/bookmarks/browser/bookmark_model.h" +using bookmarks::BookmarkNode; + @implementation BookmarkTreeBrowserCell @synthesize matrix = matrix_;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm index 8c6042d..48a70b8 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm
@@ -9,6 +9,8 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "testing/platform_test.h" +using bookmarks::BookmarkNode; + class BookmarkTreeBrowserCellTest : public PlatformTest { public: BookmarkTreeBrowserCellTest() {
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index e7e6d809..018d88c 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -106,8 +106,9 @@ Profile* profile) override; void ShowUpdateChromeDialog() override; void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override; - void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info, - const std::string& extension_id) override; + void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const ShowBookmarkAppBubbleCallback& callback) override; void ShowTranslateBubble(content::WebContents* contents, translate::TranslateStep step, translate::TranslateErrors::Type error_type,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 0079cf18..b8cb5a5 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -14,17 +14,12 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/download/download_shelf.h" -#include "chrome/browser/extensions/bookmark_app_helper.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/fullscreen.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/signin/signin_header_helper.h" #include "chrome/browser/translate/chrome_translate_client.h" -#include "chrome/browser/ui/app_list/app_list_util.h" -#include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_commands_mac.h" @@ -52,7 +47,6 @@ #include "chrome/browser/ui/search/search_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/web_applications/web_app.h" -#include "chrome/browser/web_applications/web_app_mac.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" @@ -64,7 +58,6 @@ #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" -#include "extensions/browser/pref_names.h" #include "extensions/common/constants.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/gfx/geometry/rect.h" @@ -503,9 +496,7 @@ void BrowserWindowCocoa::ShowBookmarkAppBubble( const WebApplicationInfo& web_app_info, - const std::string& extension_id) { - Profile* profile = browser_->profile(); - + const ShowBookmarkAppBubbleCallback& callback) { base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); [alert setMessageText:l10n_util::GetNSString(IDS_BOOKMARK_APP_BUBBLE_TITLE)]; [alert setAlertStyle:NSInformationalAlertStyle]; @@ -522,10 +513,7 @@ [open_as_window_checkbox setButtonType:NSSwitchButton]; [open_as_window_checkbox setTitle:l10n_util::GetNSString(IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_WINDOW)]; - [open_as_window_checkbox setState: - profile->GetPrefs()->GetInteger( - extensions::pref_names::kBookmarkAppCreationLaunchType) == - extensions::LAUNCH_TYPE_WINDOW]; + [open_as_window_checkbox setState:web_app_info.open_as_window]; [open_as_window_checkbox sizeToFit]; base::scoped_nsobject<NSTextField> app_title([[NSTextField alloc] @@ -557,59 +545,18 @@ } } - ExtensionService* service = - extensions::ExtensionSystem::Get(profile)->extension_service(); if ([alert runModal] == NSAlertFirstButtonReturn) { - // Save launch type preferences for later when creating another hosted app. - extensions::LaunchType launch_type = - [open_as_window_checkbox state] == NSOnState - ? extensions::LAUNCH_TYPE_WINDOW - : extensions::LAUNCH_TYPE_REGULAR; - profile->GetPrefs()->SetInteger( - extensions::pref_names::kBookmarkAppCreationLaunchType, launch_type); - extensions::SetLaunchType(profile, extension_id, launch_type); + WebApplicationInfo updated_info = web_app_info; + updated_info.open_as_window = [open_as_window_checkbox state] == NSOnState; - // Update name of app. NSString* new_title = [app_title stringValue]; - if (![original_title isEqualToString:new_title]) { - WebApplicationInfo new_web_app_info(web_app_info); - new_web_app_info.title = base::SysNSStringToUTF16(new_title); - extensions::CreateOrUpdateBookmarkApp(service, &new_web_app_info); - } + updated_info.title = base::SysNSStringToUTF16(new_title); - // If we're not creating app shims, no need to reveal it in Finder. - // Otherwise reveal the app in the app launcher. If not installed, - // then open the chrome://apps page. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableHostedAppShimCreation)) { - extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile); - const extensions::Extension* app = registry->GetExtensionById( - extension_id, extensions::ExtensionRegistry::ENABLED); - - web_app::RevealAppShimInFinderForApp(profile, app); - } else { - if (IsAppLauncherEnabled()) { - AppListService::Get(chrome::GetHostDesktopTypeForNativeWindow( - browser_->window()->GetNativeWindow())) - ->ShowForAppInstall(profile, extension_id, false); - } else { - chrome::NavigateParams params(profile, GURL(chrome::kChromeUIAppsURL), - ui::PAGE_TRANSITION_LINK); - params.disposition = SINGLETON_TAB; - chrome::Navigate(¶ms); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, - content::Source<content::WebContents>(params.target_contents), - content::Details<const std::string>(&extension_id)); - } - } - } else { - service->UninstallExtension(extension_id, - extensions::UNINSTALL_REASON_INSTALL_CANCELED, - base::Bind(&base::DoNothing), NULL); + callback.Run(true, updated_info); + return; } + + callback.Run(false, web_app_info); } void BrowserWindowCocoa::ShowTranslateBubble(
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index 16ba21ee..23c8d1d 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -353,11 +353,10 @@ // Gets the window style. - (ThemedWindowStyle)themedWindowStyle; -// Returns the position in the coordinates of the root view -// ([[self contentView] superview]) that the top left of a theme image with -// |alignment| should be painted at. If the window does not have a tab strip, -// the offset for THEME_IMAGE_ALIGN_WITH_FRAME is always returned. The result of -// this method can be used in conjunction with +// Returns the position in window coordinates that the top left of a theme +// image with |alignment| should be painted at. If the window does not have a +// tab strip, the offset for THEME_IMAGE_ALIGN_WITH_FRAME is always returned. +// The result of this method can be used in conjunction with // [NSGraphicsContext cr_setPatternPhase:] to set the offset of pattern colors. - (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 151ae0e..1afc906 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -99,6 +99,7 @@ #include "ui/gfx/mac/scoped_ns_disable_screen_updates.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using l10n_util::GetStringUTF16; using l10n_util::GetNSStringWithFixup; using l10n_util::GetNSStringFWithFixup;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index 1ed775b..6245b80 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -377,7 +377,7 @@ // Add the tab strip after setting the content view and moving the incognito // badge (if any), so that the tab strip will be on top (in the z-order). if ([self hasTabStrip]) - [self insertTabStripView:tabStripView intoWindow:destWindow]; + [[destWindow contentView] addSubview:tabStripView]; [sourceWindow setWindowController:nil]; [self setWindow:destWindow]; @@ -845,8 +845,9 @@ [presentationModeController_ toolbarFraction]]; [layout setHasTabStrip:[self hasTabStrip]]; - NSButton* fullScreenButton = - [[self window] standardWindowButton:NSWindowFullScreenButton]; + // NSWindowFullScreenButton is 10.7+ and results in log spam on 10.6 if used. + NSButton* fullScreenButton = base::mac::IsOSSnowLeopard() ? + nil : [[self window] standardWindowButton:NSWindowFullScreenButton]; [layout setFullscreenButtonFrame:fullScreenButton ? [fullScreenButton frame] : NSZeroRect]; if ([self shouldShowAvatar]) {
diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm index c290f70..7ad19907 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.mm +++ b/chrome/browser/ui/cocoa/framed_browser_window.mm
@@ -41,7 +41,6 @@ - (void)adjustZoomButton:(NSNotification*)notification; - (void)adjustButton:(NSButton*)button ofKind:(NSWindowButton)kind; -- (NSView*)frameView; @end @@ -111,10 +110,6 @@ selector:@selector(adjustZoomButton:) name:NSViewFrameDidChangeNotification object:zoomButton_]; - [center addObserver:self - selector:@selector(themeDidChangeNotification:) - name:kBrowserThemeDidChangeNotification - object:nil]; } return self; @@ -143,7 +138,6 @@ - (void)adjustButton:(NSButton*)button ofKind:(NSWindowButton)kind { NSRect buttonFrame = [button frame]; - NSRect frameViewBounds = [[self frameView] bounds]; CGFloat xOffset = hasTabStrip_ ? kFramedWindowButtonsWithTabStripOffsetFromLeft @@ -152,7 +146,7 @@ ? kFramedWindowButtonsWithTabStripOffsetFromTop : kFramedWindowButtonsWithoutTabStripOffsetFromTop; buttonFrame.origin = - NSMakePoint(xOffset, (NSHeight(frameViewBounds) - + NSMakePoint(xOffset, (NSHeight([self frame]) - NSHeight(buttonFrame) - yOffset)); switch (kind) { @@ -174,10 +168,6 @@ [button setPostsFrameChangedNotifications:didPost]; } -- (NSView*)frameView { - return [[self contentView] superview]; -} - // The tab strip view covers our window buttons. So we add hit testing here // to find them properly and return them to the accessibility system. - (id)accessibilityHitTest:(NSPoint)point { @@ -196,60 +186,6 @@ return value; } -- (void)windowMainStatusChanged { - NSView* frameView = [self frameView]; - NSView* contentView = [self contentView]; - NSRect updateRect = [frameView frame]; - NSRect contentRect = [contentView frame]; - CGFloat tabStripHeight = [TabStripController defaultTabHeight]; - updateRect.size.height -= NSHeight(contentRect) - tabStripHeight; - updateRect.origin.y = NSMaxY(contentRect) - tabStripHeight; - [[self frameView] setNeedsDisplayInRect:updateRect]; -} - -- (void)becomeMainWindow { - [self windowMainStatusChanged]; - [super becomeMainWindow]; -} - -- (void)resignMainWindow { - [self windowMainStatusChanged]; - [super resignMainWindow]; -} - -// Called after the current theme has changed. -- (void)themeDidChangeNotification:(NSNotification*)aNotification { - [[self frameView] setNeedsDisplay:YES]; -} - -- (void)sendEvent:(NSEvent*)event { - // For Cocoa windows, clicking on the close and the miniaturize buttons (but - // not the zoom button) while a window is in the background does NOT bring - // that window to the front. We don't get that behavior for free (probably - // because the tab strip view covers those buttons), so we handle it here. - // Zoom buttons do bring the window to the front. Note that Finder windows (in - // Leopard) behave differently in this regard in that zoom buttons don't bring - // the window to the foreground. - BOOL eventHandled = NO; - if (![self isMainWindow]) { - if ([event type] == NSLeftMouseDown) { - NSView* frameView = [self frameView]; - NSPoint mouse = [frameView convertPoint:[event locationInWindow] - fromView:nil]; - if (NSPointInRect(mouse, [closeButton_ frame])) { - [closeButton_ mouseDown:event]; - eventHandled = YES; - } else if (NSPointInRect(mouse, [miniaturizeButton_ frame])) { - [miniaturizeButton_ mouseDown:event]; - eventHandled = YES; - } - } - } - if (!eventHandled) { - [super sendEvent:event]; - } -} - - (void)setShouldHideTitle:(BOOL)flag { shouldHideTitle_ = flag; } @@ -367,14 +303,6 @@ NSPoint position = [[view window] themeImagePositionForAlignment: THEME_IMAGE_ALIGN_WITH_FRAME]; - - // Align the phase to physical pixels so resizing the window under HiDPI - // doesn't cause wiggling of the theme. - NSView* frameView = [[[view window] contentView] superview]; - position = [frameView convertPointToBase:position]; - position.x = floor(position.x); - position.y = floor(position.y); - position = [frameView convertPointFromBase:position]; [[NSGraphicsContext currentContext] cr_setPatternPhase:position forView:view]; @@ -400,10 +328,9 @@ if (overlayImage) { // Anchor to top-left and don't scale. - NSView* frameView = [[[view window] contentView] superview]; NSPoint position = [[view window] themeImagePositionForAlignment: THEME_IMAGE_ALIGN_WITH_FRAME]; - position = [view convertPoint:position fromView:frameView]; + position = [view convertPoint:position fromView:nil]; NSSize overlaySize = [overlayImage size]; NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height); [overlayImage drawAtPoint:NSMakePoint(position.x,
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.h b/chrome/browser/ui/cocoa/history_menu_bridge.h index d7f3041..fee5e95 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge.h +++ b/chrome/browser/ui/cocoa/history_menu_bridge.h
@@ -21,7 +21,6 @@ #include "components/history/core/browser/history_service_observer.h" #include "components/sessions/session_id.h" -class PageUsageData; class Profile; class TabRestoreService; @class HistoryMenuCocoaController;
diff --git a/chrome/browser/ui/cocoa/history_overlay_controller.mm b/chrome/browser/ui/cocoa/history_overlay_controller.mm index 88237a3..e78a9e3b 100644 --- a/chrome/browser/ui/cocoa/history_overlay_controller.mm +++ b/chrome/browser/ui/cocoa/history_overlay_controller.mm
@@ -5,6 +5,7 @@ #import "chrome/browser/ui/cocoa/history_overlay_controller.h" #include "base/logging.h" +#include "base/mac/scoped_cftyperef.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -36,6 +37,7 @@ @private HistoryOverlayMode mode_; CGFloat shieldAlpha_; + base::scoped_nsobject<CAShapeLayer> shapeLayer_; } @property(nonatomic) CGFloat shieldAlpha; - (id)initWithMode:(HistoryOverlayMode)mode @@ -51,6 +53,12 @@ NSRect frame = NSMakeRect(0, 0, kShieldWidth, kShieldHeight); if ((self = [super initWithFrame:frame])) { mode_ = mode; + shieldAlpha_ = 1.0; // CAShapeLayer's fillColor defaults to opaque black. + + // A layer-hosting view. + shapeLayer_.reset([[CAShapeLayer alloc] init]); + [self setLayer:shapeLayer_]; + [self setWantsLayer:YES]; // If going backward, the arrow needs to be in the right half of the circle, // so offset the X position. @@ -67,11 +75,25 @@ return self; } -- (void)drawRect:(NSRect)dirtyRect { - NSBezierPath* path = [NSBezierPath bezierPathWithOvalInRect:self.bounds]; - NSColor* fillColor = [NSColor colorWithCalibratedWhite:0 alpha:shieldAlpha_]; - [fillColor set]; - [path fill]; +- (void)setFrameSize:(CGSize)newSize { + NSSize oldSize = [self frame].size; + [super setFrameSize:newSize]; + + if (![shapeLayer_ path] || !NSEqualSizes(oldSize, newSize)) { + base::ScopedCFTypeRef<CGMutablePathRef> oval(CGPathCreateMutable()); + CGRect ovalRect = CGRectMake(0, 0, newSize.width, newSize.height); + CGPathAddEllipseInRect(oval, nullptr, ovalRect); + [shapeLayer_ setPath:oval]; + } +} + +- (void)setShieldAlpha:(CGFloat)shieldAlpha { + if (shieldAlpha != shieldAlpha_) { + shieldAlpha_ = shieldAlpha; + base::ScopedCFTypeRef<CGColorRef> fillColor( + CGColorCreateGenericGray(0, shieldAlpha)); + [shapeLayer_ setFillColor:fillColor]; + } } @end @@ -129,13 +151,12 @@ self.view.frame = frame; [contentView_ setShieldAlpha:shieldAlpha]; - [contentView_ setNeedsDisplay:YES]; } - (void)showPanelForView:(NSView*)view { parent_.reset([view retain]); [self setProgress:0 finished:NO]; // Set initial view position. - [parent_ addSubview:self.view]; + [parent_ addSubview:self.view]; } - (void)dismiss { @@ -143,25 +164,8 @@ [NSAnimationContext beginGrouping]; [NSAnimationContext currentContext].duration = kFadeOutDurationSeconds; - NSView* overlay = self.view; - - base::scoped_nsobject<CAAnimation> animation( - [[overlay animationForKey:@"alphaValue"] copy]); - [animation setDelegate:self]; - [animation setDuration:kFadeOutDurationSeconds]; - NSMutableDictionary* dictionary = - [NSMutableDictionary dictionaryWithCapacity:1]; - [dictionary setObject:animation forKey:@"alphaValue"]; - [overlay setAnimations:dictionary]; - [[overlay animator] setAlphaValue:0.0]; + [[self.view animator] removeFromSuperview]; [NSAnimationContext endGrouping]; } -- (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)finished { - [self.view removeFromSuperview]; - // Destroy the CAAnimation and its strong reference to its delegate (this - // class). - [self.view setAnimations:nil]; -} - @end
diff --git a/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm b/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm index d2224cf5..91db9b0 100644 --- a/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm
@@ -4,13 +4,7 @@ #import "chrome/browser/ui/cocoa/history_overlay_controller.h" -#import <QuartzCore/QuartzCore.h> - -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_pump_mac.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "third_party/ocmock/gtest_support.h" -#import "third_party/ocmock/OCMock/OCMock.h" class HistoryOverlayControllerTest : public CocoaTest { public: @@ -32,9 +26,7 @@ base::scoped_nsobject<NSView> test_view_; }; -// Tests that when the controller is |-dismiss|ed, the animation runs and then -// is removed when the animation completes. The view should be added and -// removed at the appropriate times. +// Tests that the overlay view gets added and removed at the appropriate times. TEST_F(HistoryOverlayControllerTest, DismissClearsAnimationsAndRemovesView) { EXPECT_EQ(0u, [[test_view() subviews] count]); @@ -43,40 +35,8 @@ [controller showPanelForView:test_view()]; EXPECT_EQ(1u, [[test_view() subviews] count]); - scoped_ptr<base::MessagePumpNSRunLoop> message_pump( - new base::MessagePumpNSRunLoop); - - id mock = [OCMockObject partialMockForObject:controller]; - [mock setExpectationOrderMatters:YES]; - [[[mock expect] andForwardToRealObject] dismiss]; - - // Called after |-animationDidStop:finished:|. - base::MessagePumpNSRunLoop* weak_message_pump = message_pump.get(); - void (^quit_loop)(NSInvocation* invocation) = ^(NSInvocation* invocation) { - weak_message_pump->Quit(); - }; - // Set up the mock to first forward to the real implementation and then call - // the above block to quit the run loop. - [[[[mock expect] andForwardToRealObject] andDo:quit_loop] - animationDidStop:[OCMArg isNotNil] finished:YES]; - - // CAAnimations must be committed within a run loop. It is not sufficient - // to commit them and activate the loop after the fact. Schedule a block to - // dismiss the controller from within the run loop, which begins the - // animation. - CFRunLoopPerformBlock(CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode, - ^(void) { - [mock dismiss]; - }); - - // Run the loop, which will dismiss the overlay. - message_pump->Run(NULL); - - EXPECT_OCMOCK_VERIFY(mock); - - // After the animation runs, there should be no more animations. - EXPECT_FALSE([[controller view] animations]); - + // We expect the view to be removed from its superview immediately + // after dismiss, even though it may still be animating a fade out. + [controller dismiss]; EXPECT_EQ(0u, [[test_view() subviews] count]); }
diff --git a/chrome/browser/ui/cocoa/infobars/alternate_nav_infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/alternate_nav_infobar_controller.mm index 30d1e79..c8873ed 100644 --- a/chrome/browser/ui/cocoa/infobars/alternate_nav_infobar_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/alternate_nav_infobar_controller.mm
@@ -30,15 +30,16 @@ size_t offset = base::string16::npos; base::string16 message = delegate->GetMessageTextWithOffset(&offset); base::string16 link = delegate->GetLinkText(); + message.insert(offset, link); NSFont* font = [NSFont labelFontOfSize: [NSFont systemFontSizeForControlSize:NSRegularControlSize]]; HyperlinkTextView* view = (HyperlinkTextView*)label_.get(); - [view setMessageAndLink:base::SysUTF16ToNSString(message) - withLink:base::SysUTF16ToNSString(link) - atOffset:offset - font:font - messageColor:[NSColor blackColor] - linkColor:[NSColor blueColor]]; + [view setMessage:base::SysUTF16ToNSString(message) + withFont:font + messageColor:[NSColor blackColor]]; + [view addLinkRange:NSMakeRange(offset, link.length()) + withName:@"" + linkColor:[NSColor blueColor]]; } // Called when someone clicks on the link in the infobar. This method
diff --git a/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm index 6affa4e9..4e8c1fe 100644 --- a/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm
@@ -108,20 +108,22 @@ // Set the text and link. NSString* message = base::SysUTF16ToNSString(delegate->GetMessageText()); - base::string16 link = delegate->GetLinkText(); - if (!link.empty()) { + NSString* link = base::SysUTF16ToNSString(delegate->GetLinkText()); + NSUInteger linkOffset = [message length]; + NSUInteger linkLength = [link length]; + if (linkLength != 0) { // Add spacing between the label and the link. - message = [message stringByAppendingString:@" "]; + message = [message stringByAppendingFormat:@" %@", link]; } NSFont* font = [NSFont labelFontOfSize: [NSFont systemFontSizeForControlSize:NSRegularControlSize]]; HyperlinkTextView* view = (HyperlinkTextView*)label_.get(); - [view setMessageAndLink:message - withLink:base::SysUTF16ToNSString(link) - atOffset:[message length] - font:font - messageColor:[NSColor blackColor] - linkColor:[NSColor blueColor]]; + [view setMessage:message withFont:font messageColor:[NSColor blackColor]]; + if (linkLength != 0) { + [view addLinkRange:NSMakeRange(linkOffset, linkLength) + withName:@"" + linkColor:[NSColor blueColor]]; + } } // Called when someone clicks on the link in the infobar. This method
diff --git a/chrome/browser/ui/cocoa/new_tab_button.h b/chrome/browser/ui/cocoa/new_tab_button.h index 97b84822..8b2ddcf6 100644 --- a/chrome/browser/ui/cocoa/new_tab_button.h +++ b/chrome/browser/ui/cocoa/new_tab_button.h
@@ -7,12 +7,14 @@ #import <Cocoa/Cocoa.h> +#import "chrome/browser/ui/cocoa/themed_window.h" + // Overrides hit-test behavior to only accept clicks inside the image of the // button, not just inside the bounding box. This could be abstracted to general // use, but no other buttons are so irregularly shaped with respect to their // bounding box. -@interface NewTabButton : NSButton +@interface NewTabButton : NSButton<ThemedWindowDrawing> // Returns YES if the given point is over the button. |point| is in the // superview's coordinate system.
diff --git a/chrome/browser/ui/cocoa/new_tab_button.mm b/chrome/browser/ui/cocoa/new_tab_button.mm index 7c4d70d..e3e88f0 100644 --- a/chrome/browser/ui/cocoa/new_tab_button.mm +++ b/chrome/browser/ui/cocoa/new_tab_button.mm
@@ -55,4 +55,14 @@ return nil; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm index 26c7c4eb..50e2931 100644 --- a/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm +++ b/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm
@@ -232,6 +232,7 @@ // Set the text. NSString* learnMoreText = l10n_util::GetNSStringWithFixup(IDS_LEARN_MORE); NSString* messageText; + NSUInteger learnMoreOffset = 0; ui::ResourceBundle::FontStyle fontStyle = isSyncDialog_ ? chrome_style::kTextFontStyle : ui::ResourceBundle::SmallFont; @@ -243,20 +244,21 @@ if (isSyncDialog_) { messageText = l10n_util::GetNSStringFWithFixup( IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW, email_); - messageText = [messageText stringByAppendingString:@" "]; + learnMoreOffset = [messageText length]; + messageText = [messageText stringByAppendingFormat:@" %@", learnMoreText]; } else { - messageText = @""; + messageText = learnMoreText; } NSColor* linkColor = gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); - [informativeTextView_ setMessageAndLink:messageText - withLink:learnMoreText - atOffset:[messageText length] - font:font - messageColor:[NSColor blackColor] - linkColor:linkColor]; - + [informativeTextView_ setMessage:messageText + withFont:font + messageColor:[NSColor blackColor]]; + [informativeTextView_ addLinkRange:NSMakeRange(learnMoreOffset, + [learnMoreText length]) + withName:@"" + linkColor:linkColor]; // Make the "Advanced" link font as large as the "Learn More" link. [[advancedLink_ cell] setFont:font];
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm index cc43140..0732470c 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -166,14 +166,17 @@ [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); NSColor* link_color = gfx::SkColorToCalibratedNSColor( chrome_style::GetLinkColor()); + NSMutableString* finalMessage = + [NSMutableString stringWithFormat:@"%@\n", message]; + [finalMessage insertString:link atIndex:link_offset]; // Adds a padding row at the bottom, because |boundingRectWithSize| below cuts // off the last row sometimes. - [text_view setMessageAndLink:[NSString stringWithFormat:@"%@\n", message] - withLink:link - atOffset:link_offset - font:[NSFont labelFontOfSize:kTextFontSize] - messageColor:[NSColor blackColor] - linkColor:link_color]; + [text_view setMessage:finalMessage + withFont:[NSFont labelFontOfSize:kTextFontSize] + messageColor:[NSColor blackColor]]; + [text_view addLinkRange:NSMakeRange(link_offset, [link length]) + withName:@"" + linkColor:link_color]; // Removes the underlining from the link. [text_view setLinkTextAttributes:nil]; @@ -1781,8 +1784,15 @@ imageTitleSpacing:kImageTitleSpacing backgroundColor:GetDialogBackgroundColor()]); [profileButton setTitle:base::SysUTF16ToNSString(item.name)]; + + // Use the low-res, small default avatars in the fast user switcher, like + // we do in the menu bar. + gfx::Image itemIcon; + bool isRectangle; + AvatarMenu::GetImageForMenuButton(item.profile_path, &itemIcon, &isRectangle); + [profileButton setDefaultImage:CreateProfileImage( - item.icon, kSmallImageSide).ToNSImage()]; + itemIcon, kSmallImageSide).ToNSImage()]; [profileButton setImagePosition:NSImageLeft]; [profileButton setAlignment:NSLeftTextAlignment]; [profileButton setBordered:NO];
diff --git a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_view_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_view_controller.mm index d9879a4..2af31fd 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_view_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_view_controller.mm
@@ -92,12 +92,17 @@ font_style).GetNativeFont(); NSColor* linkColor = gfx::SkColorToCalibratedNSColor( chrome_style::GetLinkColor()); - [textView setMessageAndLink:base::SysUTF16ToNSString(message) - withLink:base::SysUTF16ToNSString(link) - atOffset:offset - font:font - messageColor:[NSColor blackColor] - linkColor:linkColor]; + NSMutableString* finalMessage = [NSMutableString stringWithString: + base::SysUTF16ToNSString(message)]; + NSString* linkString = base::SysUTF16ToNSString(link); + + [finalMessage insertString:linkString atIndex:offset]; + [textView setMessage:finalMessage + withFont:font + messageColor:[NSColor blackColor]]; + [textView addLinkRange:NSMakeRange(offset, [linkString length]) + withName:@"" + linkColor:linkColor]; RemoveUnderlining(textView, offset, link.size()); [textView setDelegate:delegate]; [parent addSubview:textView];
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm index 7560f67..1ac0c2a 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm
@@ -176,16 +176,17 @@ // Get the help text and link. size_t linkOffset = 0; + const base::string16 helpLink = + l10n_util::GetStringUTF16(IDS_SAD_TAB_HELP_LINK); NSString* helpMessage(base::SysUTF16ToNSString(l10n_util::GetStringFUTF16( - IDS_SAD_TAB_HELP_MESSAGE, base::string16(), &linkOffset))); - NSString* helpLink = l10n_util::GetNSString(IDS_SAD_TAB_HELP_LINK); + IDS_SAD_TAB_HELP_MESSAGE, helpLink, &linkOffset))); NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; - [help_ setMessageAndLink:helpMessage - withLink:helpLink - atOffset:linkOffset - font:font - messageColor:[NSColor whiteColor] - linkColor:[NSColor whiteColor]]; + [help_ setMessage:helpMessage + withFont:font + messageColor:[NSColor whiteColor]]; + [help_ addLinkRange:NSMakeRange(linkOffset, helpLink.length()) + withName:@"" + linkColor:[NSColor whiteColor]]; [help_ setAlignment:NSCenterTextAlignment]; }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h b/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h index c9ed4403..5639540 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h
@@ -7,11 +7,13 @@ #import <Cocoa/Cocoa.h> +#import "chrome/browser/ui/cocoa/themed_window.h" + // A view that draws the theme image in the top area of the window (behind the // tab strip area). It should be arranged so that its z-order is below its // overlapping sibling views (window controls, tab strip view, profile button // and fullscreen button). -@interface TabStripBackgroundView : NSView +@interface TabStripBackgroundView : NSView<ThemedWindowDrawing> @end #endif // CHROME_BROWSER_UI_COCOA_TABS_TAB_STRIP_BACKGROUND_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.mm index d8fba5d..4b32010 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_background_view.mm
@@ -40,33 +40,13 @@ } } -- (void)viewWillMoveToWindow:(NSWindow*)window { - if ([self window]) { - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:NSWindowDidBecomeMainNotification - object:[self window]]; - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:NSWindowDidResignMainNotification - object:[self window]]; - } - if (window) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(windowFocusDidChange:) - name:NSWindowDidBecomeMainNotification - object:window]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(windowFocusDidChange:) - name:NSWindowDidResignMainNotification - object:window]; - } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; } -- (void)windowFocusDidChange:(NSNotification*)notification { - // The theme image may depend on the window's active state. +- (void)windowDidChangeActive { [self setNeedsDisplay:YES]; }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h index 9cbe669..0a5f724 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h
@@ -154,15 +154,6 @@ // during a drag. - (void)deferPerformClose; -// The tab strip should always be inserted directly above the content view. -- (void)insertTabStripView:(NSView*)tabStripView intoWindow:(NSWindow*)window; - -// The tab strip background view should always be inserted as the back-most -// subview of the root view. It cannot be a subview of the contentView, as that -// would cause it to become layer backed, which would cause it to draw on top -// of non-layer backed content like the window controls. -- (void)insertTabStripBackgroundViewIntoWindow:(NSWindow*)window; - @end @interface TabWindowController(ProtectedMethods)
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm index d49e5e7..0100d036 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
@@ -101,7 +101,7 @@ [tabStripView_ setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; if (hasTabStrip) - [self insertTabStripView:tabStripView_ intoWindow:[self window]]; + [windowView addSubview:tabStripView_]; } return self; } @@ -189,7 +189,7 @@ positioned:NSWindowBelow relativeTo:nil]; originalContentView_.frame = [[window contentView] bounds]; - [self insertTabStripView:[self tabStripView] intoWindow:window]; + [[window contentView] addSubview:[self tabStripView]]; [[window contentView] updateTrackingAreas]; [focusBeforeOverlay_ restoreFocusInWindow:window]; @@ -327,18 +327,6 @@ closeDeferred_ = YES; } -- (void)insertTabStripView:(NSView*)tabStripView intoWindow:(NSWindow*)window { - NSView* contentParent = [window contentView]; - if (contentParent == [[window contentView] superview]) { - // Add the tab strip directly above the content view, if they are siblings. - [contentParent addSubview:tabStripView - positioned:NSWindowAbove - relativeTo:[window contentView]]; - } else { - [contentParent addSubview:tabStripView]; - } -} - - (void)insertTabStripBackgroundViewIntoWindow:(NSWindow*)window { DCHECK(tabStripBackgroundView_); NSView* rootView = [[window contentView] superview];
diff --git a/chrome/browser/ui/cocoa/themed_window.h b/chrome/browser/ui/cocoa/themed_window.h index ab4b18c..0a55c2b 100644 --- a/chrome/browser/ui/cocoa/themed_window.h +++ b/chrome/browser/ui/cocoa/themed_window.h
@@ -36,11 +36,10 @@ - (ThemeProvider*)themeProvider; - (ThemedWindowStyle)themedWindowStyle; -// Returns the position in the coordinates of the root view -// ([[self contentView] superview]) that the top left of a theme image with -// |alignment| should be painted at. The result of this method can be used in -// conjunction with [NSGraphicsContext cr_setPatternPhase:] to set the offset of -// pattern colors. +// Returns the position in window coordinates that the top left of a theme +// image with |alignment| should be painted at. The result of this method can +// be used in conjunction with [NSGraphicsContext cr_setPatternPhase:] to set +// the offset of pattern colors. - (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment; @end
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h index 2eb4f2c..9a34f52 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h
@@ -24,8 +24,7 @@ // PermissionBubbleView interface. void Show(const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) override; + const std::vector<bool>& accept_state) override; void Hide() override; bool IsVisible() override; void SetDelegate(Delegate* delegate) override;
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm index 4370ec2..df581a4b 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm
@@ -21,8 +21,7 @@ void PermissionBubbleCocoa::Show( const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) { + const std::vector<bool>& accept_state) { DCHECK(parent_window_); if (!bubbleController_) { @@ -34,8 +33,7 @@ [bubbleController_ showAtAnchor:GetAnchorPoint() withDelegate:delegate_ forRequests:requests - acceptStates:accept_state - customizationMode:customization_mode]; + acceptStates:accept_state]; } void PermissionBubbleCocoa::Hide() {
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h index 3ec26c4..ce41462 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
@@ -17,7 +17,7 @@ BaseBubbleController<NSTextViewDelegate> { @private // Array of views that are the checkboxes for every requested permission. - // Only populated if |customizationMode| is YES when the UI is shown. + // Only populated if multiple requests are shown at once. base::scoped_nsobject<NSMutableArray> checkboxes_; // Delegate to be informed of user actions. @@ -43,10 +43,6 @@ - (void)showAtAnchor:(NSPoint)anchor withDelegate:(PermissionBubbleView::Delegate*)delegate forRequests:(const std::vector<PermissionBubbleRequest*>&)requests - acceptStates:(const std::vector<bool>&)acceptStates - customizationMode:(BOOL)customizationMode; - -// Called when a menu item is selected. -- (void)onMenuItemClicked:(int)commandId; + acceptStates:(const std::vector<bool>&)acceptStates; @end
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm index 5d8df94..cadc1a42 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
@@ -39,8 +39,14 @@ namespace { +// Distance between permission icon and permission label. +const CGFloat kHorizontalIconPadding = 8.0f; + +// Distance between two permission labels. +const CGFloat kVerticalPermissionPadding = 2.0f; + const CGFloat kHorizontalPadding = 13.0f; -const CGFloat kVerticalPadding = 13.0f; +const CGFloat kVerticalPadding = 15.0f; const CGFloat kBetweenButtonsPadding = 10.0f; const CGFloat kButtonRightEdgePadding = 17.0f; const CGFloat kTitlePaddingX = 50.0f; @@ -57,9 +63,6 @@ ui::Accelerator* accelerator) override { return false; } - void ExecuteCommand(int command_id, int event_flags) override { - [bubble_controller_ onMenuItemClicked:command_id]; - } private: PermissionBubbleController* bubble_controller_; // Weak, owns us. DISALLOW_COPY_AND_ASSIGN(MenuDelegate); @@ -68,8 +71,8 @@ } // namespace // NSPopUpButton with a menu containing two items: allow and block. -// One AllowBlockMenuButton is used for each requested permission, but only when -// the permission bubble is in 'customize' mode. +// One AllowBlockMenuButton is used for each requested permission when there are +// multiple permissions in the bubble. @interface AllowBlockMenuButton : NSPopUpButton { @private scoped_ptr<PermissionMenuModel> menuModel_; @@ -183,10 +186,6 @@ // Returns an autoreleased NSView displaying a block button. - (NSView*)blockButton; -// Returns an autoreleased NSView with a block button and a drop-down menu -// with one item, which will change the UI to allow customizing the permissions. -- (NSView*)blockButtonWithCustomizeMenu; - // Returns an autoreleased NSView displaying the close 'x' button. - (NSView*)closeButton; @@ -202,9 +201,6 @@ // Called when the 'close' button is pressed. - (void)onClose:(id)sender; -// Called when the 'customize' button is pressed. -- (void)onCustomize:(id)sender; - // Sets the width of both |viewA| and |viewB| to be the larger of the // two views' widths. Does not change either view's origin or height. + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB; @@ -267,45 +263,45 @@ - (void)showAtAnchor:(NSPoint)anchorPoint withDelegate:(PermissionBubbleView::Delegate*)delegate forRequests:(const std::vector<PermissionBubbleRequest*>&)requests - acceptStates:(const std::vector<bool>&)acceptStates - customizationMode:(BOOL)customizationMode { + acceptStates:(const std::vector<bool>&)acceptStates { DCHECK(!requests.empty()); DCHECK(delegate); - DCHECK(!customizationMode || (requests.size() == acceptStates.size())); delegate_ = delegate; NSView* contentView = [[self window] contentView]; [contentView setSubviews:@[]]; + BOOL singlePermission = requests.size() == 1; + // Create one button to use as a guide for the permissions' y-offsets. base::scoped_nsobject<NSView> allowOrOkButton; - if (customizationMode) { - NSString* okTitle = l10n_util::GetNSString(IDS_OK); - allowOrOkButton.reset([[self buttonWithTitle:okTitle - action:@selector(ok:)] retain]); - } else { + if (singlePermission) { NSString* allowTitle = l10n_util::GetNSString(IDS_PERMISSION_ALLOW); allowOrOkButton.reset([[self buttonWithTitle:allowTitle action:@selector(onAllow:)] retain]); + } else { + NSString* okTitle = l10n_util::GetNSString(IDS_OK); + allowOrOkButton.reset([[self buttonWithTitle:okTitle + action:@selector(ok:)] retain]); } CGFloat yOffset = 2 * kVerticalPadding + NSMaxY([allowOrOkButton frame]); - BOOL singlePermission = requests.size() == 1; base::scoped_nsobject<NSMutableArray> permissionMenus; - if (customizationMode) + if (!singlePermission) permissionMenus.reset([[NSMutableArray alloc] init]); CGFloat maxPermissionLineWidth = 0; + CGFloat verticalPadding = 0.0f; for (auto it = requests.begin(); it != requests.end(); it++) { base::scoped_nsobject<NSView> permissionView( [[self labelForRequest:(*it)] retain]); NSPoint origin = [permissionView frame].origin; origin.x += kHorizontalPadding; - origin.y += yOffset; + origin.y += yOffset + verticalPadding; [permissionView setFrameOrigin:origin]; [contentView addSubview:permissionView]; - if (customizationMode) { + if (!singlePermission) { int index = it - requests.begin(); base::scoped_nsobject<NSView> menu( [[self menuForRequest:(*it) @@ -321,6 +317,9 @@ maxPermissionLineWidth = std::max( maxPermissionLineWidth, NSMaxX([permissionView frame])); yOffset += NSHeight([permissionView frame]); + + // Add extra padding for all but first permission. + verticalPadding = kVerticalPermissionPadding; } base::scoped_nsobject<NSView> titleView( @@ -342,7 +341,7 @@ bubbleFrame.size.height = NSMaxY([titleView frame]) + kVerticalPadding + info_bubble::kBubbleArrowHeight; - if (customizationMode) { + if (!singlePermission) { // Add the maximum menu width to the bubble width. CGFloat maxMenuWidth = 0; for (AllowBlockMenuButton* button in permissionMenus.get()) { @@ -380,20 +379,9 @@ [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; [contentView addSubview:allowOrOkButton]; - if (customizationMode) { - // Adjust the horizontal origin for each menu so that its right edge - // lines up with the right edge of the ok button. - CGFloat rightEdge = NSMaxX([allowOrOkButton frame]); - for (NSView* view in permissionMenus.get()) { - [view setFrameOrigin:NSMakePoint(rightEdge - NSWidth([view frame]), - NSMinY([view frame]))]; - } - } else { + if (singlePermission) { base::scoped_nsobject<NSView> blockButton; - if (singlePermission) - blockButton.reset([[self blockButton] retain]); - else - blockButton.reset([[self blockButtonWithCustomizeMenu] retain]); + blockButton.reset([[self blockButton] retain]); CGFloat width = [PermissionBubbleController matchWidthsOf:blockButton andOf:allowOrOkButton]; // Ensure the allow/ok button is still in the correct position. @@ -403,6 +391,14 @@ xOrigin = NSMinX([allowOrOkButton frame]) - width - kBetweenButtonsPadding; [blockButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; [contentView addSubview:blockButton]; + } else { + // Adjust the horizontal origin for each menu so that its right edge + // lines up with the right edge of the ok button. + CGFloat rightEdge = NSMaxX([allowOrOkButton frame]); + for (NSView* view in permissionMenus.get()) { + [view setFrameOrigin:NSMakePoint(rightEdge - NSWidth([view frame]), + NSMinY([view frame]))]; + } } bubbleFrame = [[self window] frameRectForContentRect:bubbleFrame]; @@ -446,7 +442,7 @@ [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; [permissionLabel sizeToFit]; [permissionLabel setFrameOrigin: - NSMakePoint(NSWidth([permissionIcon frame]), 0)]; + NSMakePoint(NSWidth([permissionIcon frame]) + kHorizontalIconPadding, 0)]; [permissionView addSubview:permissionLabel]; // Match the horizontal centers of the two subviews. Note that the label's @@ -518,17 +514,6 @@ action:@selector(onBlock:)]; } -- (NSView*)blockButtonWithCustomizeMenu { - menuDelegate_.reset(new MenuDelegate(self)); - base::scoped_nsobject<SplitBlockButton> blockButton([[SplitBlockButton alloc] - initWithMenuDelegate:menuDelegate_.get()]); - [blockButton sizeToFit]; - [blockButton setEnabled:YES]; - [blockButton setAction:@selector(onBlock:)]; - [blockButton setTarget:self]; - return blockButton.autorelease(); -} - - (NSView*)closeButton { int dimension = chrome_style::GetCloseButtonSize(); NSRect frame = NSMakeRect(0, 0, dimension, dimension); @@ -559,16 +544,6 @@ delegate_->Closing(); } -- (void)onCustomize:(id)sender { - DCHECK(delegate_); - delegate_->SetCustomizationMode(); -} - -- (void)onMenuItemClicked:(int)commandId { - DCHECK(commandId == 0); - [self onCustomize:nil]; -} - - (void)activateTabWithContents:(content::WebContents*)newContents previousContents:(content::WebContents*)oldContents atIndex:(NSInteger)index
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm index 4642c1be..f54f6be 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm
@@ -129,20 +129,6 @@ [menu performActionForItemAtIndex:[menu indexOfItem:next_item]]; } - NSMenuItem* FindCustomizeMenuItem() { - NSButton* button = FindButtonWithTitle(IDS_PERMISSION_DENY); - if (!button || ![button isKindOfClass:[SplitBlockButton class]]) - return nil; - NSString* customize = l10n_util::GetNSString(IDS_PERMISSION_CUSTOMIZE); - SplitBlockButton* block_button = - base::mac::ObjCCast<SplitBlockButton>(button); - for (NSMenuItem* item in [[block_button menu] itemArray]) { - if ([[item title] isEqualToString:customize]) - return item; - } - return nil; - } - protected: PermissionBubbleController* controller_; // Weak; it deletes itself. scoped_ptr<PermissionBubbleCocoa> bridge_; @@ -160,79 +146,108 @@ [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:NO]; + acceptStates:accept_states_]; EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY)); EXPECT_FALSE(FindButtonWithTitle(IDS_OK)); - EXPECT_FALSE(FindCustomizeMenuItem()); } TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) { AddRequest(kPermissionB); AddRequest(kPermissionC); + accept_states_.push_back(true); // A + accept_states_.push_back(true); // B + accept_states_.push_back(true); // C + [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:NO]; + acceptStates:accept_states_]; EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); EXPECT_TRUE(FindTextFieldWithString(kPermissionB)); EXPECT_TRUE(FindTextFieldWithString(kPermissionC)); - EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); - EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY)); - EXPECT_TRUE(FindCustomizeMenuItem()); - EXPECT_FALSE(FindButtonWithTitle(IDS_OK)); + EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); + EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); + EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); } -TEST_F(PermissionBubbleControllerTest, ShowCustomizationModeAllow) { - accept_states_.push_back(true); +TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsAllow) { + AddRequest(kPermissionB); + + accept_states_.push_back(true); // A + accept_states_.push_back(true); // B + [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:YES]; + acceptStates:accept_states_]; - // Test that there is one menu, with 'Allow' visible. + // Test that all menus have 'Allow' visible. EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); - EXPECT_FALSE(FindCustomizeMenuItem()); } -TEST_F(PermissionBubbleControllerTest, ShowCustomizationModeBlock) { - accept_states_.push_back(false); +TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsBlock) { + AddRequest(kPermissionB); + + accept_states_.push_back(false); // A + accept_states_.push_back(false); // B + [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:YES]; + acceptStates:accept_states_]; - // Test that there is one menu, with 'Block' visible. + // Test that all menus have 'Block' visible. EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); - EXPECT_FALSE(FindCustomizeMenuItem()); } -TEST_F(PermissionBubbleControllerTest, OK) { - accept_states_.push_back(true); +TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsMixed) { + AddRequest(kPermissionB); + AddRequest(kPermissionC); + + accept_states_.push_back(false); // A + accept_states_.push_back(false); // B + accept_states_.push_back(true); // C + [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:YES]; + acceptStates:accept_states_]; + + // Test that both 'allow' and 'deny' are visible. + EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); + EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); + + EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); + EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); + EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); +} + +TEST_F(PermissionBubbleControllerTest, OK) { + AddRequest(kPermissionB); + + accept_states_.push_back(true); // A + accept_states_.push_back(true); // B + + [controller_ showAtAnchor:NSZeroPoint + withDelegate:this + forRequests:requests_ + acceptStates:accept_states_]; EXPECT_CALL(*this, Closing()).Times(1); [FindButtonWithTitle(IDS_OK) performClick:nil]; @@ -242,8 +257,7 @@ [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:NO]; + acceptStates:accept_states_]; EXPECT_CALL(*this, Accept()).Times(1); [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil]; @@ -253,8 +267,7 @@ [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:NO]; + acceptStates:accept_states_]; EXPECT_CALL(*this, Deny()).Times(1); [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil]; @@ -263,14 +276,13 @@ TEST_F(PermissionBubbleControllerTest, ChangePermissionSelection) { AddRequest(kPermissionB); - accept_states_.push_back(true); - accept_states_.push_back(false); + accept_states_.push_back(true); // A + accept_states_.push_back(false); // B [controller_ showAtAnchor:NSZeroPoint withDelegate:this forRequests:requests_ - acceptStates:accept_states_ - customizationMode:YES]; + acceptStates:accept_states_]; EXPECT_CALL(*this, ToggleAccept(0, false)).Times(1); EXPECT_CALL(*this, ToggleAccept(1, true)).Times(1); @@ -279,18 +291,3 @@ ChangePermissionMenuSelection(menu_a, IDS_PERMISSION_DENY); ChangePermissionMenuSelection(menu_b, IDS_PERMISSION_ALLOW); } - -TEST_F(PermissionBubbleControllerTest, ClickCustomize) { - AddRequest(kPermissionB); - [controller_ showAtAnchor:NSZeroPoint - withDelegate:this - forRequests:requests_ - acceptStates:accept_states_ - customizationMode:NO]; - - EXPECT_CALL(*this, SetCustomizationMode()).Times(1); - NSMenuItem* customize_item = FindCustomizeMenuItem(); - EXPECT_TRUE(customize_item); - NSMenu* menu = [customize_item menu]; - [menu performActionForItemAtIndex:[menu indexOfItem:customize_item]]; -}
diff --git a/chrome/browser/ui/libgtk2ui/BUILD.gn b/chrome/browser/ui/libgtk2ui/BUILD.gn index 7614064e..a8455be 100644 --- a/chrome/browser/ui/libgtk2ui/BUILD.gn +++ b/chrome/browser/ui/libgtk2ui/BUILD.gn
@@ -120,6 +120,7 @@ "//third_party/mojo/src/mojo/edk/system", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/events", "//ui/events:events_base", "//ui/gfx",
diff --git a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp index c52bc11..d3e3004b 100644 --- a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp +++ b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
@@ -25,6 +25,7 @@ '../../../../printing/printing.gyp:printing', '../../../../skia/skia.gyp:skia', '../../../../ui/aura/aura.gyp:aura', + '../../../../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../../../../ui/base/ui_base.gyp:ui_base', '../../../../ui/events/events.gyp:events', '../../../../ui/events/events.gyp:events_base',
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc index 8ef3451..c5d64431 100644 --- a/chrome/browser/ui/login/login_prompt_browsertest.cc +++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -661,9 +661,8 @@ // Change the host from 127.0.0.1 to www.a.com so that when the // page tries to load from b, it will be cross-origin. - std::string new_host("www.a.com"); GURL::Replacements replacements; - replacements.SetHostStr(new_host); + replacements.SetHostStr("www.a.com"); test_page = test_page.ReplaceComponents(replacements); WindowedLoadStopObserver load_stop_waiter(controller, 1); @@ -683,9 +682,8 @@ // Change the host from 127.0.0.1 to www.b.com so that when the // page tries to load from b, it will be same-origin. - std::string new_host("www.b.com"); GURL::Replacements replacements; - replacements.SetHostStr(new_host); + replacements.SetHostStr("www.b.com"); test_page = test_page.ReplaceComponents(replacements); WindowedAuthNeededObserver auth_needed_waiter(controller); @@ -731,9 +729,9 @@ // Change the host from 127.0.0.1 to www.a.com so that when the // page tries to load from b, it will be cross-origin. - std::string new_host("www.a.com"); + static const char kNewHost[] = "www.a.com"; GURL::Replacements replacements; - replacements.SetHostStr(new_host); + replacements.SetHostStr(kNewHost); test_page = test_page.ReplaceComponents(replacements); WindowedAuthNeededObserver auth_needed_waiter(controller); @@ -751,7 +749,7 @@ // When a cross origin iframe displays a login prompt, the blank // interstitial shouldn't be displayed and the omnibox should show the // main frame's url, not the iframe's. - EXPECT_EQ(new_host, contents->GetVisibleURL().host()); + EXPECT_EQ(kNewHost, contents->GetVisibleURL().host()); handler->CancelAuth(); auth_cancelled_waiter.Wait();
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 50e42fa..d7d344cb 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -276,8 +276,7 @@ Profile* profile, const base::FilePath& cur_dir, chrome::startup::IsProcessStartup process_startup, - chrome::startup::IsFirstRun is_first_run, - int* return_code) { + chrome::startup::IsFirstRun is_first_run) { in_synchronous_profile_launch_ = process_startup == chrome::startup::IS_PROCESS_STARTUP; DCHECK(profile); @@ -320,8 +319,6 @@ in_synchronous_profile_launch_ = false; if (!launched) { LOG(ERROR) << "launch error"; - if (return_code) - *return_code = chrome::RESULT_CODE_INVALID_CMDLINE_URL; return false; } } else { @@ -485,7 +482,6 @@ bool process_startup, Profile* last_used_profile, const Profiles& last_opened_profiles, - int* return_code, StartupBrowserCreator* browser_creator) { VLOG(2) << "ProcessCmdLineImpl : BEGIN"; DCHECK(last_used_profile); @@ -719,7 +715,7 @@ VLOG(2) << "ProcessCmdLineImpl: PLACE 8.A"; if (!browser_creator->LaunchBrowser(command_line, profile_to_open, cur_dir, is_process_startup, - is_first_run, return_code)) { + is_first_run)) { return false; } } else { @@ -761,7 +757,7 @@ if (!browser_creator->LaunchBrowser((*it == last_used_profile) ? command_line : command_line_without_urls, *it, cur_dir, - is_process_startup, is_first_run, return_code)) + is_process_startup, is_first_run)) return false; // We've launched at least one browser. is_process_startup = chrome::startup::IS_NOT_PROCESS_STARTUP; @@ -815,9 +811,9 @@ const base::FilePath& cur_dir, Profile* profile, Profile::CreateStatus status) { - if (status == Profile::CREATE_STATUS_INITIALIZED) - ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL, - NULL); + if (status != Profile::CREATE_STATUS_INITIALIZED) + return; + ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL); } // static @@ -837,8 +833,7 @@ return; } - ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL, - NULL); + ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL); } // static
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h index d5d7a9d..52a8d1a2 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.h +++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -43,10 +43,9 @@ bool Start(const base::CommandLine& cmd_line, const base::FilePath& cur_dir, Profile* last_used_profile, - const Profiles& last_opened_profiles, - int* return_code) { + const Profiles& last_opened_profiles) { return ProcessCmdLineImpl(cmd_line, cur_dir, true, last_used_profile, - last_opened_profiles, return_code, this); + last_opened_profiles, this); } // This function performs command-line handling and is invoked only after @@ -74,8 +73,7 @@ Profile* profile, const base::FilePath& cur_dir, chrome::startup::IsProcessStartup is_process_startup, - chrome::startup::IsFirstRun is_first_run, - int* return_code); + chrome::startup::IsFirstRun is_first_run); // When called the first time, reads the value of the preference kWasRestarted // and resets it to false. Subsequent calls return the value which was read @@ -128,7 +126,6 @@ bool process_startup, Profile* last_used_profile, const Profiles& last_opened_profiles, - int* return_code, StartupBrowserCreator* browser_creator); // This function performs command-line handling and is invoked only after
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index c96fce4..427fc9a 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -659,13 +659,12 @@ // Do a simple non-process-startup browser launch. base::CommandLine dummy(base::CommandLine::NO_PROGRAM); - int return_code; StartupBrowserCreator browser_creator; std::vector<Profile*> last_opened_profiles; last_opened_profiles.push_back(default_profile); last_opened_profiles.push_back(other_profile); browser_creator.Start(dummy, profile_manager->user_data_dir(), - default_profile, last_opened_profiles, &return_code); + default_profile, last_opened_profiles); // urls1 were opened in a browser for default_profile, and urls2 were opened // in a browser for other_profile. @@ -776,13 +775,12 @@ // Simulate a launch after a browser update. base::CommandLine dummy(base::CommandLine::NO_PROGRAM); - int return_code; StartupBrowserCreator browser_creator; std::vector<Profile*> last_opened_profiles; last_opened_profiles.push_back(profile1); last_opened_profiles.push_back(profile2); browser_creator.Start(dummy, profile_manager->user_data_dir(), profile1, - last_opened_profiles, &return_code); + last_opened_profiles); while (SessionRestore::IsRestoring(profile1) || SessionRestore::IsRestoring(profile2)) @@ -880,7 +878,6 @@ // Do a simple non-process-startup browser launch. base::CommandLine dummy(base::CommandLine::NO_PROGRAM); - int return_code; StartupBrowserCreator browser_creator; std::vector<Profile*> last_opened_profiles; last_opened_profiles.push_back(profile_home1); @@ -888,7 +885,7 @@ last_opened_profiles.push_back(profile_last); last_opened_profiles.push_back(profile_urls); browser_creator.Start(dummy, profile_manager->user_data_dir(), profile_home1, - last_opened_profiles, &return_code); + last_opened_profiles); while (SessionRestore::IsRestoring(default_profile) || SessionRestore::IsRestoring(profile_home1) || @@ -997,14 +994,13 @@ base::CommandLine dummy(base::CommandLine::NO_PROGRAM); dummy.AppendSwitchASCII(switches::kTestType, "browser"); - int return_code; StartupBrowserCreator browser_creator; std::vector<Profile*> last_opened_profiles; last_opened_profiles.push_back(profile_home); last_opened_profiles.push_back(profile_last); last_opened_profiles.push_back(profile_urls); browser_creator.Start(dummy, profile_manager->user_data_dir(), profile_home, - last_opened_profiles, &return_code); + last_opened_profiles); // No profiles are getting restored, since they all display the crash info // bar.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc index eb2f2f7e..d5b2821 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc
@@ -60,7 +60,6 @@ // Do a simple non-process-startup browser launch. base::CommandLine dummy(base::CommandLine::NO_PROGRAM); - int return_code; StartupBrowserCreator browser_creator; std::vector<Profile*> last_opened_profiles; last_opened_profiles.push_back(profile_1); @@ -68,7 +67,7 @@ last_opened_profiles.push_back(profile_3); last_opened_profiles.push_back(profile_4); browser_creator.Start(dummy, profile_manager->user_data_dir(), profile_2, - last_opened_profiles, &return_code); + last_opened_profiles); while (!browser_creator.ActivatedProfile()) base::MessageLoop::current()->RunUntilIdle(); @@ -104,6 +103,5 @@ browser()->host_desktop_type()); ASSERT_TRUE(new_browser); EXPECT_FALSE(new_browser->window()->IsActive()); - } #endif // !OS_MACOSX && !OS_CHROMEOS
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index fd8a661b..28393333 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -39,6 +39,7 @@ #if defined(OS_ANDROID) #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" +#include "chrome/browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h" #include "chrome/browser/ui/android/context_menu_helper.h" #include "chrome/browser/ui/android/window_android_helper.h" #else @@ -161,6 +162,7 @@ #if defined(OS_ANDROID) ContextMenuHelper::CreateForWebContents(web_contents); + EnhancedBookmarkTabHelper::CreateForWebContents(web_contents); SingleTabModeTabHelper::CreateForWebContents(web_contents); WindowAndroidHelper::CreateForWebContents(web_contents); #else
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc index 4979ecf9..307a74d 100644 --- a/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc +++ b/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc
@@ -4,77 +4,18 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/browser_action_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h" +#include "chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/test/base/in_process_browser_test.h" #include "extensions/common/feature_switch.h" -#include "grit/theme_resources.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_skia.h" namespace { const char kMockId[] = "mock_action"; -class MockComponentAction : public ToolbarActionViewController { - public: - MockComponentAction() : click_count_(0u), id_(kMockId) {} - ~MockComponentAction() override {} - - // ToolbarActionButtonController: - const std::string& GetId() const override { return id_; } - void SetDelegate(ToolbarActionViewDelegate* delegate) override {} - gfx::Image GetIcon(content::WebContents* web_contents) override { - return ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_BROWSER_ACTION); - } - gfx::ImageSkia GetIconWithBadge() override { - return *GetIcon(nullptr).ToImageSkia(); - } - base::string16 GetActionName() const override { - return base::ASCIIToUTF16("Component Action"); - } - base::string16 GetAccessibleName(content::WebContents* web_contents) - const override { - return GetActionName(); - } - base::string16 GetTooltip(content::WebContents* web_contents) - const override { - return GetActionName(); - } - bool IsEnabled(content::WebContents* web_contents) const override { - return true; - } - bool WantsToRun(content::WebContents* web_contents) const override { - return false; - } - bool HasPopup(content::WebContents* web_contents) const override { - return true; - } - void HidePopup() override {} - gfx::NativeView GetPopupNativeView() override { return nullptr; } - ui::MenuModel* GetContextMenu() override { return nullptr; } - bool CanDrag() const override { return false; } - bool IsMenuRunning() const override { return false; } - bool ExecuteAction(bool by_user) override { - ++click_count_; - return false; - } - void UpdateState() override {} - - size_t click_count() const { return click_count_; } - - private: - size_t click_count_; - std::string id_; - - DISALLOW_COPY_AND_ASSIGN(MockComponentAction); -}; - class MockComponentToolbarActionsFactory : public ComponentToolbarActionsFactory { public: @@ -85,13 +26,13 @@ ScopedVector<ToolbarActionViewController> GetComponentToolbarActions() override; - const std::vector<MockComponentAction*>& weak_actions() const { + const std::vector<TestToolbarActionViewController*>& weak_actions() const { return weak_actions_; } private: // A (weak) set of all created actions. - std::vector<MockComponentAction*> weak_actions_; + std::vector<TestToolbarActionViewController*> weak_actions_; DISALLOW_COPY_AND_ASSIGN(MockComponentToolbarActionsFactory); }; @@ -107,7 +48,8 @@ ScopedVector<ToolbarActionViewController> MockComponentToolbarActionsFactory::GetComponentToolbarActions() { ScopedVector<ToolbarActionViewController> component_actions; - MockComponentAction* action = new MockComponentAction(); + TestToolbarActionViewController* action = + new TestToolbarActionViewController(kMockId); component_actions.push_back(action); weak_actions_.push_back(action); return component_actions.Pass(); @@ -152,14 +94,14 @@ EXPECT_EQ(kMockId, browser_actions_bar.GetExtensionId(0)); // There should only have been one created component action. - const std::vector<MockComponentAction*> weak_actions = + const std::vector<TestToolbarActionViewController*>& weak_actions = mock_factory()->weak_actions(); ASSERT_EQ(1u, weak_actions.size()); - MockComponentAction* mock_component_action = weak_actions[0]; + TestToolbarActionViewController* mock_component_action = weak_actions[0]; ASSERT_TRUE(mock_component_action); // Test that clicking on the component action works. - EXPECT_EQ(0u, mock_component_action->click_count()); + EXPECT_EQ(0, mock_component_action->execute_action_count()); browser_actions_bar.Press(0); - EXPECT_EQ(1u, mock_component_action->click_count()); + EXPECT_EQ(1, mock_component_action->execute_action_count()); }
diff --git a/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.cc b/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.cc new file mode 100644 index 0000000..c6c9107 --- /dev/null +++ b/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.cc
@@ -0,0 +1,129 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h" + +#include "base/strings/string16.h" +#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" + +TestToolbarActionViewController::TestToolbarActionViewController( + const std::string& id) + : id_(id), + delegate_(nullptr), + is_enabled_(true), + wants_to_run_(false), + execute_action_count_(0) { +} + +TestToolbarActionViewController::~TestToolbarActionViewController() { +} + +const std::string& TestToolbarActionViewController::GetId() const { + return id_; +} + +void TestToolbarActionViewController::SetDelegate( + ToolbarActionViewDelegate* delegate) { + delegate_ = delegate; +} + +gfx::Image TestToolbarActionViewController::GetIcon( + content::WebContents* web_contents) { + return gfx::Image(); +} + +gfx::ImageSkia TestToolbarActionViewController::GetIconWithBadge() { + return gfx::ImageSkia(); +} + +base::string16 TestToolbarActionViewController::GetActionName() const { + return base::string16(); +} + +base::string16 TestToolbarActionViewController::GetAccessibleName( + content::WebContents* web_contents) const { + return accessible_name_; +} + +base::string16 TestToolbarActionViewController::GetTooltip( + content::WebContents* web_contents) const { + return tooltip_; +} + +bool TestToolbarActionViewController::IsEnabled( + content::WebContents* web_contents) const { + return is_enabled_; +} + +bool TestToolbarActionViewController::WantsToRun( + content::WebContents* web_contents) const { + return wants_to_run_; +} + +bool TestToolbarActionViewController::HasPopup( + content::WebContents* web_contents) const { + return true; +} + +void TestToolbarActionViewController::HidePopup() { + delegate_->OnPopupClosed(); +} + +gfx::NativeView TestToolbarActionViewController::GetPopupNativeView() { + return nullptr; +} + +ui::MenuModel* TestToolbarActionViewController::GetContextMenu() { + return nullptr; +} + +bool TestToolbarActionViewController::IsMenuRunning() const { + return false; +} + +bool TestToolbarActionViewController::CanDrag() const { + return false; +} + +bool TestToolbarActionViewController::ExecuteAction(bool by_user) { + ++execute_action_count_; + return false; +} + +void TestToolbarActionViewController::UpdateState() { + UpdateDelegate(); +} + +void TestToolbarActionViewController::ShowPopup(bool by_user) { + delegate_->OnPopupShown(by_user); +} + +void TestToolbarActionViewController::SetAccessibleName( + const base::string16& name) { + accessible_name_ = name; + UpdateDelegate(); +} + +void TestToolbarActionViewController::SetTooltip( + const base::string16& tooltip) { + tooltip_ = tooltip; + UpdateDelegate(); +} + +void TestToolbarActionViewController::SetEnabled(bool is_enabled) { + is_enabled_ = is_enabled; + UpdateDelegate(); +} + +void TestToolbarActionViewController::SetWantsToRun(bool wants_to_run) { + wants_to_run_ = wants_to_run; + UpdateDelegate(); +} + +void TestToolbarActionViewController::UpdateDelegate() { + if (delegate_) + delegate_->UpdateState(); +}
diff --git a/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h b/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h new file mode 100644 index 0000000..7a699d3 --- /dev/null +++ b/chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h
@@ -0,0 +1,75 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_TOOLBAR_TEST_TOOLBAR_ACTION_VIEW_CONTROLLER_H_ +#define CHROME_BROWSER_UI_TOOLBAR_TEST_TOOLBAR_ACTION_VIEW_CONTROLLER_H_ + +#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" + +// A minimalistic and configurable ToolbarActionViewController for use in +// testing. +class TestToolbarActionViewController : public ToolbarActionViewController { + public: + explicit TestToolbarActionViewController(const std::string& id); + ~TestToolbarActionViewController() override; + + // ToolbarActionViewController: + const std::string& GetId() const override; + void SetDelegate(ToolbarActionViewDelegate* delegate) override; + gfx::Image GetIcon(content::WebContents* web_contents) override; + gfx::ImageSkia GetIconWithBadge() override; + base::string16 GetActionName() const override; + base::string16 GetAccessibleName(content::WebContents* web_contents) + const override; + base::string16 GetTooltip(content::WebContents* web_contents) + const override; + bool IsEnabled(content::WebContents* web_contents) const override; + bool WantsToRun(content::WebContents* web_contents) const override; + bool HasPopup(content::WebContents* web_contents) const override; + void HidePopup() override; + gfx::NativeView GetPopupNativeView() override; + ui::MenuModel* GetContextMenu() override; + bool IsMenuRunning() const override; + bool CanDrag() const override; + bool ExecuteAction(bool by_user) override; + void UpdateState() override; + + // Instruct the controller to fake showing a popup. + void ShowPopup(bool by_user); + + // Configure the test controller. These also call UpdateDelegate(). + void SetAccessibleName(const base::string16& name); + void SetTooltip(const base::string16& tooltip); + void SetEnabled(bool is_enabled); + void SetWantsToRun(bool wants_to_run); + + int execute_action_count() const { return execute_action_count_; } + + private: + // Updates the delegate, if one exists. + void UpdateDelegate(); + + // The id of the controller. + std::string id_; + + // The delegate of the controller, if one exists. + ToolbarActionViewDelegate* delegate_; + + // The optional accessible name and tooltip; by default these are empty. + base::string16 accessible_name_; + base::string16 tooltip_; + + // Whether or not the action is enabled. Defaults to true. + bool is_enabled_; + + // Whether or not the action wants to run. Defaults to false. + bool wants_to_run_; + + // The number of times the action would have been executed. + int execute_action_count_; + + DISALLOW_COPY_AND_ASSIGN(TestToolbarActionViewController); +}; + +#endif // CHROME_BROWSER_UI_TOOLBAR_TEST_TOOLBAR_ACTION_VIEW_CONTROLLER_H_
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model.cc b/chrome/browser/ui/toolbar/wrench_menu_model.cc index f8dbcf8..3684113e 100644 --- a/chrome/browser/ui/toolbar/wrench_menu_model.cc +++ b/chrome/browser/ui/toolbar/wrench_menu_model.cc
@@ -240,7 +240,18 @@ #endif if (extensions::util::IsNewBookmarkAppsEnabled()) { - AddItemWithStringId(IDC_CREATE_HOSTED_APP, IDS_CREATE_HOSTED_APP); +#if defined(OS_MACOSX) + int string_id = IDS_ADD_TO_DOCK; +#elif defined(OS_WIN) + int string_id = IDS_ADD_TO_TASKBAR; +#else + int string_id = IDS_ADD_TO_DESKTOP; +#endif +#if defined(USE_ASH) + if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) + string_id = IDS_ADD_TO_SHELF; +#endif + AddItemWithStringId(IDC_CREATE_HOSTED_APP, string_id); AddSeparator(ui::NORMAL_SEPARATOR); } else if (show_create_shortcuts) { AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS); @@ -254,6 +265,10 @@ AddItemWithStringId(IDC_CLEAR_BROWSING_DATA, IDS_CLEAR_BROWSING_DATA); +#if defined(OS_CHROMEOS) + AddItemWithStringId(IDC_TAKE_SCREENSHOT, IDS_TAKE_SCREENSHOT); +#endif + AddSeparator(ui::NORMAL_SEPARATOR); encoding_menu_model_.reset(new EncodingMenuModel(browser));
diff --git a/chrome/browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc b/chrome/browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc new file mode 100644 index 0000000..9b27cb1 --- /dev/null +++ b/chrome/browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc
@@ -0,0 +1,257 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <oleacc.h> + +#include "base/strings/string_util.h" +#include "base/win/scoped_bstr.h" +#include "base/win/scoped_com_initializer.h" +#include "base/win/scoped_comptr.h" +#include "base/win/scoped_variant.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/omnibox/omnibox_view.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" +#include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/browser_accessibility_state.h" +#include "net/dns/mock_host_resolver.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/test/ui_controls.h" +#include "url/gurl.h" + +// We could move this into a utility file in the future if it ends up +// being useful to other tests. +class WinAccessibilityEventMonitor { + public: + WinAccessibilityEventMonitor(UINT event_min, UINT event_max); + ~WinAccessibilityEventMonitor(); + + // Blocks until the next event is received. When it's received, it + // queries accessibility information about the object that fired the + // event and populates the event, hwnd, role, state, and name in the + // passed arguments. + void WaitForNextEvent(DWORD* out_event, + HWND* out_hwnd, + UINT* out_role, + UINT* out_state, + std::string* out_name); + + private: + void OnWinEventHook(HWINEVENTHOOK handle, + DWORD event, + HWND hwnd, + LONG obj_id, + LONG child_id, + DWORD event_thread, + DWORD event_time); + + static void CALLBACK WinEventHookThunk( + HWINEVENTHOOK handle, + DWORD event, + HWND hwnd, + LONG obj_id, + LONG child_id, + DWORD event_thread, + DWORD event_time); + + struct EventInfo { + DWORD event; + HWND hwnd; + LONG obj_id; + LONG child_id; + }; + + std::deque<EventInfo> event_queue_; + scoped_refptr<content::MessageLoopRunner> loop_runner_; + HWINEVENTHOOK win_event_hook_handle_; + static WinAccessibilityEventMonitor* instance_; + + DISALLOW_COPY_AND_ASSIGN(WinAccessibilityEventMonitor); +}; + +// static +WinAccessibilityEventMonitor* WinAccessibilityEventMonitor::instance_ = NULL; + +WinAccessibilityEventMonitor::WinAccessibilityEventMonitor( + UINT event_min, UINT event_max) { + CHECK(!instance_) << "There can be only one instance of" + << " WinAccessibilityEventMonitor at a time."; + instance_ = this; + win_event_hook_handle_ = SetWinEventHook( + event_min, + event_max, + NULL, + &WinAccessibilityEventMonitor::WinEventHookThunk, + GetCurrentProcessId(), + 0, // Hook all threads + WINEVENT_OUTOFCONTEXT); +} + +WinAccessibilityEventMonitor::~WinAccessibilityEventMonitor() { + UnhookWinEvent(win_event_hook_handle_); + instance_ = NULL; +} + +void WinAccessibilityEventMonitor::WaitForNextEvent( + DWORD* out_event, + HWND* out_hwnd, + UINT* out_role, + UINT* out_state, + std::string* out_name) { + if (event_queue_.empty()) { + loop_runner_ = new content::MessageLoopRunner(); + loop_runner_->Run(); + loop_runner_ = NULL; + } + EventInfo event_info = event_queue_.front(); + event_queue_.pop_front(); + + *out_event = event_info.event; + *out_hwnd = event_info.hwnd; + + base::win::ScopedComPtr<IAccessible> acc_obj; + base::win::ScopedVariant child_variant; + CHECK(S_OK == AccessibleObjectFromEvent( + event_info.hwnd, event_info.obj_id, event_info.child_id, + acc_obj.Receive(), child_variant.Receive())); + + base::win::ScopedVariant role_variant; + if (S_OK == acc_obj->get_accRole(child_variant, role_variant.Receive())) + *out_role = V_I4(&role_variant); + else + *out_role = 0; + + base::win::ScopedVariant state_variant; + if (S_OK == acc_obj->get_accState(child_variant, state_variant.Receive())) + *out_state = V_I4(&state_variant); + else + *out_state = 0; + + base::win::ScopedBstr name_bstr; + HRESULT hr = acc_obj->get_accName(child_variant, name_bstr.Receive()); + if (S_OK == hr) + *out_name = base::UTF16ToUTF8(base::string16(name_bstr)); + else + *out_name = ""; +} + +void WinAccessibilityEventMonitor::OnWinEventHook( + HWINEVENTHOOK handle, + DWORD event, + HWND hwnd, + LONG obj_id, + LONG child_id, + DWORD event_thread, + DWORD event_time) { + EventInfo event_info; + event_info.event = event; + event_info.hwnd = hwnd; + event_info.obj_id = obj_id; + event_info.child_id = child_id; + event_queue_.push_back(event_info); + if (loop_runner_.get()) + loop_runner_->Quit(); +} + +// static +void CALLBACK WinAccessibilityEventMonitor::WinEventHookThunk( + HWINEVENTHOOK handle, + DWORD event, + HWND hwnd, + LONG obj_id, + LONG child_id, + DWORD event_thread, + DWORD event_time) { + if (instance_) { + instance_->OnWinEventHook(handle, event, hwnd, obj_id, child_id, + event_thread, event_time); + } +} + +class NavigationAccessibilityTest : public InProcessBrowserTest { + protected: + NavigationAccessibilityTest() {} + virtual ~NavigationAccessibilityTest() {} + + void SendKeyPress(ui::KeyboardCode key) { + gfx::NativeWindow native_window = browser()->window()->GetNativeWindow(); + ASSERT_NO_FATAL_FAILURE( + ASSERT_TRUE( + ui_test_utils::SendKeyPressToWindowSync( + native_window, key, false, false, false, false))); + } + + private: + base::win::ScopedCOMInitializer com_initializer_; + + DISALLOW_COPY_AND_ASSIGN(NavigationAccessibilityTest); +}; + +// Tests that when focus is in the omnibox and the user types a url and +// presses enter, no focus events are sent on the old document. +// TODO(dmazzoni): enable this test. http://crbug.com/421116 +IN_PROC_BROWSER_TEST_F(NavigationAccessibilityTest, + DISABLED_TestNavigateToNewUrl) { + content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); + + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8," + "<head><title>First Page</title></head>")); + + chrome::ExecuteCommand(browser(), IDC_FOCUS_LOCATION); + + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(test_server()->Start()); + GURL main_url(test_server()->GetURL("files/english_page.html")); + + OmniboxViewViews* omnibox_view = + BrowserView::GetBrowserViewForBrowser(browser())-> + toolbar()->location_bar()->omnibox_view(); + omnibox_view->SetUserText(base::UTF8ToUTF16(main_url.spec()), + base::UTF8ToUTF16(main_url.spec()), + false); + + WinAccessibilityEventMonitor monitor(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS); + SendKeyPress(ui::VKEY_RETURN); + + for (;;) { + DWORD event; + HWND hwnd; + UINT role; + UINT state; + std::string name; + monitor.WaitForNextEvent(&event, &hwnd, &role, &state, &name); + + LOG(INFO) << "Got event: " + << " event=" << event + << " hwnd=" << hwnd + << " role=" << role + << " state=" << state + << " name=" << name; + + // We should get only focus events. + EXPECT_EQ(EVENT_OBJECT_FOCUS, event); + + // We should get only focus events on document objects. (On a page with + // JavaScript or autofocus, additional focus events would be expected.) + EXPECT_EQ(ROLE_SYSTEM_DOCUMENT, role); + + // We shouldn't get any events on the first page because from the time + // we start monitoring, the user has already initiated a load to the + // second page. + EXPECT_NE("First Page", name); + + // Finish when we get an event on the second page. + if (name == "This page is in English") { + LOG(INFO) << "Got event on second page, finishing test."; + break; + } + } +}
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc index 84112a3..733f20d 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
@@ -184,7 +184,8 @@ } bool AppInfoFooterPanel::CanUninstallApp() const { - return extensions::ExtensionSystem::Get(profile_) - ->management_policy() - ->UserMayModifySettings(app_, NULL); + extensions::ManagementPolicy* policy = + extensions::ExtensionSystem::Get(profile_)->management_policy(); + return policy->UserMayModifySettings(app_, nullptr) && + !policy->MustRemainInstalled(app_, nullptr); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 0e87819..6672c13 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -90,6 +90,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; using content::OpenURLParams; using content::PageNavigator;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h index 9eb766d..2546b17 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -113,11 +113,12 @@ // showing and |loc| is over the overflow button, the bookmark bar node is // returned and |model_start_index| is set to the index of the first node // contained in the overflow menu. - const BookmarkNode* GetNodeForButtonAtModelIndex(const gfx::Point& loc, - int* model_start_index); + const bookmarks::BookmarkNode* GetNodeForButtonAtModelIndex( + const gfx::Point& loc, + int* model_start_index); // Returns the MenuButton for node. - views::MenuButton* GetMenuButtonForNode(const BookmarkNode* node); + views::MenuButton* GetMenuButtonForNode(const bookmarks::BookmarkNode* node); // Returns the position to anchor the menu for |button| at. void GetAnchorPositionForButton(views::MenuButton* button, @@ -212,26 +213,27 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; // views::DragController: void WriteDragDataForView(views::View* sender, @@ -308,40 +310,41 @@ views::MenuButton* CreateOverflowButton(); // Creates the button for rendering the specified bookmark node. - views::View* CreateBookmarkButton(const BookmarkNode* node); + views::View* CreateBookmarkButton(const bookmarks::BookmarkNode* node); // Creates the button for rendering the apps page shortcut. views::LabelButton* CreateAppsPageShortcutButton(); // Configures the button from the specified node. This sets the text, // and icon. - void ConfigureButton(const BookmarkNode* node, views::LabelButton* button); + void ConfigureButton(const bookmarks::BookmarkNode* node, + views::LabelButton* button); // Implementation for BookmarkNodeAddedImpl. Returns true if LayoutAndPaint() // is required. bool BookmarkNodeAddedImpl(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index); // Implementation for BookmarkNodeRemoved. Returns true if LayoutAndPaint() is // required. bool BookmarkNodeRemovedImpl(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index); // If the node is a child of the root node, the button is updated // appropriately. void BookmarkNodeChangedImpl(bookmarks::BookmarkModel* model, - const BookmarkNode* node); + const bookmarks::BookmarkNode* node); // Shows the menu used during drag and drop for the specified node. - void ShowDropFolderForNode(const BookmarkNode* node); + void ShowDropFolderForNode(const bookmarks::BookmarkNode* node); // Cancels the timer used to show a drop menu. void StopShowFolderDropMenuTimer(); // Stars the timer used to show a drop menu for node. - void StartShowFolderDropMenuTimer(const BookmarkNode* node); + void StartShowFolderDropMenuTimer(const bookmarks::BookmarkNode* node); // Calculates the location for the drop in |location|. void CalculateDropLocation(const ui::DropTargetEvent& event, @@ -349,20 +352,20 @@ DropLocation* location); // Writes a BookmarkNodeData for node to data. - void WriteBookmarkDragData(const BookmarkNode* node, + void WriteBookmarkDragData(const bookmarks::BookmarkNode* node, ui::OSExchangeData* data); // This determines which view should throb and starts it // throbbing (e.g when the bookmark bubble is showing). // If |overflow_only| is true, start throbbing only if |node| is hidden in // the overflow menu. - void StartThrobbing(const BookmarkNode* node, bool overflow_only); + void StartThrobbing(const bookmarks::BookmarkNode* node, bool overflow_only); // Returns the view to throb when a node is removed. |parent| is the parent of // the node that was removed, and |old_index| the index of the node that was // removed. views::CustomButton* DetermineViewToThrobFromRemove( - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index); // Updates the colors for all the child objects in the bookmarks bar.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc index bfb8a8b..d8887c2 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -49,6 +49,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; using content::OpenURLParams; using content::PageNavigator;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc index cce07b9..64cfc329 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -26,6 +26,8 @@ #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/menu_button.h" +using bookmarks::BookmarkNode; + class BookmarkBarViewTest : public BrowserWithTestWindowTest { public: BookmarkBarViewTest() {}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc index 64a6e0c8..98a9bc6 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -34,6 +34,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using views::ColumnSet; using views::GridLayout;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc index 12e6ddf..f8bd590 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc
@@ -15,6 +15,7 @@ #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/widget/widget.h" +using bookmarks::BookmarkNode; using content::PageNavigator; namespace {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.h b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.h index 4631eaa..b90099afc 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.h
@@ -21,7 +21,7 @@ public: // Invoked before the specified items are removed from the bookmark model. virtual void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) = 0; + const std::vector<const bookmarks::BookmarkNode*>& bookmarks) = 0; // Invoked after the items have been removed from the model. virtual void DidRemoveBookmarks() = 0; @@ -39,8 +39,8 @@ Browser* browser, Profile* profile, content::PageNavigator* page_navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection, + const bookmarks::BookmarkNode* parent, + const std::vector<const bookmarks::BookmarkNode*>& selection, bool close_on_remove); ~BookmarkContextMenu() override; @@ -68,7 +68,7 @@ void CloseMenu() override; void WillExecuteCommand( int command_id, - const std::vector<const BookmarkNode*>& bookmarks) override; + const std::vector<const bookmarks::BookmarkNode*>& bookmarks) override; void DidExecuteCommand(int command_id) override; private:
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc index 0240d798..a65489f 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
@@ -36,6 +36,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; using content::OpenURLParams; using content::PageNavigator;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc index 93c8cbf..a1639410 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc
@@ -16,6 +16,7 @@ #include "ui/views/widget/widget.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace chrome {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index 484da8c6..1f729c0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -40,6 +40,7 @@ using bookmarks::BookmarkExpandedStateTracker; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using views::GridLayout; namespace {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h index 2ff02118..b5b2fe0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h
@@ -71,7 +71,7 @@ }; BookmarkEditorView(Profile* profile, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, const EditDetails& details, BookmarkEditor::Configuration configuration); @@ -130,26 +130,28 @@ void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override {} void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override {} - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override {} + const bookmarks::BookmarkNode* node) override {} + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeFaviconChanged( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override {} // Creates the necessary sub-views, configures them, adds them to the layout, // and requests the entries to display from the database. @@ -169,7 +171,7 @@ // Adds and creates a child node in b_node for all children of bb_node that // are folders. - void CreateNodes(const BookmarkNode* bb_node, EditorNode* b_node); + void CreateNodes(const bookmarks::BookmarkNode* bb_node, EditorNode* b_node); // Returns the node with the specified id, or NULL if one can't be found. EditorNode* FindNodeWithID(BookmarkEditorView::EditorNode* node, int64 id); @@ -191,10 +193,10 @@ // used to determine the new BookmarkNode parent based on the EditorNode // parent. void ApplyNameChangesAndCreateNewFolders( - const BookmarkNode* bb_node, + const bookmarks::BookmarkNode* bb_node, BookmarkEditorView::EditorNode* b_node, BookmarkEditorView::EditorNode* parent_b_node, - const BookmarkNode** parent_bb_node); + const bookmarks::BookmarkNode** parent_bb_node); // Returns the current url the user has input. GURL GetInputURL() const; @@ -247,7 +249,7 @@ // Initial parent to select. Is only used if |details_.existing_node| is // NULL. - const BookmarkNode* parent_; + const bookmarks::BookmarkNode* parent_; const EditDetails details_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc index 777ad5a..e4d38d8 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
@@ -24,6 +24,7 @@ using base::Time; using base::TimeDelta; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using content::BrowserThread; // Base class for bookmark editor tests. Creates a BookmarkModel and populates
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc index 7e84b2d1..b01a8c0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc
@@ -21,6 +21,7 @@ #include "ui/views/widget/widget.h" using base::UserMetricsAction; +using bookmarks::BookmarkNode; using content::PageNavigator; using views::MenuItemView;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h index 8ade673..86ea7e9 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h
@@ -15,9 +15,12 @@ class BookmarkBarView; class BookmarkMenuControllerObserver; class BookmarkMenuDelegate; -class BookmarkNode; class Browser; +namespace bookmarks { +class BookmarkNode; +} + namespace content { class PageNavigator; } @@ -45,7 +48,7 @@ BookmarkMenuController(Browser* browser, content::PageNavigator* page_navigator, views::Widget* parent, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, int start_child_index, bool for_drop); @@ -59,7 +62,7 @@ void Cancel(); // Returns the node the menu is showing for. - const BookmarkNode* node() const { return node_; } + const bookmarks::BookmarkNode* node() const { return node_; } // Returns the menu. views::MenuItemView* menu() const; @@ -122,7 +125,7 @@ scoped_ptr<BookmarkMenuDelegate> menu_delegate_; // The node we're showing the contents of. - const BookmarkNode* node_; + const bookmarks::BookmarkNode* node_; // Data for the drop. bookmarks::BookmarkNodeData drop_data_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc index 739399f..074e9b0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
@@ -31,6 +31,7 @@ using base::UserMetricsAction; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; using content::PageNavigator; using views::MenuItemView;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h index e06443a..7c07e17 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
@@ -15,7 +15,6 @@ #include "components/bookmarks/browser/bookmark_node_data.h" #include "ui/views/controls/menu/menu_delegate.h" -class BookmarkNode; class Browser; class ChromeBookmarkClient; class Profile; @@ -61,7 +60,7 @@ // Creates the menus from the model. void Init(views::MenuDelegate* real_delegate, views::MenuItemView* parent, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, int start_child_index, ShowOptions show_options, BookmarkLaunchLocation location); @@ -74,7 +73,7 @@ // Makes the menu for |node| the active menu. |start_index| is the index of // the first child of |node| to show in the menu. - void SetActiveMenu(const BookmarkNode* node, int start_index); + void SetActiveMenu(const bookmarks::BookmarkNode* node, int start_index); bookmarks::BookmarkModel* GetBookmarkModel(); ChromeBookmarkClient* GetChromeBookmarkClient(); @@ -124,19 +123,20 @@ // BookmarkModelObserver methods. void BookmarkModelChanged() override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; // BookmarkContextMenu::Observer methods. void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) override; + const std::vector<const bookmarks::BookmarkNode*>& bookmarks) override; void DidRemoveBookmarks() override; private: - typedef std::map<int, const BookmarkNode*> MenuIDToNodeMap; - typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap; + typedef std::map<int, const bookmarks::BookmarkNode*> MenuIDToNodeMap; + typedef std::map<const bookmarks::BookmarkNode*, views::MenuItemView*> + NodeToMenuMap; // Creates a menu. This uses BuildMenu() to recursively populate the menu. - views::MenuItemView* CreateMenu(const BookmarkNode* parent, + views::MenuItemView* CreateMenu(const bookmarks::BookmarkNode* parent, int start_child_index, ShowOptions show_options); @@ -149,7 +149,7 @@ // represent it. If |node| is not empty and |added_separator| is false, a // separator is added before the new menu items and |added_separator| is set // to true. - void BuildMenuForPermanentNode(const BookmarkNode* node, + void BuildMenuForPermanentNode(const bookmarks::BookmarkNode* node, int icon_resource_id, views::MenuItemView* menu, int* next_menu_id, @@ -160,7 +160,7 @@ // Creates an entry in menu for each child node of |parent| starting at // |start_child_index|. - void BuildMenu(const BookmarkNode* parent, + void BuildMenu(const bookmarks::BookmarkNode* parent, int start_child_index, views::MenuItemView* menu, int* next_menu_id);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc index 87e3f732..571f387 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
@@ -18,6 +18,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; class BookmarkMenuDelegateTest : public BrowserWithTestWindowTest { public:
diff --git a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc index 934e8a9..55e7b98 100644 --- a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc
@@ -5,31 +5,17 @@ #include "chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h" #include "base/strings/string16.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/app_icon_loader_impl.h" -#include "chrome/browser/extensions/bookmark_app_helper.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/launch_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/app_list/app_list_service.h" -#include "chrome/browser/ui/app_list/app_list_util.h" -#include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/host_desktop.h" -#include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" -#include "extensions/browser/extension_prefs.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_system.h" -#include "extensions/browser/pref_names.h" -#include "extensions/browser/uninstall_reason.h" #include "extensions/common/constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/geometry/safe_integer_conversions.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_skia_source.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/image_view.h" @@ -51,50 +37,60 @@ // Size of the icon. const int kIconSize = extension_misc::EXTENSION_ICON_MEDIUM; -ExtensionService* GetExtensionService(Profile* profile) { - return extensions::ExtensionSystem::Get(profile)->extension_service(); -} +class WebAppInfoImageSource : public gfx::ImageSkiaSource { + public: + WebAppInfoImageSource(int dip_size, const WebApplicationInfo& info) + : dip_size_(dip_size), info_(info) {} + ~WebAppInfoImageSource() override {} + + private: + gfx::ImageSkiaRep GetImageForScale(float scale) override { + int size = gfx::ClampToInt(dip_size_ * scale); + for (const auto& icon_info : info_.icons) { + if (icon_info.width == size) { + return gfx::ImageSkiaRep(icon_info.data, scale); + } + } + return gfx::ImageSkiaRep(); + } + + int dip_size_; + WebApplicationInfo info_; +}; } // namespace -BookmarkAppBubbleView* BookmarkAppBubbleView::bookmark_app_bubble_ = NULL; - BookmarkAppBubbleView::~BookmarkAppBubbleView() { } // static -void BookmarkAppBubbleView::ShowBubble(views::View* anchor_view, - Profile* profile, - const WebApplicationInfo& web_app_info, - const std::string& extension_id) { - if (bookmark_app_bubble_ != NULL) - return; - - bookmark_app_bubble_ = new BookmarkAppBubbleView( - anchor_view, profile, web_app_info, extension_id); - views::BubbleDelegateView::CreateBubble(bookmark_app_bubble_)->Show(); +void BookmarkAppBubbleView::ShowBubble( + views::View* anchor_view, + const WebApplicationInfo& web_app_info, + const BrowserWindow::ShowBookmarkAppBubbleCallback& callback) { + // |bookmark_app_bubble| becomes owned by the BubbleDelegateView through the + // views system, and is freed when the BubbleDelegateView is closed and + // subsequently destroyed. + BookmarkAppBubbleView* bookmark_app_bubble = + new BookmarkAppBubbleView(anchor_view, web_app_info, callback); + views::BubbleDelegateView::CreateBubble(bookmark_app_bubble)->Show(); // Select the entire title textfield contents when the bubble is first shown. - bookmark_app_bubble_->title_tf_->SelectAll(true); - bookmark_app_bubble_->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); + bookmark_app_bubble->title_tf_->SelectAll(true); + bookmark_app_bubble->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); } BookmarkAppBubbleView::BookmarkAppBubbleView( views::View* anchor_view, - Profile* profile, const WebApplicationInfo& web_app_info, - const std::string& extension_id) + const BrowserWindow::ShowBookmarkAppBubbleCallback& callback) : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), - profile_(profile), web_app_info_(web_app_info), - extension_id_(extension_id), + user_accepted_(false), + callback_(callback), add_button_(NULL), cancel_button_(NULL), open_as_window_checkbox_(NULL), - title_tf_(NULL), - remove_app_(true), - app_icon_loader_(new extensions::AppIconLoaderImpl(profile, - kIconSize, - this)) { + title_tf_(NULL) { const SkColor background_color = GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_DialogBackground); set_arrow(views::BubbleBorder::TOP_CENTER); @@ -171,35 +167,33 @@ layout->AddView(title_label); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(profile_)->GetExtensionById( - extension_id_, extensions::ExtensionRegistry::EVERYTHING); - layout->StartRow(0, TITLE_TEXT_COLUMN_SET_ID); icon_image_view_ = new views::ImageView(); - icon_image_view_->SetImageSize(gfx::Size(kIconSize, kIconSize)); + + gfx::Size image_size(kIconSize, kIconSize); + gfx::ImageSkia image(new WebAppInfoImageSource(kIconSize, web_app_info_), + image_size); + icon_image_view_->SetImageSize(image_size); + icon_image_view_->SetImage(image); layout->AddView(icon_image_view_); - app_icon_loader_->FetchImage(extension_id_); title_tf_ = new views::Textfield(); - title_tf_->SetText(extension ? base::UTF8ToUTF16(extension->name()) - : web_app_info_.title); + title_tf_->SetText(web_app_info_.title); + title_tf_->set_controller(this); layout->AddView(title_tf_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); layout->StartRow(0, CONTENT_COLUMN_SET_ID); open_as_window_checkbox_ = new views::Checkbox( l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_WINDOW)); - open_as_window_checkbox_->SetChecked( - profile_->GetPrefs()->GetInteger( - extensions::pref_names::kBookmarkAppCreationLaunchType) == - extensions::LAUNCH_TYPE_WINDOW); + open_as_window_checkbox_->SetChecked(web_app_info_.open_as_window); layout->AddView(open_as_window_checkbox_); layout->AddView(add_button_); layout->AddView(cancel_button_); layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); + UpdateAddButtonState(); } views::View* BookmarkAppBubbleView::GetInitiallyFocusedView() { @@ -207,21 +201,7 @@ } void BookmarkAppBubbleView::WindowClosing() { - // We have to reset |bookmark_app_bubble_| here, not in our destructor, - // because we'll be destroyed asynchronously and the shown state will be - // checked before then. - DCHECK_EQ(bookmark_app_bubble_, this); - bookmark_app_bubble_ = NULL; - - if (remove_app_) { - GetExtensionService(profile_) - ->UninstallExtension(extension_id_, - extensions::UNINSTALL_REASON_INSTALL_CANCELED, - base::Bind(&base::DoNothing), - NULL); - } else { - ApplyEdits(); - } + callback_.Run(user_accepted_, web_app_info_); } bool BookmarkAppBubbleView::AcceleratorPressed( @@ -244,71 +224,29 @@ HandleButtonPressed(sender); } -void BookmarkAppBubbleView::SetAppImage(const std::string& id, - const gfx::ImageSkia& image) { - DCHECK_EQ(extension_id_, id); - icon_image_view_->SetImage(image); +void BookmarkAppBubbleView::ContentsChanged( + views::Textfield* sender, + const base::string16& new_contents) { + DCHECK_EQ(title_tf_, sender); + UpdateAddButtonState(); } void BookmarkAppBubbleView::HandleButtonPressed(views::Button* sender) { - // Unset |remove_app_| so we don't delete the bookmark after the window - // closes. - if (sender == add_button_) - remove_app_ = false; + if (sender == add_button_) { + user_accepted_ = true; + web_app_info_.title = GetTrimmedTitle(); + web_app_info_.open_as_window = open_as_window_checkbox_->checked(); + } GetWidget()->Close(); } -void BookmarkAppBubbleView::ApplyEdits() { - // Set the launch type based on the checkbox. - extensions::LaunchType launch_type = open_as_window_checkbox_->checked() - ? extensions::LAUNCH_TYPE_WINDOW - : extensions::LAUNCH_TYPE_REGULAR; - profile_->GetPrefs()->SetInteger( - extensions::pref_names::kBookmarkAppCreationLaunchType, launch_type); - extensions::SetLaunchType(profile_, extension_id_, launch_type); +void BookmarkAppBubbleView::UpdateAddButtonState() { + add_button_->SetEnabled(!GetTrimmedTitle().empty()); +} - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(profile_)->GetExtensionById( - extension_id_, extensions::ExtensionRegistry::EVERYTHING); - - if (!extension) - return; - - if (base::UTF8ToUTF16(extension->name()) != title_tf_->text()) { - // Reinstall the app with an updated name. - WebApplicationInfo install_info(web_app_info_); - install_info.title = title_tf_->text(); - - // This will asynchronously reload the extension, causing the Extension* - // we have to be destroyed. The extension ID will stay the same so that is - // used later on to highlight the app. - extensions::CreateOrUpdateBookmarkApp(GetExtensionService(profile_), - &install_info); - } - - // As the extension could be destroyed after this point, set it to null to - // prevent anyone trying to use it in future. - extension = nullptr; - - // Show the newly installed app in the app launcher or chrome://apps. - Profile* current_profile = profile_->GetOriginalProfile(); - if (IsAppLauncherEnabled()) { - chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow( - GetWidget()->GetNativeWindow()); - AppListService::Get(desktop) - ->ShowForAppInstall(current_profile, extension_id_, false); - return; - } - - chrome::NavigateParams params(current_profile, - GURL(chrome::kChromeUIAppsURL), - ui::PAGE_TRANSITION_LINK); - params.disposition = SINGLETON_TAB; - chrome::Navigate(¶ms); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, - content::Source<content::WebContents>(params.target_contents), - content::Details<const std::string>(&extension_id_)); +base::string16 BookmarkAppBubbleView::GetTrimmedTitle() { + base::string16 title(title_tf_->text()); + base::TrimWhitespace(title, base::TRIM_ALL, &title); + return title; }
diff --git a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h index 0bdb2d5a..688cf058 100644 --- a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h +++ b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h
@@ -7,16 +7,11 @@ #include "base/basictypes.h" #include "base/strings/string16.h" -#include "chrome/browser/extensions/app_icon_loader.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/common/web_application_info.h" #include "ui/views/bubble/bubble_delegate.h" #include "ui/views/controls/button/button.h" - -class Profile; - -namespace extensions { -class AppIconLoader; -} +#include "ui/views/controls/textfield/textfield_controller.h" namespace gfx { class ImageSkia; @@ -30,26 +25,26 @@ } // BookmarkAppBubbleView is a view intended to be used as the content of a -// Bubble. BookmarkAppBubbleView provides views for editing the bookmark app it -// is created with. Don't create a BookmarkAppBubbleView directly, instead use -// the static ShowBubble method. +// Bubble. BookmarkAppBubbleView provides views for editing the details to +// create a bookmark app with. Don't create a BookmarkAppBubbleView directly, +// instead use the static ShowBubble method. class BookmarkAppBubbleView : public views::BubbleDelegateView, public views::ButtonListener, - public extensions::AppIconLoader::Delegate { + public views::TextfieldController { public: ~BookmarkAppBubbleView() override; - static void ShowBubble(views::View* anchor_view, - Profile* profile, - const WebApplicationInfo& web_app_info, - const std::string& extension_id); + static void ShowBubble( + views::View* anchor_view, + const WebApplicationInfo& web_app_info, + const BrowserWindow::ShowBookmarkAppBubbleCallback& callback); private: // Creates a BookmarkAppBubbleView. - BookmarkAppBubbleView(views::View* anchor_view, - Profile* profile, - const WebApplicationInfo& web_app_info, - const std::string& extension_id); + BookmarkAppBubbleView( + views::View* anchor_view, + const WebApplicationInfo& web_app_info, + const BrowserWindow::ShowBookmarkAppBubbleCallback& callback); // Overriden from views::BubbleDelegateView: void Init() override; @@ -66,26 +61,27 @@ // Closes the bubble or opens the edit dialog. void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // Overridden from extensions::AppIconLoader::Delegate: - void SetAppImage(const std::string& id, const gfx::ImageSkia& image) override; + // Overridden from views::TextfieldController: + void ContentsChanged(views::Textfield* sender, + const base::string16& new_contents) override; // Handle the message when the user presses a button. void HandleButtonPressed(views::Button* sender); - // Sets the title and launch type of the app. - void ApplyEdits(); + // Update the state of the Add button. + void UpdateAddButtonState(); - // The bookmark app bubble, if we're showing one. - static BookmarkAppBubbleView* bookmark_app_bubble_; + // Get the trimmed contents of the title text field. + base::string16 GetTrimmedTitle(); - // The profile. - Profile* profile_; + // The WebApplicationInfo that the user is editing. + WebApplicationInfo web_app_info_; - // The WebApplicationInfo being used to create the app. - const WebApplicationInfo web_app_info_; + // Whether the user has accepted the dialog. + bool user_accepted_; - // The extension id of the bookmark app. - const std::string extension_id_; + // The callback to be invoked when the dialog is completed. + BrowserWindow::ShowBookmarkAppBubbleCallback callback_; // Button for removing the bookmark. views::LabelButton* add_button_; @@ -102,12 +98,6 @@ // Image showing the icon of the app. views::ImageView* icon_image_view_; - // When the destructor is invoked should the app be removed? - bool remove_app_; - - // Used to load the icon. - scoped_ptr<extensions::AppIconLoader> app_icon_loader_; - DISALLOW_COPY_AND_ASSIGN(BookmarkAppBubbleView); };
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index f1668c3..30bfc7d 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1234,11 +1234,8 @@ void BrowserView::ShowBookmarkAppBubble( const WebApplicationInfo& web_app_info, - const std::string& extension_id) { - BookmarkAppBubbleView::ShowBubble(GetToolbarView(), - browser_->profile(), - web_app_info, - extension_id); + const ShowBookmarkAppBubbleCallback& callback) { + BookmarkAppBubbleView::ShowBubble(GetToolbarView(), web_app_info, callback); } void BrowserView::ShowTranslateBubble(
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 83bcf2e..a85e479b 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -308,8 +308,9 @@ Profile* profile) override; void ShowUpdateChromeDialog() override; void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override; - void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info, - const std::string& extension_id) override; + void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const ShowBookmarkAppBubbleCallback& callback) override; void ShowTranslateBubble(content::WebContents* contents, translate::TranslateStep step, translate::TranslateErrors::Type error_type,
diff --git a/chrome/browser/ui/views/message_center/message_center_frame_view.cc b/chrome/browser/ui/views/message_center/message_center_frame_view.cc index 2a61ccb..07a8774f 100644 --- a/chrome/browser/ui/views/message_center/message_center_frame_view.cc +++ b/chrome/browser/ui/views/message_center/message_center_frame_view.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/message_center/message_center_frame_view.h" #include "ui/base/hit_test.h" +#include "ui/gfx/shadow_value.h" #include "ui/message_center/message_center_style.h" #include "ui/views/shadow_border.h" #include "ui/views/widget/widget.h" @@ -19,10 +20,8 @@ #else const int kShadowBlur = 8; SetBorder(scoped_ptr<views::Border>(new views::ShadowBorder( - kShadowBlur, - message_center::kMessageCenterShadowColor, - 0, // Vertical offset - 0))); // Horizontal offset + gfx::ShadowValue(gfx::Point(0, 0), kShadowBlur, + message_center::kMessageCenterShadowColor)))); #endif }
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 188dc8c7..3e4ae7b 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -1246,8 +1246,15 @@ const AvatarMenu::Item& item = avatar_menu_->GetItemAt(index); const int kSmallImageSide = 32; + // Use the low-res, small default avatars in the fast user switcher, like + // we do in the menu bar. + gfx::Image item_icon; + bool is_rectangle; + AvatarMenu::GetImageForMenuButton( + item.profile_path, &item_icon, &is_rectangle); + gfx::Image image = profiles::GetSizedAvatarIcon( - item.icon, true, kSmallImageSide, kSmallImageSide); + item_icon, true, kSmallImageSide, kSmallImageSide); views::LabelButton* button = new BackgroundColorHoverButton( this,
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc index c56b9dd..946c021 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
@@ -227,7 +227,7 @@ view_controller->GetActionName(); ToolbarActionView* view = - new ToolbarActionView(view_controller, browser_, this); + new ToolbarActionView(view_controller, browser_->profile(), this); toolbar_action_views_.insert(toolbar_action_views_.begin() + index, view); AddChildViewAt(view, index); }
diff --git a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc index f3ea71a5..daf7a11a 100644 --- a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
@@ -233,7 +233,7 @@ scoped_refptr<ExtensionContextMenuModel> context_menu_contents = new ExtensionContextMenuModel(view_controller->extension(), - view->browser(), + view_controller->browser(), view_controller); views::MenuRunner context_menu_runner(context_menu_contents.get(), views::MenuRunner::HAS_MNEMONICS |
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index fcc64769..7ef849d 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -11,14 +11,11 @@ #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/browser/ui/views/toolbar/wrench_toolbar_button.h" #include "chrome/grit/generated_resources.h" +#include "content/public/browser/notification_source.h" #include "grit/theme_resources.h" #include "ui/accessibility/ax_view_state.h" #include "ui/base/resource/resource_bundle.h" @@ -44,11 +41,11 @@ ToolbarActionView::ToolbarActionView( ToolbarActionViewController* view_controller, - Browser* browser, + Profile* profile, ToolbarActionView::Delegate* delegate) : MenuButton(this, base::string16(), NULL, false), view_controller_(view_controller), - browser_(browser), + profile_(profile), delegate_(delegate), called_register_command_(false), wants_to_run_(false) { @@ -64,7 +61,7 @@ this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, content::Source<ThemeService>( - ThemeServiceFactory::GetForProfile(browser->profile()))); + ThemeServiceFactory::GetForProfile(profile_))); wants_to_run_border_ = CreateDefaultBorder(); DecorateWantsToRunBorder(wants_to_run_border_.get()); @@ -149,8 +146,7 @@ gfx::ImageSkia icon(view_controller_->GetIcon(web_contents).AsImageSkia()); if (!icon.isNull()) { - ThemeService* theme = - ThemeServiceFactory::GetForProfile(browser_->profile()); + ThemeService* theme = ThemeServiceFactory::GetForProfile(profile_); gfx::ImageSkia bg = *theme->GetImageSkiaNamed(IDR_BROWSER_ACTION); SetImage(views::Button::STATE_NORMAL, @@ -253,8 +249,7 @@ // RunMenuAt expects a nested menu to be parented by the same widget as the // already visible menu, in this case the Chrome menu. return delegate_->ShownInsideMenu() ? - BrowserView::GetBrowserViewForBrowser(browser_) - ->toolbar()->app_menu()->GetWidget() : + delegate_->GetOverflowReferenceView()->GetWidget() : GetWidget(); }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.h b/chrome/browser/ui/views/toolbar/toolbar_action_view.h index dde788fd..debef33 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.h
@@ -13,8 +13,8 @@ #include "ui/views/drag_controller.h" #include "ui/views/view.h" -class Browser; class ExtensionAction; +class Profile; namespace extensions { class Extension; @@ -63,7 +63,7 @@ }; ToolbarActionView(ToolbarActionViewController* view_controller, - Browser* browser, + Profile* profile, Delegate* delegate); ~ToolbarActionView() override; @@ -102,7 +102,6 @@ ToolbarActionViewController* view_controller() { return view_controller_; } - Browser* browser() { return browser_; } // Returns button icon so it can be accessed during tests. gfx::ImageSkia GetIconForTest(); @@ -137,8 +136,8 @@ // The controller for this toolbar action view. ToolbarActionViewController* view_controller_; - // The associated browser. - Browser* browser_; + // The associated profile. + Profile* profile_; // Delegate that usually represents a container for ToolbarActionView. Delegate* delegate_;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc new file mode 100644 index 0000000..fe711579 --- /dev/null +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc
@@ -0,0 +1,267 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/run_loop.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/sessions/session_tab_helper.h" +#include "chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h" +#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" +#include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread.h" +#include "content/public/test/test_renderer_host.h" +#include "content/public/test/web_contents_tester.h" +#include "ui/accessibility/ax_view_state.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/test/views_test_base.h" + +#if defined(USE_AURA) +#include "ui/aura/env.h" +#endif + +namespace { + +// A helper class to create test web contents (tabs) for unit tests, without +// inheriting from RenderViewTestHarness. Can create web contents, and will +// clean up after itself upon destruction. Owns all created web contents. +// A few notes: +// - Works well allocated on the stack, because it should be destroyed before +// associated browser context. +// - Doesn't play nice with web contents created any other way (because of +// the implementation of RenderViewHostTestEnabler). But if you are creating +// web contents already, what do you need this for? ;) +// TODO(devlin): Look around and see if this class is needed elsewhere; if so, +// move it there and expand the API a bit (methods to, e.g., delete/close a +// web contents, access existing web contents, etc). +class TestWebContentsFactory { + public: + // |init_aura| initializes the aura environment (and cleans it up at + // shutdown, which is necessary for web contents. Since this method should + // only be called once, this should only be true if no other part of the test + // has initialized the environment. + explicit TestWebContentsFactory(bool init_aura); + ~TestWebContentsFactory(); + + // Creates a new WebContents with the given |context|, and returns it. + content::WebContents* CreateWebContents(content::BrowserContext* context); + private: + // The test factory (and friends) for creating test web contents. + scoped_ptr<content::RenderViewHostTestEnabler> rvh_enabler_; + // The vector of web contents that this class created. + ScopedVector<content::WebContents> web_contents_; + + // True if the factory initialized aura (and should thus tear it down). + bool init_aura_; + + DISALLOW_COPY_AND_ASSIGN(TestWebContentsFactory); +}; + +TestWebContentsFactory::TestWebContentsFactory(bool init_aura) + : rvh_enabler_(new content::RenderViewHostTestEnabler()), + init_aura_(init_aura) { +#if defined(USE_AURA) + if (init_aura) + aura::Env::CreateInstance(true); +#endif +} + +TestWebContentsFactory::~TestWebContentsFactory() { + web_contents_.clear(); + // Let any posted tasks for web contents deletion run. + base::RunLoop().RunUntilIdle(); + rvh_enabler_.reset(); + // Let any posted tasks for RenderProcess/ViewHost deletion run. + base::RunLoop().RunUntilIdle(); +#if defined(USE_AURA) + if (init_aura_) + aura::Env::DeleteInstance(); +#endif +} + +content::WebContents* TestWebContentsFactory::CreateWebContents( + content::BrowserContext* context) { + scoped_ptr<content::WebContents> web_contents( + content::WebContentsTester::CreateTestWebContents(context, nullptr)); + DCHECK(web_contents); + web_contents_.push_back(web_contents.release()); + return web_contents_.back(); +} + +// A test delegate for a toolbar action view. +class TestToolbarActionViewDelegate : public ToolbarActionView::Delegate { + public: + TestToolbarActionViewDelegate() : shown_in_menu_(false), + overflow_reference_view_(nullptr), + web_contents_(nullptr) {} + ~TestToolbarActionViewDelegate() override {} + + // ToolbarActionView::Delegate: + content::WebContents* GetCurrentWebContents() override { + return web_contents_; + } + bool ShownInsideMenu() const override { return shown_in_menu_; } + void OnToolbarActionViewDragDone() override {} + views::MenuButton* GetOverflowReferenceView() override { + return overflow_reference_view_; + } + void SetPopupOwner(ToolbarActionView* popup_owner) override {} + ToolbarActionView* GetMainViewForAction(ToolbarActionView* view) override { + return nullptr; + } + void WriteDragDataForView(views::View* sender, + const gfx::Point& press_pt, + ui::OSExchangeData* data) override {} + int GetDragOperationsForView(views::View* sender, + const gfx::Point& p) override { + return ui::DragDropTypes::DRAG_NONE; + } + bool CanStartDragForView(views::View* sender, + const gfx::Point& press_pt, + const gfx::Point& p) override { return false; } + + void set_shown_in_menu(bool shown_in_menu) { shown_in_menu_ = shown_in_menu; } + void set_overflow_reference_view(views::MenuButton* overflow_reference_view) { + overflow_reference_view_ = overflow_reference_view; + } + void set_web_contents(content::WebContents* web_contents) { + web_contents_ = web_contents; + } + + private: + bool shown_in_menu_; + + views::MenuButton* overflow_reference_view_; + + content::WebContents* web_contents_; + + DISALLOW_COPY_AND_ASSIGN(TestToolbarActionViewDelegate); +}; + +} // namespace + +class ToolbarActionViewUnitTest : public views::ViewsTestBase { + public: + ToolbarActionViewUnitTest() + : widget_(nullptr), + ui_thread_(content::BrowserThread::UI, message_loop()) {} + ~ToolbarActionViewUnitTest() override {} + + void SetUp() override { + views::ViewsTestBase::SetUp(); + + widget_ = new views::Widget; + views::Widget::InitParams params = + CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.bounds = gfx::Rect(0, 0, 200, 200); + widget_->Init(params); + } + void TearDown() override { + if (!widget_->IsClosed()) + widget_->Close(); + views::ViewsTestBase::TearDown(); + } + + views::Widget* widget() { return widget_; } + + private: + // The widget managed by this test. + views::Widget* widget_; + + // Web contents need a fake ui thread. + content::TestBrowserThread ui_thread_; + + DISALLOW_COPY_AND_ASSIGN(ToolbarActionViewUnitTest); +}; + +// Test the basic ui of a ToolbarActionView and that it responds correctly to +// a controller's state. +TEST_F(ToolbarActionViewUnitTest, BasicToolbarActionViewTest) { + TestingProfile profile; + + // ViewsTestBase initializees the aura environment, so the factory shouldn't. + TestWebContentsFactory web_contents_factory(false); + + TestToolbarActionViewController controller("fake controller"); + TestToolbarActionViewDelegate action_view_delegate; + + // Configure the test controller and delegate. + base::string16 name = base::ASCIIToUTF16("name"); + controller.SetAccessibleName(name); + base::string16 tooltip = base::ASCIIToUTF16("tooltip"); + controller.SetTooltip(tooltip); + content::WebContents* web_contents = + web_contents_factory.CreateWebContents(&profile); + SessionTabHelper::CreateForWebContents(web_contents); + action_view_delegate.set_web_contents(web_contents); + + // Move the mouse off the not-yet-existent button. + ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); + generator.MoveMouseTo(gfx::Point(300, 300)); + + // Create a new toolbar action view. + ToolbarActionView view(&controller, &profile, &action_view_delegate); + view.set_owned_by_client(); + view.SetBoundsRect(gfx::Rect(0, 0, 200, 20)); + widget()->SetContentsView(&view); + widget()->Show(); + + // Check that the tooltip and accessible state of the view match the + // controller's. + base::string16 tooltip_test; + EXPECT_TRUE(view.GetTooltipText(gfx::Point(), &tooltip_test)); + EXPECT_EQ(tooltip, tooltip_test); + ui::AXViewState ax_state; + view.GetAccessibleState(&ax_state); + EXPECT_EQ(name, ax_state.name); + + // The button should start in normal state, with no actions executed. + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + EXPECT_EQ(0, controller.execute_action_count()); + + // Click the button. This should execute it. + generator.MoveMouseTo(gfx::Point(10, 10)); + generator.ClickLeftButton(); + EXPECT_EQ(1, controller.execute_action_count()); + + // Move the mouse off the button, and show a popup through a non-user action. + // Since this was not a user action, the button should not be pressed. + generator.MoveMouseTo(gfx::Point(300, 300)); + controller.ShowPopup(false); + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + controller.HidePopup(); + + // Show the popup through a user action - the button should be pressed. + controller.ShowPopup(true); + EXPECT_EQ(views::Button::STATE_PRESSED, view.state()); + controller.HidePopup(); + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + + // Ensure that the button's enabled state reflects that of the controller. + controller.SetEnabled(false); + EXPECT_EQ(views::Button::STATE_DISABLED, view.state()); + controller.SetEnabled(true); + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + + // Ensure that the button's want-to-run state reflects that of the controller. + controller.SetWantsToRun(true); + EXPECT_TRUE(view.wants_to_run_for_testing()); + controller.SetWantsToRun(false); + EXPECT_FALSE(view.wants_to_run_for_testing()); + + // Create an overflow button. + views::MenuButton overflow_button(nullptr, base::string16(), nullptr, false); + overflow_button.set_owned_by_client(); + action_view_delegate.set_overflow_reference_view(&overflow_button); + + // If the view isn't visible, the overflow button should be pressed for + // popups. + view.SetVisible(false); + controller.ShowPopup(true); + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + EXPECT_EQ(views::Button::STATE_PRESSED, overflow_button.state()); + controller.HidePopup(); + EXPECT_EQ(views::Button::STATE_NORMAL, view.state()); + EXPECT_EQ(views::Button::STATE_NORMAL, overflow_button.state()); +}
diff --git a/chrome/browser/ui/views/toolbar/wrench_menu.cc b/chrome/browser/ui/views/toolbar/wrench_menu.cc index 55c85ab..3d3f5ca9 100644 --- a/chrome/browser/ui/views/toolbar/wrench_menu.cc +++ b/chrome/browser/ui/views/toolbar/wrench_menu.cc
@@ -787,12 +787,13 @@ // WrenchMenu ------------------------------------------------------------------ WrenchMenu::WrenchMenu(Browser* browser, int run_flags) - : root_(NULL), + : root_(nullptr), browser_(browser), - selected_menu_model_(NULL), + selected_menu_model_(nullptr), selected_index_(0), - bookmark_menu_(NULL), - feedback_menu_item_(NULL), + bookmark_menu_(nullptr), + feedback_menu_item_(nullptr), + screenshot_menu_item_(nullptr), run_flags_(run_flags) { registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, content::Source<Profile>(browser_->profile())); @@ -1053,10 +1054,11 @@ void WrenchMenu::WillHideMenu(MenuItemView* menu) { // Turns off the fade out animation of the wrench menus if - // |feedback_menu_item_| is selected. This excludes the wrench menu itself - // from the snapshot in the feedback UI. - if (menu->HasSubmenu() && feedback_menu_item_ && - feedback_menu_item_->IsSelected()) { + // |feedback_menu_item_| or |screenshot_menu_item_| is selected. This + // excludes the wrench menu itself from the screenshot. + if (menu->HasSubmenu() && + ((feedback_menu_item_ && feedback_menu_item_->IsSelected()) || + (screenshot_menu_item_ && screenshot_menu_item_->IsSelected()))) { // It's okay to just turn off the animation and no to take care the // animation back because the menu widget will be recreated next time // it's opened. See ToolbarView::RunMenu() and Init() of this class. @@ -1161,6 +1163,13 @@ break; #endif +#if defined(OS_CHROMEOS) + case IDC_TAKE_SCREENSHOT: + DCHECK(!screenshot_menu_item_); + screenshot_menu_item_ = item; + break; +#endif + case IDC_RECENT_TABS_MENU: DCHECK(!recent_tabs_menu_model_delegate_.get()); recent_tabs_menu_model_delegate_.reset(
diff --git a/chrome/browser/ui/views/toolbar/wrench_menu.h b/chrome/browser/ui/views/toolbar/wrench_menu.h index 1966dd2f2..22fb8973 100644 --- a/chrome/browser/ui/views/toolbar/wrench_menu.h +++ b/chrome/browser/ui/views/toolbar/wrench_menu.h
@@ -176,6 +176,9 @@ // Menu corresponding to IDC_FEEDBACK. views::MenuItemView* feedback_menu_item_; + // Menu corresponding to IDC_TAKE_SCREENSHOT. + views::MenuItemView* screenshot_menu_item_; + // Used for managing "Recent tabs" menu items. scoped_ptr<RecentTabsMenuModelDelegate> recent_tabs_menu_model_delegate_;
diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc index 0395007..1bf465a 100644 --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc
@@ -133,43 +133,10 @@ index_, permission.setting == CONTENT_SETTING_ALLOW); } -// A combobox originating on the Allow button allowing for customization -// of permissions. -class CustomizeAllowComboboxModel : public ui::ComboboxModel { - public: - enum Item { - INDEX_ALLOW = 0, - INDEX_CUSTOMIZE = 1 - }; - - CustomizeAllowComboboxModel() {} - ~CustomizeAllowComboboxModel() override {} - - int GetItemCount() const override; - base::string16 GetItemAt(int index) override; - int GetDefaultIndex() const override; -}; - -int CustomizeAllowComboboxModel::GetItemCount() const { - return 2; -} - -base::string16 CustomizeAllowComboboxModel::GetItemAt(int index) { - if (index == INDEX_ALLOW) - return l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW); - else - return l10n_util::GetStringUTF16(IDS_PERMISSION_CUSTOMIZE); -} - -int CustomizeAllowComboboxModel::GetDefaultIndex() const { - return INDEX_ALLOW; -} - /////////////////////////////////////////////////////////////////////////////// // View implementation for the permissions bubble. class PermissionsBubbleDelegateView : public views::BubbleDelegateView, public views::ButtonListener, - public views::ComboboxListener, public PermissionCombobox::Listener { public: PermissionsBubbleDelegateView( @@ -177,8 +144,7 @@ PermissionBubbleViewViews* owner, const std::string& languages, const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode); + const std::vector<bool>& accept_state); ~PermissionsBubbleDelegateView() override; void Close(); @@ -194,9 +160,6 @@ // ButtonListener: void ButtonPressed(views::Button* button, const ui::Event& event) override; - // ComboboxListener: - void OnPerformAction(views::Combobox* combobox) override; - // PermissionCombobox::Listener: void PermissionSelectionChanged(int index, bool allowed) override; @@ -217,8 +180,7 @@ PermissionBubbleViewViews* owner, const std::string& languages, const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) + const std::vector<bool>& accept_state) : views::BubbleDelegateView(anchor, views::BubbleBorder::TOP_LEFT), owner_(owner), allow_(NULL), @@ -244,8 +206,8 @@ for (size_t index = 0; index < requests.size(); index++) { DCHECK(index < accept_state.size()); // The row is laid out containing a leading-aligned label area and a - // trailing column which will be filled during customization with a - // combobox. + // trailing column which will be filled if there are multiple permission + // requests. views::View* row = new views::View(); views::GridLayout* row_layout = new views::GridLayout(row); row->SetLayoutManager(row_layout); @@ -272,7 +234,7 @@ label_container->AddChildView(label); row_layout->AddView(label_container); - if (customization_mode) { + if (requests.size() > 1) { PermissionCombobox* combobox = new PermissionCombobox( this, index, @@ -293,8 +255,8 @@ button_row->SetLayoutManager(button_layout); AddChildView(button_row); - // Customization case: just an "OK" button - if (customization_mode) { + // For multiple permissions: just an "OK" button. + if (requests.size() > 1) { columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 100, views::GridLayout::USE_PREF, 0, 0); button_layout->StartRowWithPadding(0, 0, 0, 4); @@ -308,8 +270,7 @@ return; } - // No customization: lay out the Deny/Allow buttons. - + // For a single permission: lay out the Deny/Allow buttons. columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 100, views::GridLayout::USE_PREF, 0, 0); columns->AddPaddingColumn(0, kItemMajorSpacing - (2*kButtonBorderSize)); @@ -317,26 +278,11 @@ 0, views::GridLayout::USE_PREF, 0, 0); button_layout->StartRow(0, 0); - // Allow button is a regular button when there's only one option, and a - // STYLE_ACTION Combobox when there are more than one option and - // customization is an option. - base::string16 allow_text = l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW); - if (requests.size() == 1) { - views::LabelButton* allow_button = new views::LabelButton(this, allow_text); - allow_button->SetStyle(views::Button::STYLE_BUTTON); - button_layout->AddView(allow_button); - allow_ = allow_button; - } else { - views::Combobox* allow_combobox = new views::Combobox( - new CustomizeAllowComboboxModel()); - allow_combobox->set_listener(this); - allow_combobox->SetStyle(views::Combobox::STYLE_ACTION); - allow_combobox->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_COMBOBOX)); - button_layout->AddView(allow_combobox); - allow_combobox_ = allow_combobox; - } + views::LabelButton* allow_button = new views::LabelButton(this, allow_text); + allow_button->SetStyle(views::Button::STYLE_BUTTON); + button_layout->AddView(allow_button); + allow_ = allow_button; base::string16 deny_text = l10n_util::GetStringUTF16(IDS_PERMISSION_DENY); views::LabelButton* deny_button = new views::LabelButton(this, deny_text); @@ -403,18 +349,6 @@ owner_->Toggle(index, allowed); } -void PermissionsBubbleDelegateView::OnPerformAction( - views::Combobox* combobox) { - if (combobox == allow_combobox_) { - if (combobox->selected_index() == - CustomizeAllowComboboxModel::INDEX_CUSTOMIZE) - owner_->SetCustomizationMode(); - else if (combobox->selected_index() == - CustomizeAllowComboboxModel::INDEX_ALLOW) - owner_->Accept(); - } -} - ////////////////////////////////////////////////////////////////////////////// // PermissionBubbleViewViews @@ -437,14 +371,13 @@ void PermissionBubbleViewViews::Show( const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& values, - bool customization_mode) { + const std::vector<bool>& values) { if (bubble_delegate_ != NULL) bubble_delegate_->Close(); bubble_delegate_ = new PermissionsBubbleDelegateView(anchor_view_, this, languages_, - requests, values, customization_mode); + requests, values); views::BubbleDelegateView::CreateBubble(bubble_delegate_)->Show(); bubble_delegate_->SizeToContents(); } @@ -485,8 +418,3 @@ if (delegate_) delegate_->Deny(); } - -void PermissionBubbleViewViews::SetCustomizationMode() { - if (delegate_) - delegate_->SetCustomizationMode(); -}
diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.h b/chrome/browser/ui/views/website_settings/permissions_bubble_view.h index 886bb207..9091b56f 100644 --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.h +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.h
@@ -26,8 +26,7 @@ // PermissionBubbleView: void SetDelegate(Delegate* delegate) override; void Show(const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) override; + const std::vector<bool>& accept_state) override; bool CanAcceptRequestUpdate() override; void Hide() override; bool IsVisible() override; @@ -36,7 +35,6 @@ void Toggle(int index, bool value); void Accept(); void Deny(); - void SetCustomizationMode(); private: views::View* anchor_view_;
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc index 54bdee4..51ffb802 100644 --- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc +++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
@@ -160,7 +160,7 @@ //////////////////////////////////////////////////////////////////////////////// PopupHeaderView::PopupHeaderView(views::ButtonListener* close_button_listener) - : name_(NULL), status_(NULL) { + : name_(nullptr), status_(nullptr) { views::GridLayout* layout = new views::GridLayout(this); SetLayoutManager(layout); @@ -301,20 +301,20 @@ : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT), web_contents_(web_contents), browser_(browser), - header_(NULL), - tabbed_pane_(NULL), - site_data_content_(NULL), - cookie_dialog_link_(NULL), - permissions_content_(NULL), - connection_tab_(NULL), - identity_info_content_(NULL), - certificate_dialog_link_(NULL), - signed_certificate_timestamps_link_(NULL), - reset_decisions_button_(NULL), + header_(nullptr), + tabbed_pane_(nullptr), + site_data_content_(nullptr), + cookie_dialog_link_(nullptr), + permissions_content_(nullptr), + connection_tab_(nullptr), + identity_info_content_(nullptr), + certificate_dialog_link_(nullptr), + signed_certificate_timestamps_link_(nullptr), + reset_decisions_button_(nullptr), cert_id_(0), - help_center_link_(NULL), - connection_info_content_(NULL), - page_info_content_(NULL), + help_center_link_(nullptr), + connection_info_content_(nullptr), + page_info_content_(nullptr), weak_factory_(this) { // Compensate for built-in vertical padding in the anchor view's image. set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0, @@ -396,7 +396,7 @@ new CollectedCookiesViews(web_contents_); } else if (source == certificate_dialog_link_) { gfx::NativeWindow parent = GetAnchorView() ? - GetAnchorView()->GetWidget()->GetNativeWindow() : NULL; + GetAnchorView()->GetWidget()->GetNativeWindow() : nullptr; presenter_->RecordWebsiteSettingsAction( WebsiteSettings::WEBSITE_SETTINGS_CERTIFICATE_DIALOG_OPENED); ShowCertificateViewerByID(web_contents_, parent, cert_id_); @@ -440,7 +440,7 @@ } gfx::Size WebsiteSettingsPopupView::GetPreferredSize() const { - if (header_ == NULL && tabbed_pane_ == NULL) + if (header_ == nullptr && tabbed_pane_ == nullptr) return views::View::GetPreferredSize(); int height = 0; @@ -619,9 +619,9 @@ WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status), base::string16(), // The connection section has no headline. base::UTF8ToUTF16(identity_info.connection_status_description), - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr); connection_tab_->InvalidateLayout(); Layout(); @@ -635,9 +635,9 @@ WebsiteSettingsUI::GetFirstVisitIcon(first_visit), l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE), first_visit, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr); connection_tab_->InvalidateLayout(); Layout(); SizeToContents(); @@ -668,7 +668,7 @@ CreateSection(l10n_util::GetStringUTF16( IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS), permissions_content_, - NULL); + nullptr); pane->AddChildView(permissions_section); return pane; }
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.cc b/chrome/browser/ui/website_settings/permission_bubble_manager.cc index b8d26d5..b8a53e5f 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc +++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc
@@ -83,7 +83,6 @@ bubble_showing_(false), view_(NULL), request_url_has_loaded_(false), - customization_mode_(false), weak_factory_(this) {} PermissionBubbleManager::~PermissionBubbleManager() { @@ -271,12 +270,6 @@ accept_states_[request_index] = new_value; } -void PermissionBubbleManager::SetCustomizationMode() { - customization_mode_ = true; - if (view_) - view_->Show(requests_, accept_states_, customization_mode_); -} - void PermissionBubbleManager::Accept() { std::vector<PermissionBubbleRequest*>::iterator requests_iter; std::vector<bool>::iterator accepts_iter = accept_states_.begin(); @@ -352,7 +345,7 @@ // Note: this should appear above Show() for testing, since in that // case we may do in-line calling of finalization. bubble_showing_ = true; - view_->Show(requests_, accept_states_, customization_mode_); + view_->Show(requests_, accept_states_); } void PermissionBubbleManager::FinalizeBubble() {
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.h b/chrome/browser/ui/website_settings/permission_bubble_manager.h index 414184b..15d384fa 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager.h +++ b/chrome/browser/ui/website_settings/permission_bubble_manager.h
@@ -85,7 +85,6 @@ // PermissionBubbleView::Delegate: void ToggleAccept(int request_index, bool new_value) override; - void SetCustomizationMode() override; void Accept() override; void Deny() override; void Closing() override; @@ -137,7 +136,6 @@ bool request_url_has_loaded_; std::vector<bool> accept_states_; - bool customization_mode_; base::WeakPtrFactory<PermissionBubbleManager> weak_factory_; };
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc index c866fb14..4ec4a02 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc +++ b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc
@@ -32,8 +32,7 @@ void SetDelegate(Delegate* delegate) override { delegate_ = delegate; } void Show(const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_state_) override { + const std::vector<bool>& accept_state) override { shown_ = true; permission_requests_ = requests; permission_states_ = accept_state;
diff --git a/chrome/browser/ui/website_settings/permission_bubble_view.h b/chrome/browser/ui/website_settings/permission_bubble_view.h index 669c997..6c34474 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_view.h +++ b/chrome/browser/ui/website_settings/permission_bubble_view.h
@@ -23,7 +23,6 @@ virtual ~Delegate() {} virtual void ToggleAccept(int index, bool new_value) = 0; - virtual void SetCustomizationMode() = 0; virtual void Accept() = 0; virtual void Deny() = 0; virtual void Closing() = 0; @@ -43,8 +42,7 @@ // in this call. virtual void Show( const std::vector<PermissionBubbleRequest*>& requests, - const std::vector<bool>& accept_state, - bool customization_mode) = 0; + const std::vector<bool>& accept_state) = 0; // Returns true if the view can accept a new Show() command to coalesce // requests. Currently the policy is that this should return true if the view
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc index b93254c..b568e64 100644 --- a/chrome/browser/ui/webui/about_ui.cc +++ b/chrome/browser/ui/webui/about_ui.cc
@@ -843,10 +843,8 @@ return data; } -void AboutSandboxRow(std::string* data, const std::string& prefix, int name_id, - bool good) { +void AboutSandboxRow(std::string* data, int name_id, bool good) { data->append("<tr><td>"); - data->append(prefix); data->append(l10n_util::GetStringUTF8(name_id)); if (good) { data->append("</td><td style='color: green;'>"); @@ -873,31 +871,26 @@ data.append("<table>"); - AboutSandboxRow(&data, - std::string(), - IDS_ABOUT_SANDBOX_SUID_SANDBOX, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_SUID_SANDBOX, status & content::kSandboxLinuxSUID); - AboutSandboxRow(&data, " ", IDS_ABOUT_SANDBOX_PID_NAMESPACES, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_NAMESPACE_SANDBOX, + status & content::kSandboxLinuxUserNS); + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_PID_NAMESPACES, status & content::kSandboxLinuxPIDNS); - AboutSandboxRow(&data, " ", IDS_ABOUT_SANDBOX_NET_NAMESPACES, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_NET_NAMESPACES, status & content::kSandboxLinuxNetNS); - AboutSandboxRow(&data, - std::string(), - IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX, status & content::kSandboxLinuxSeccompBPF); - AboutSandboxRow(&data, - std::string(), - IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX_TSYNC, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_SECCOMP_BPF_SANDBOX_TSYNC, status & content::kSandboxLinuxSeccompTSYNC); - AboutSandboxRow(&data, - std::string(), - IDS_ABOUT_SANDBOX_YAMA_LSM, + AboutSandboxRow(&data, IDS_ABOUT_SANDBOX_YAMA_LSM, status & content::kSandboxLinuxYama); data.append("</table>"); - // The setuid sandbox is required as our first-layer sandbox. - bool good_layer1 = status & content::kSandboxLinuxSUID && + // Require either the setuid or namespace sandbox for our first-layer sandbox. + bool good_layer1 = (status & content::kSandboxLinuxSUID || + status & content::kSandboxLinuxUserNS) && status & content::kSandboxLinuxPIDNS && status & content::kSandboxLinuxNetNS; // A second-layer sandbox is also required to be adequately sandboxed.
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc index 7969a52..57efa4d 100644 --- a/chrome/browser/ui/webui/certificate_viewer_webui.cc +++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -350,16 +350,14 @@ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER)); base::Time issued, expires; if (x509_certificate_model::GetTimes(cert, &issued, &expires)) { - // The object Time internally saves the time in UTC timezone. This is why we - // do a simple UTC string concatenation. node_details->SetString( "payload.val", - base::UTF16ToUTF8(base::TimeFormatShortDateAndTime(issued)) + " " + - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_UTC_TIMEZONE)); + base::UTF16ToUTF8( + base::TimeFormatShortDateAndTimeWithTimeZone(issued))); alt_node_details->SetString( "payload.val", - base::UTF16ToUTF8(base::TimeFormatShortDateAndTime(expires)) + " " + - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_UTC_TIMEZONE)); + base::UTF16ToUTF8( + base::TimeFormatShortDateAndTimeWithTimeZone(expires))); } cert_fields->Append(node_details = new base::DictionaryValue());
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 120d49b2..d2a1273 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -36,6 +36,7 @@ #include "chrome/browser/ui/webui/interstitials/interstitial_ui.h" #include "chrome/browser/ui/webui/invalidations_ui.h" #include "chrome/browser/ui/webui/local_state/local_state_ui.h" +#include "chrome/browser/ui/webui/md_settings_ui.h" #include "chrome/browser/ui/webui/memory_internals/memory_internals_ui.h" #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h" #include "chrome/browser/ui/webui/omnibox/omnibox_ui.h" @@ -367,6 +368,10 @@ return &NewWebUI<IdentityInternalsUI>; if (url.host() == chrome::kChromeUINewTabHost) return &NewWebUI<NewTabUI>; + if (url.host() == chrome::kChromeUIMdSettingsHost && + ::switches::MdSettingsEnabled()) { + return &NewWebUI<MdSettingsUI>; + } // Android does not support plugins for now. if (url.host() == chrome::kChromeUIPluginsHost) return &NewWebUI<PluginsUI>;
diff --git a/chrome/browser/ui/webui/chromeos/OWNERS b/chrome/browser/ui/webui/chromeos/OWNERS index dd4971f..2ac29f5 100644 --- a/chrome/browser/ui/webui/chromeos/OWNERS +++ b/chrome/browser/ui/webui/chromeos/OWNERS
@@ -3,6 +3,7 @@ nkostylev@chromium.org achuith@chromium.org satorux@chromium.org +stevenjb@chromium.org per-file choose_mobile_network_ui.*=armansito@chromium.org per-file network*=stevenjb@chromium.org
diff --git a/chrome/browser/ui/webui/chromeos/network_config_message_handler.cc b/chrome/browser/ui/webui/chromeos/network_config_message_handler.cc deleted file mode 100644 index ec5833e..0000000 --- a/chrome/browser/ui/webui/chromeos/network_config_message_handler.cc +++ /dev/null
@@ -1,238 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/chromeos/network_config_message_handler.h" - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/logging.h" -#include "base/values.h" -#include "chromeos/login/login_state.h" -#include "chromeos/network/device_state.h" -#include "chromeos/network/managed_network_configuration_handler.h" -#include "chromeos/network/network_configuration_handler.h" -#include "chromeos/network/network_state.h" -#include "chromeos/network/network_state_handler.h" -#include "chromeos/network/network_util.h" -#include "chromeos/network/onc/onc_signature.h" -#include "chromeos/network/onc/onc_utils.h" -#include "chromeos/network/shill_property_util.h" -#include "components/onc/onc_constants.h" -#include "content/public/browser/web_ui.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { - -namespace { - -bool GetServicePathFromGuid(const std::string& guid, - std::string* service_path) { - const NetworkState* network = - NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid( - guid); - if (!network) - return false; - *service_path = network->path(); - return true; -} - -} // namespace - -NetworkConfigMessageHandler::NetworkConfigMessageHandler() - : weak_ptr_factory_(this) { -} - -NetworkConfigMessageHandler::~NetworkConfigMessageHandler() { -} - -void NetworkConfigMessageHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "networkConfig.getNetworks", - base::Bind(&NetworkConfigMessageHandler::GetNetworks, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "networkConfig.getProperties", - base::Bind(&NetworkConfigMessageHandler::GetProperties, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "networkConfig.getManagedProperties", - base::Bind(&NetworkConfigMessageHandler::GetManagedProperties, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "networkConfig.getShillProperties", - base::Bind(&NetworkConfigMessageHandler::GetShillProperties, - base::Unretained(this))); -} - -void NetworkConfigMessageHandler::GetNetworks( - const base::ListValue* arg_list) const { - int callback_id = 0; - const base::DictionaryValue* filter = NULL; - if (!arg_list->GetInteger(0, &callback_id) || - !arg_list->GetDictionary(1, &filter)) { - NOTREACHED(); - } - std::string type = ::onc::network_type::kAllTypes; - bool visible_only = false; - bool configured_only = false; - int limit = 1000; - filter->GetString("type", &type); - NetworkTypePattern pattern = onc::NetworkTypePatternFromOncType(type); - filter->GetBoolean("visible", &visible_only); - filter->GetBoolean("configured", &configured_only); - filter->GetInteger("limit", &limit); - - base::ListValue return_arg_list; - return_arg_list.AppendInteger(callback_id); - - scoped_ptr<base::ListValue> network_properties_list = - chromeos::network_util::TranslateNetworkListToONC( - pattern, configured_only, visible_only, limit, - true /* debugging_properties */); - - return_arg_list.Append(network_properties_list.release()); - - InvokeCallback(return_arg_list); -} - -void NetworkConfigMessageHandler::GetProperties( - const base::ListValue* arg_list) { - int callback_id = 0; - std::string guid; - if (!arg_list->GetInteger(0, &callback_id) || - !arg_list->GetString(1, &guid)) { - NOTREACHED(); - } - std::string service_path; - if (!GetServicePathFromGuid(guid, &service_path)) { - scoped_ptr<base::DictionaryValue> error_data; - ErrorCallback(callback_id, "Error.InvalidNetworkGuid", error_data.Pass()); - return; - } - NetworkHandler::Get()->managed_network_configuration_handler()->GetProperties( - service_path, - base::Bind(&NetworkConfigMessageHandler::GetPropertiesSuccess, - weak_ptr_factory_.GetWeakPtr(), callback_id), - base::Bind(&NetworkConfigMessageHandler::ErrorCallback, - weak_ptr_factory_.GetWeakPtr(), callback_id)); -} - -void NetworkConfigMessageHandler::GetManagedProperties( - const base::ListValue* arg_list) { - int callback_id = 0; - std::string guid; - if (!arg_list->GetInteger(0, &callback_id) || - !arg_list->GetString(1, &guid)) { - NOTREACHED(); - } - std::string service_path; - if (!GetServicePathFromGuid(guid, &service_path)) { - scoped_ptr<base::DictionaryValue> error_data; - ErrorCallback(callback_id, "Error.InvalidNetworkGuid", error_data.Pass()); - return; - } - NetworkHandler::Get()->managed_network_configuration_handler()-> - GetManagedProperties( - LoginState::Get()->primary_user_hash(), - service_path, - base::Bind(&NetworkConfigMessageHandler::GetPropertiesSuccess, - weak_ptr_factory_.GetWeakPtr(), callback_id), - base::Bind(&NetworkConfigMessageHandler::ErrorCallback, - weak_ptr_factory_.GetWeakPtr(), callback_id)); -} - -void NetworkConfigMessageHandler::GetPropertiesSuccess( - int callback_id, - const std::string& service_path, - const base::DictionaryValue& dictionary) const { - base::ListValue return_arg_list; - return_arg_list.AppendInteger(callback_id); - - base::DictionaryValue* network_properties = dictionary.DeepCopy(); - // Set the 'ServicePath' property for debugging. - network_properties->SetStringWithoutPathExpansion( - "ServicePath", service_path); - - return_arg_list.Append(network_properties); - InvokeCallback(return_arg_list); -} - -void NetworkConfigMessageHandler::GetShillProperties( - const base::ListValue* arg_list) { - int callback_id = 0; - std::string guid; - if (!arg_list->GetInteger(0, &callback_id) || - !arg_list->GetString(1, &guid)) { - NOTREACHED(); - } - std::string service_path; - if (!GetServicePathFromGuid(guid, &service_path)) { - scoped_ptr<base::DictionaryValue> error_data; - ErrorCallback(callback_id, "Error.InvalidNetworkGuid", error_data.Pass()); - return; - } - NetworkHandler::Get()->network_configuration_handler()->GetProperties( - service_path, - base::Bind(&NetworkConfigMessageHandler::GetShillPropertiesSuccess, - weak_ptr_factory_.GetWeakPtr(), callback_id), - base::Bind(&NetworkConfigMessageHandler::ErrorCallback, - weak_ptr_factory_.GetWeakPtr(), callback_id)); -} - -void NetworkConfigMessageHandler::GetShillPropertiesSuccess( - int callback_id, - const std::string& service_path, - const base::DictionaryValue& dictionary) const { - scoped_ptr<base::DictionaryValue> dictionary_copy(dictionary.DeepCopy()); - // Set the 'ServicePath' property for debugging. - dictionary_copy->SetStringWithoutPathExpansion("ServicePath", service_path); - - // Get the device properties for debugging. - std::string device; - dictionary_copy->GetStringWithoutPathExpansion( - shill::kDeviceProperty, &device); - const DeviceState* device_state = - NetworkHandler::Get()->network_state_handler()->GetDeviceState(device); - if (device_state) { - base::DictionaryValue* device_dictionary = - device_state->properties().DeepCopy(); - dictionary_copy->Set(shill::kDeviceProperty, device_dictionary); - - // Convert IPConfig dictionary to a ListValue. - base::ListValue* ip_configs = new base::ListValue; - for (base::DictionaryValue::Iterator iter(device_state->ip_configs()); - !iter.IsAtEnd(); iter.Advance()) { - ip_configs->Append(iter.value().DeepCopy()); - } - device_dictionary->SetWithoutPathExpansion( - shill::kIPConfigsProperty, ip_configs); - } - - base::ListValue return_arg_list; - return_arg_list.AppendInteger(callback_id); - return_arg_list.Append(dictionary_copy.release()); - InvokeCallback(return_arg_list); -} - -void NetworkConfigMessageHandler::InvokeCallback( - const base::ListValue& arg_list) const { - web_ui()->CallJavascriptFunction( - "networkConfig.chromeCallbackSuccess", arg_list); -} - -void NetworkConfigMessageHandler::ErrorCallback( - int callback_id, - const std::string& error_name, - scoped_ptr<base::DictionaryValue> error_data) const { - LOG(ERROR) << "NetworkConfigMessageHandler Error: " << error_name; - base::ListValue arg_list; - arg_list.AppendInteger(callback_id); - arg_list.AppendString(error_name); - web_ui()->CallJavascriptFunction( - "networkConfig.chromeCallbackError", arg_list); -} - -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/network_config_message_handler.h b/chrome/browser/ui/webui/chromeos/network_config_message_handler.h deleted file mode 100644 index 0da4765..0000000 --- a/chrome/browser/ui/webui/chromeos/network_config_message_handler.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_CONFIG_MESSAGE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_CONFIG_MESSAGE_HANDLER_H_ - -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/web_ui_message_handler.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace chromeos { - -// This class provides support for network configuration from WebUI components. -// It implements network_config.js which is a drop-in replacement for the -// networkingPrivate extention API. TODO(stevenjb): Implement the remaining -// networkingPrivate methods as needed. -class NetworkConfigMessageHandler : public content::WebUIMessageHandler { - public: - NetworkConfigMessageHandler(); - ~NetworkConfigMessageHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // WebUI::RegisterMessageCallback callbacks. These callbacks collect the - // requested information and call the associated JS method. The first - // argument in |arg_list| is always the callback id which is passed back - // to the callback method. - void GetNetworks(const base::ListValue* arg_list) const; - void GetProperties(const base::ListValue* arg_list); - void GetManagedProperties(const base::ListValue* arg_list); - void GetPropertiesSuccess(int callback_id, - const std::string& service_path, - const base::DictionaryValue& dictionary) const; - - // Get Shill Properties for debugging purposes only. - void GetShillProperties(const base::ListValue* arg_list); - void GetShillPropertiesSuccess(int callback_id, - const std::string& service_path, - const base::DictionaryValue& dictionary) const; - - void InvokeCallback(const base::ListValue& arg_list) const; - void ErrorCallback(int callback_id, - const std::string& error_name, - scoped_ptr<base::DictionaryValue> error_data) const; - - base::WeakPtrFactory<NetworkConfigMessageHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(NetworkConfigMessageHandler); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_CONFIG_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc index 7c1b482..6cfb6a7 100644 --- a/chrome/browser/ui/webui/chromeos/network_ui.cc +++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -6,21 +6,141 @@ #include <string> +#include "base/memory/weak_ptr.h" #include "base/values.h" -#include "chrome/browser/ui/webui/chromeos/network_config_message_handler.h" +#include "chrome/browser/extensions/tab_helper.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/device_event_log.h" +#include "chromeos/network/device_state.h" +#include "chromeos/network/network_configuration_handler.h" +#include "chromeos/network/network_state.h" +#include "chromeos/network/network_state_handler.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "content/public/browser/web_ui_message_handler.h" #include "grit/browser_resources.h" +#include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { +namespace { + +bool GetServicePathFromGuid(const std::string& guid, + std::string* service_path) { + const NetworkState* network = + NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid( + guid); + if (!network) + return false; + *service_path = network->path(); + return true; +} + +void SetDeviceProperties(base::DictionaryValue* dictionary) { + std::string device; + dictionary->GetStringWithoutPathExpansion(shill::kDeviceProperty, &device); + const DeviceState* device_state = + NetworkHandler::Get()->network_state_handler()->GetDeviceState(device); + if (!device_state) + return; + + scoped_ptr<base::DictionaryValue> device_dictionary( + device_state->properties().DeepCopy()); + + if (!device_state->ip_configs().empty()) { + // Convert IPConfig dictionary to a ListValue. + scoped_ptr<base::ListValue> ip_configs(new base::ListValue); + for (base::DictionaryValue::Iterator iter(device_state->ip_configs()); + !iter.IsAtEnd(); iter.Advance()) { + ip_configs->Append(iter.value().DeepCopy()); + } + device_dictionary->SetWithoutPathExpansion(shill::kIPConfigsProperty, + ip_configs.release()); + } + if (!device_dictionary->empty()) + dictionary->Set(shill::kDeviceProperty, device_dictionary.release()); +} + +class NetworkConfigMessageHandler : public content::WebUIMessageHandler { + public: + NetworkConfigMessageHandler() : weak_ptr_factory_(this) {} + ~NetworkConfigMessageHandler() override {} + + // WebUIMessageHandler implementation. + void RegisterMessages() override { + web_ui()->RegisterMessageCallback( + "getShillProperties", + base::Bind(&NetworkConfigMessageHandler::GetShillProperties, + base::Unretained(this))); + } + + private: + void GetShillProperties(const base::ListValue* arg_list) { + std::string guid; + if (!arg_list->GetString(0, &guid)) { + NOTREACHED(); + ErrorCallback(guid, "Missing GUID in arg list", nullptr); + return; + } + std::string service_path; + if (!GetServicePathFromGuid(guid, &service_path)) { + ErrorCallback(guid, "Error.InvalidNetworkGuid", nullptr); + return; + } + NetworkHandler::Get()->network_configuration_handler()->GetProperties( + service_path, + base::Bind(&NetworkConfigMessageHandler::GetShillPropertiesSuccess, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&NetworkConfigMessageHandler::ErrorCallback, + weak_ptr_factory_.GetWeakPtr(), guid)); + } + + void GetShillPropertiesSuccess( + const std::string& service_path, + const base::DictionaryValue& dictionary) const { + scoped_ptr<base::DictionaryValue> dictionary_copy(dictionary.DeepCopy()); + + // Set the 'ServicePath' property for debugging. + dictionary_copy->SetStringWithoutPathExpansion("ServicePath", service_path); + // Set the device properties for debugging. + SetDeviceProperties(dictionary_copy.get()); + + base::ListValue return_arg_list; + return_arg_list.Append(dictionary_copy.release()); + web_ui()->CallJavascriptFunction("NetworkUI.getShillPropertiesResult", + return_arg_list); + } + + void ErrorCallback( + const std::string& guid, + const std::string& error_name, + scoped_ptr<base::DictionaryValue> /* error_data */) const { + NET_LOG(ERROR) << "Shill Error: " << error_name << " guid=" << guid; + base::ListValue return_arg_list; + scoped_ptr<base::DictionaryValue> dictionary; + dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid); + dictionary->SetStringWithoutPathExpansion("ShillError", error_name); + return_arg_list.Append(dictionary.release()); + web_ui()->CallJavascriptFunction("NetworkUI.getShillPropertiesResult", + return_arg_list); + } + + base::WeakPtrFactory<NetworkConfigMessageHandler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(NetworkConfigMessageHandler); +}; + +} // namespace + NetworkUI::NetworkUI(content::WebUI* web_ui) : content::WebUIController(web_ui) { web_ui->AddMessageHandler(new NetworkConfigMessageHandler()); + // Enable extension API calls in the WebUI. + extensions::TabHelper::CreateForWebContents(web_ui->GetWebContents()); + content::WebUIDataSource* html = content::WebUIDataSource::Create(chrome::kChromeUINetworkHost); @@ -43,7 +163,6 @@ IDS_NETWORK_UI_FAVORITE_NETWORKS); html->SetJsonPath("strings.js"); - html->AddResourcePath("network_config.js", IDR_NETWORK_CONFIG_JS); html->AddResourcePath("network_ui.css", IDR_NETWORK_UI_CSS); html->AddResourcePath("network_ui.js", IDR_NETWORK_UI_JS); html->SetDefaultResource(IDR_NETWORK_UI_HTML);
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js index 3ce65f32..449fe4bf 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
@@ -7,6 +7,10 @@ GEN('#include "chrome/browser/ui/webui/extensions/' + 'extension_settings_browsertest.h"'); +// chrome/test/data/extensions/good.crx's extension ID. good.crx is loaded by +// ExtensionSettingsUIBrowserTest::InstallGoodExtension() in some of the tests. +var GOOD_CRX_ID = 'ldnnhddmnhbkjipkidpdiheffobcpfmf'; + /** * Test C++ fixture for settings WebUI testing. * @constructor @@ -115,9 +119,9 @@ * @constructor * @extends {ExtensionSettingsWebUITest} */ -function ExtensionSettingsWebUITestWithExtensionInstalled() {} +function InstalledExtensionSettingsWebUITest() {} -ExtensionSettingsWebUITestWithExtensionInstalled.prototype = { +InstalledExtensionSettingsWebUITest.prototype = { __proto__: ExtensionSettingsWebUITest.prototype, /** @override */ @@ -126,33 +130,69 @@ /** @override */ testGenPreamble: function() { GEN(' InstallGoodExtension();'); - } + }, }; -TEST_F('ExtensionSettingsWebUITestWithExtensionInstalled', - 'baseAccessibilityIsOk', function() { +/** @this {InstalledExtensionSettingsWebUITest} */ +function runAudit() { assertEquals(this.browsePreload, document.location.href); this.runAccessibilityAudit(); +} + +TEST_F('InstalledExtensionSettingsWebUITest', 'baseAccessibilityOk', runAudit); + +/** + * @constructor + * @extends {InstalledExtensionSettingsWebUITest} + */ +function AsyncInstalledExtensionSettingsWebUITest() {} + +AsyncInstalledExtensionSettingsWebUITest.prototype = { + __proto__: InstalledExtensionSettingsWebUITest.prototype, + + /** @override */ + isAsync: true, +}; + +TEST_F('AsyncInstalledExtensionSettingsWebUITest', 'showOptions', function() { + var optionsOverlay = extensions.ExtensionOptionsOverlay.getInstance(); + optionsOverlay.setExtensionAndShowOverlay(GOOD_CRX_ID, 'GOOD!', '', testDone); + + // Preferred size changes don't happen in browser tests. Just fake it. + var size = {width: 500, height: 500}; + document.querySelector('extensionoptions').onpreferredsizechanged(size); }); /** * @constructor - * @extends {ExtensionSettingsWebUITestWithExtensionInstalled} + * @extends {InstalledExtensionSettingsWebUITest} */ function ManagedExtensionSettingsWebUITest() {} ManagedExtensionSettingsWebUITest.prototype = { - __proto__: ExtensionSettingsWebUITestWithExtensionInstalled.prototype, + __proto__: InstalledExtensionSettingsWebUITest.prototype, /** @override */ testGenPreamble: function() { GEN(' AddManagedPolicyProvider();'); - ExtensionSettingsWebUITestWithExtensionInstalled.prototype.testGenPreamble. - call(this); + InstalledExtensionSettingsWebUITest.prototype.testGenPreamble.call(this); }, }; -TEST_F('ManagedExtensionSettingsWebUITest', 'testAccessibility', function() { - assertEquals(this.browsePreload, document.location.href); - this.runAccessibilityAudit(); -}); +TEST_F('ManagedExtensionSettingsWebUITest', 'testAccessibility', runAudit); + +/** + * @constructor + * @extends {InstalledExtensionSettingsWebUITest} + */ +function ExtensionOptionsDialogWebUITest() {} + +ExtensionOptionsDialogWebUITest.prototype = { + __proto__: InstalledExtensionSettingsWebUITest.prototype, + + /** @override */ + browsePreload: ExtensionSettingsWebUITest.prototype.browsePreload + + '?options=' + GOOD_CRX_ID, +}; + +TEST_F('ExtensionOptionsDialogWebUITest', 'testAccessibility', runAudit);
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc index 210867d..e048df42 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc +++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -335,16 +335,17 @@ } extension_data->Set("dependentExtensions", dependents_list); - // Extensions only want all URL access if: + // We show the "all urls" checkbox if: // - The feature is enabled for the given extension. // - The extension has access to enough urls that we can't just let it run // on those specified in the permissions. - bool wants_all_urls = - util::ScriptsMayRequireActionForExtension(extension) && - (extension->permissions_data()->HasWithheldImpliedAllHosts() || - util::AllowedScriptingOnAllUrls( - extension->id(), extension_service_->GetBrowserContext())); - extension_data->SetBoolean("wantsAllUrls", wants_all_urls); + bool show_all_urls = + (FeatureSwitch::scripts_require_action()->IsEnabled() && + util::ScriptsMayRequireActionForExtension( + extension, + extension->permissions_data()->active_permissions().get())) || + extension->permissions_data()->HasWithheldImpliedAllHosts(); + extension_data->SetBoolean("showAllUrls", show_all_urls); extension_data->SetBoolean( "allowAllUrls", util::AllowedScriptingOnAllUrls(
diff --git a/chrome/browser/ui/webui/md_settings_ui.cc b/chrome/browser/ui/webui/md_settings_ui.cc new file mode 100644 index 0000000..fe65e48 --- /dev/null +++ b/chrome/browser/ui/webui/md_settings_ui.cc
@@ -0,0 +1,29 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/md_settings_ui.h" + +#include <string> + +#include "base/values.h" +#include "chrome/common/url_constants.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "grit/browser_resources.h" + +MdSettingsUI::MdSettingsUI(content::WebUI* web_ui) + : content::WebUIController(web_ui) { + content::WebUIDataSource* html_source = + content::WebUIDataSource::Create(chrome::kChromeUIMdSettingsHost); + + html_source->SetDefaultResource(IDR_MD_SETTINGS_UI_HTML); + + content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), + html_source); +} + +MdSettingsUI::~MdSettingsUI() { +}
diff --git a/chrome/browser/ui/webui/md_settings_ui.h b/chrome/browser/ui/webui/md_settings_ui.h new file mode 100644 index 0000000..3630a3a --- /dev/null +++ b/chrome/browser/ui/webui/md_settings_ui.h
@@ -0,0 +1,20 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_ + +#include "content/public/browser/web_ui_controller.h" + +// The WebUI handler for chrome://md-settings. +class MdSettingsUI : public content::WebUIController { + public: + explicit MdSettingsUI(content::WebUI* web_ui); + ~MdSettingsUI() override; + + private: + DISALLOW_COPY_AND_ASSIGN(MdSettingsUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.h b/chrome/browser/ui/webui/ntp/most_visited_handler.h index 2ccc25b..7e04d42 100644 --- a/chrome/browser/ui/webui/ntp/most_visited_handler.h +++ b/chrome/browser/ui/webui/ntp/most_visited_handler.h
@@ -15,7 +15,6 @@ #include "content/public/browser/web_ui_message_handler.h" class GURL; -class PageUsageData; namespace base { class ListValue;
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index 244c8e4..e9e624d 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -501,12 +501,6 @@ bool bookmark_apps_enabled = extensions::util::IsNewBookmarkAppsEnabled(); load_time_data.SetBoolean("enableNewBookmarkApps", bookmark_apps_enabled); - // Use a different string for launching as a regular tab when bookmark apps - // are enabled. - if (bookmark_apps_enabled) { - load_time_data.SetString("applaunchtypetab", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB)); - } #if defined(OS_CHROMEOS) load_time_data.SetString("expandMenu",
diff --git a/chrome/browser/ui/webui/ntp/suggestions_page_handler.h b/chrome/browser/ui/webui/ntp/suggestions_page_handler.h index 8f23fd3b..de7712fc 100644 --- a/chrome/browser/ui/webui/ntp/suggestions_page_handler.h +++ b/chrome/browser/ui/webui/ntp/suggestions_page_handler.h
@@ -14,7 +14,6 @@ #include "content/public/browser/web_ui_message_handler.h" class GURL; -class PageUsageData; namespace base { class ListValue;
diff --git a/chrome/browser/ui/webui/options/autofill_options_interactive_uitest.cc b/chrome/browser/ui/webui/options/autofill_options_interactive_uitest.cc new file mode 100644 index 0000000..4ff1c44 --- /dev/null +++ b/chrome/browser/ui/webui/options/autofill_options_interactive_uitest.cc
@@ -0,0 +1,380 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/strings/stringprintf.h" +#include "chrome/browser/autofill/autofill_uitest_util.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/url_constants.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/interactive_test_utils.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/personal_data_manager.h" +#include "content/public/test/browser_test_utils.h" + +namespace { + +// This class tests the Autofill options settings. +// This test is part of the interactive_ui_tests instead of browser_tests +// because it is necessary to emulate pushing the tab key. +class AutofillOptionsWebUITest : public InProcessBrowserTest { + public: + AutofillOptionsWebUITest() {} + + // Navigate to the autofillEditAddress page. + void SetUpOnMainThread() override { + const GURL url = chrome::GetSettingsUrl("autofillEditAddress"); + ui_test_utils::NavigateToURL(browser(), url); + } + + protected: + const std::string kEditAddressOverlaySelector = + "#autofill-edit-address-overlay"; + + content::RenderFrameHost* GetActiveFrame() { + return GetActiveWebContents()->GetFocusedFrame(); + } + + content::RenderViewHost* GetRenderViewHost() { + return GetActiveWebContents()->GetRenderViewHost(); + } + + content::WebContents* GetActiveWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + void CreateTestProfile() { + autofill::AddTestProfile(browser(), autofill::test::GetFullProfile()); + } + + // Returns true if element contains document.activeElement. + bool ContainsActiveElement(const std::string& element_selector) { + const std::string script = base::StringPrintf( + "domAutomationController.send(" + "document.querySelector('%s').contains(document.activeElement));", + element_selector.c_str()); + bool result; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + GetActiveFrame(), + script, + &result)); + return result; + } + + // Returns the number of items in the list. + int GetListSize(const std::string& list_selector) { + const std::string script = base::StringPrintf( + "domAutomationController.send(" + "document.querySelector('%s').items.length);", + list_selector.c_str()); + int length = -1; + EXPECT_TRUE(content::ExecuteScriptAndExtractInt( + GetActiveFrame(), + script, + &length)); + return length; + } + + // Focus the first input field of the first list item. + void FocusFirstListItemInput(const std::string& list_selector) { + const std::string script = base::StringPrintf( + "document.querySelector('%s input').focus();", + list_selector.c_str()); + EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script)); + } + + // Returns the text of the first item in the list. + std::string GetFirstListItemText(const std::string& list_selector) { + // EXPECT_TRUE will fail if there is no first item or first item does not + // have 'input'. + const std::string script = base::StringPrintf( + "domAutomationController.send(" + "document.querySelector('%s input').value);", + list_selector.c_str()); + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + GetActiveFrame(), + script, + &result)); + return result; + } + + // Returns true if the first item in the list has 'selected' attribute. + bool GetFirstListItemSelected(const std::string& list_selector) { + // EXPECT_TRUE will fail if there is no first item. + const std::string script = base::StringPrintf( + "domAutomationController.send(" + "document.querySelector('%s').items[0].hasAttribute('selected'));", + list_selector.c_str()); + bool result = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + GetActiveFrame(), + script, + &result)); + return result; + } + + // Returns true if a row delete button ('X' button) is focused. + bool GetDeleteButtonFocused() { + const std::string script = + "domAutomationController.send(" + "document.activeElement.classList.contains('row-delete-button'));"; + bool result = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + GetActiveFrame(), + script, + &result)); + return result; + } + + // Insert text into currently focused element. + void InsertText(const std::string& text) { + ASSERT_EQ(std::string::npos, text.find("'")); + const std::string script = base::StringPrintf( + "document.execCommand('insertText', false, '%s');", + text.c_str()); + EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script)); + } + + // Press and release tab key in the browser. This will wait for the element on + // the page to change. + bool PressTab(bool shift) { + return ui_test_utils::SendKeyPressAndWait( + browser(), + ui::VKEY_TAB, + false, + shift, + false, + false, + content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::Source<content::RenderViewHost>(GetRenderViewHost())); + } + + void InitializeDomMessageQueue() { + dom_message_queue_.reset(new content::DOMMessageQueue); + } + + // Wait for a message from the DOM automation controller. + void WaitForDomMessage(const std::string& message) { + const std::string expected = "\"" + message + "\""; + std::string received; + do { + ASSERT_TRUE(dom_message_queue_->WaitForMessage(&received)); + } while (received != expected); + } + + void ListenForFirstItemSelected(const std::string& list_selector) { + const std::string script = base::StringPrintf( + "document.querySelector('%s').items[0].addEventListener(" + "'selectedChange', function(e) {" + "if (e.newValue) {" + "domAutomationController.setAutomationId(0);" + "domAutomationController.send('first item selected');" + "}" + "});", + list_selector.c_str()); + + EXPECT_TRUE(content::ExecuteScript( + GetActiveFrame(), + script)); + } + + void ListenForCommitEdit(const std::string& list_selector) { + const std::string script = base::StringPrintf( + "document.querySelector('%s').addEventListener(" + "'commitedit', function() {" + "domAutomationController.setAutomationId(0);" + "domAutomationController.send('done commitedit');" + "});", + list_selector.c_str()); + + EXPECT_TRUE(content::ExecuteScript( + GetActiveFrame(), + script)); + } + + // Add an event listener to send a DOM automation controller message from + // JavaScript each time validation completes for the list. + void ListenForDoneValidating(const std::string& list_selector) { + // doneValidating will execute the 'then' function immediately if no + // validations are pending, so wait for 'commitedit' event before calling + // doneValidating. + const std::string script = base::StringPrintf( + "document.querySelector('%s').addEventListener('commitedit'," + "function() {" + "document.querySelector('%s').doneValidating().then(function() {" + "domAutomationController.setAutomationId(0);" + "domAutomationController.send('done validating');" + "});" + "});", + list_selector.c_str(), + list_selector.c_str()); + + EXPECT_TRUE(content::ExecuteScript( + GetActiveFrame(), + script)); + } + + // Verifies that everything is the way it should be after list item is + // added or edited. + void VerifyEditAddressListPostConditions(const std::string& list_selector, + const std::string& input_text, + bool list_requires_validation) { + // Verify that neither the list nor any of its children still have focus. + EXPECT_FALSE(ContainsActiveElement(list_selector)); + + // Verify that focus moved to a different element of the overlay. + EXPECT_TRUE(ContainsActiveElement(kEditAddressOverlaySelector)); + + // Verify that list has exactly two items. They will be the item that was + // just added/modified + the placeholder. + EXPECT_EQ(2, GetListSize(list_selector)); + + // Verify that the first list item has the string that was inserted. + EXPECT_EQ(input_text, GetFirstListItemText(list_selector)); + + // TODO(bondd): phone list doesn't select first item after validation. + // It becomes selected later when the list is given focus. + if (!list_requires_validation) { + // Verify that the first list item is the selected item in the list. + EXPECT_TRUE(GetFirstListItemSelected(list_selector)); + } + } + + // Make sure that when text is entered in the placeholder of an empty list and + // the tab key is pressed: + // + Focus leaves the list and goes to a different element on the page. + // + The text stays added and a new placeholder is created. + // + The list item with the newly added text is the selected list item (not + // the placeholder). + // + // Added to prevent http://crbug.com/440760 from regressing again. + void TestEditAddressListTabKeyAddItem(const std::string& list_selector, + const std::string& input_text, + bool list_requires_validation) { + // Focus the input field and insert test string. + FocusFirstListItemInput(list_selector); + WaitForDomMessage("first item selected"); + + InsertText(input_text); + + // Press tab key to move to next element after the list. + PressTab(false); + + if (list_requires_validation) + WaitForDomMessage("done validating"); + else + WaitForDomMessage("done commitedit"); + + // Make sure everything ended up the way it should be. + VerifyEditAddressListPostConditions(list_selector, input_text, + list_requires_validation); + } + + // Depends on state set up by TestEditAddressListTabKeyAddItem. Should be + // called immediately after that method. + // + // Make sure that when a list item's text is edited and the tab key is + // pressed twice: + // + After the first tab press the item's delete button is focused. + // + After the second tab press focus leaves the list and goes to a + // different element on the page. + // + The edited text persists. + // + The edited list item is the selected list item. + // + // Added to prevent http://crbug.com/443491 from regressing again. + void TestEditAddressListTabKeyEditItem(const std::string& list_selector, + const std::string& input_text, + bool list_requires_validation, + bool skip_ok_button) { + if (skip_ok_button) + PressTab(true); + + // Press shift+tab to move back to the first list item's delete button. + PressTab(true); + EXPECT_TRUE(GetDeleteButtonFocused()); + + // Press shift+tab to move back to the first list item's input field. + PressTab(true); + // Verify that the first item in the list is focused. + EXPECT_TRUE(ContainsActiveElement(list_selector + " input")); + + // Insert modified text in the first list item. + std::string second_input = "second" + input_text; + InsertText(second_input); + + // Press tab key to focus the list item's delete button. + PressTab(false); + EXPECT_TRUE(GetDeleteButtonFocused()); + + // Press tab key again to move to next element after the list. + PressTab(false); + + if (list_requires_validation) + WaitForDomMessage("done validating"); + else + WaitForDomMessage("done commitedit"); + + // Make sure everything ended up the way it should be. + VerifyEditAddressListPostConditions(list_selector, second_input, + list_requires_validation); + } + + void TestEditAddressListTabKey(const std::string& field_name, + const std::string& input_text, + bool list_requires_validation, + bool skip_ok_button) { + const std::string list_selector = kEditAddressOverlaySelector + " [field=" + + field_name + "]"; + + InitializeDomMessageQueue(); + ListenForFirstItemSelected(list_selector); + if (list_requires_validation) + ListenForDoneValidating(list_selector); + else + ListenForCommitEdit(list_selector); + + TestEditAddressListTabKeyAddItem(list_selector, input_text, + list_requires_validation); + TestEditAddressListTabKeyEditItem(list_selector, input_text, + list_requires_validation, skip_ok_button); + } + + private: + scoped_ptr<content::DOMMessageQueue> dom_message_queue_; + + DISALLOW_COPY_AND_ASSIGN(AutofillOptionsWebUITest); +}; + +} // namespace + +// Test the 'fullName' InlineEditableItemList in autofillEditAddress overlay. +IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest, + TestEditAddressNameTabKey) { + TestEditAddressListTabKey("fullName", "Test Name", false, false); +} + +// Test the 'phone' InlineEditableItemList in autofillEditAddress overlay. +IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest, + TestEditAddressPhoneTabKey) { + CreateTestProfile(); + TestEditAddressListTabKey("phone", "123-456-7890", true, false); +} + +// Test the 'email' InlineEditableItemList in autofillEditAddress overlay. +IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest, + TestEditAddressEmailTabKey) { +#if defined(OS_WIN) || defined(OS_CHROMEOS) + // Button strip order is 'Cancel' and then 'OK' on Linux and Mac. 'OK' and + // then 'Cancel' on Windows and CrOS. + bool skip_ok_button = true; +#else + bool skip_ok_button = false; +#endif + + TestEditAddressListTabKey("email", "test@example.com", false, skip_ok_button); +}
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index d00be98..0e77438 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -2035,14 +2035,11 @@ } void BrowserOptionsHandler::SetupEasyUnlock() { - // TODO(xiyuan): Update when pairing data is really availble. - const base::ListValue* devices = - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->GetRemoteDevices(); - bool has_pairing = devices && !devices->empty(); - base::FundamentalValue has_pairing_value(has_pairing); + base::FundamentalValue is_enabled( + EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->IsEnabled()); web_ui()->CallJavascriptFunction( "BrowserOptions.updateEasyUnlock", - has_pairing_value); + is_enabled); } void BrowserOptionsHandler::SetupExtensionControlledIndicators() {
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc index 7603c06..33c6c55 100644 --- a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc +++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/basictypes.h" +#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/prefs/pref_service.h" #include "chrome/browser/chromeos/login/login_manager_test.h"
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc index b5d6653..11190a7a 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -6,9 +6,11 @@ #include "base/bind.h" #include "base/prefs/pref_service.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/browser_navigator.h" @@ -60,11 +62,12 @@ signin::GetLandingURL(signin::kSignInPromoQueryKeySource, static_cast<int>(source)).spec()); + Profile* profile = Profile::FromWebUI(web_ui()); std::string default_email; if (source != signin_metrics::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT && source != signin_metrics::SOURCE_REAUTH) { - default_email = Profile::FromWebUI(web_ui())->GetPrefs()->GetString( - prefs::kGoogleServicesLastUsername); + default_email = + profile->GetPrefs()->GetString(prefs::kGoogleServicesLastUsername); } else { if (!net::GetValueForKeyInQuery(current_url, "email", &default_email)) default_email.clear(); @@ -72,10 +75,16 @@ if (!default_email.empty()) params.SetString("email", default_email); + std::string frame_url_id_str; + net::GetValueForKeyInQuery(current_url, "frameUrlId", &frame_url_id_str); + int frame_url_id; std::string frame_url; - net::GetValueForKeyInQuery(current_url, "frameUrl", &frame_url); - if (!frame_url.empty()) + if (!frame_url_id_str.empty() && + base::StringToInt(frame_url_id_str, &frame_url_id) && + extensions::GaiaAuthExtensionLoader::Get(profile) + ->GetData(frame_url_id, &frame_url)) { params.SetString("frameUrl", frame_url); + } std::string is_constrained; net::GetValueForKeyInQuery( @@ -101,13 +110,17 @@ void InlineLoginHandler::HandleSwitchToFullTabMessage( const base::ListValue* args) { - base::string16 url_str; + std::string url_str; CHECK(args->GetString(0, &url_str)); + Profile* profile = Profile::FromWebUI(web_ui()); + const int frame_url_id = + extensions::GaiaAuthExtensionLoader::Get(profile)->AddData(url_str); + content::WebContents* web_contents = web_ui()->GetWebContents(); GURL main_frame_url(web_contents->GetURL()); main_frame_url = net::AppendOrReplaceQueryParameter( - main_frame_url, "frameUrl", base::UTF16ToASCII(url_str)); + main_frame_url, "frameUrlId", base::IntToString(frame_url_id)); // Adds extra parameters to the signin URL so that Chrome will close the tab // and show the account management view of the avatar menu upon completion. @@ -117,7 +130,7 @@ main_frame_url, signin::kSignInPromoQueryKeyShowAccountManagement, "1"); chrome::NavigateParams params( - Profile::FromWebUI(web_ui()), + profile, net::AppendOrReplaceQueryParameter( main_frame_url, signin::kSignInPromoQueryKeyConstrained, "0"), ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc index 0f8d24e..5ec0bbc 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
@@ -277,16 +277,9 @@ // Flaky on CrOS, http://crbug.com/364759. // Also flaky on Mac, http://crbug.com/442674. -#if defined(OS_CHROMEOS) || defined(OS_MACOSX) -#define MAYBE_NavigationToOtherChromeURLDisallowed \ - DISABLED_NavigationToOtherChromeURLDisallowed -#else -#define MAYBE_NavigationToOtherChromeURLDisallowed \ - NavigationToOtherChromeURLDisallowed -#endif - +// Also flaky on Linux which is just too flaky IN_PROC_BROWSER_TEST_F(InlineLoginUISafeIframeBrowserTest, - MAYBE_NavigationToOtherChromeURLDisallowed) { + DISABLED_NavigationToOtherChromeURLDisallowed) { ui_test_utils::NavigateToURL( browser(), signin::GetPromoURL(signin_metrics::SOURCE_START_PAGE, false)); WaitUntilUIReady(browser());
diff --git a/chrome/browser/undo/bookmark_undo_service.cc b/chrome/browser/undo/bookmark_undo_service.cc index c195729..c779d41 100644 --- a/chrome/browser/undo/bookmark_undo_service.cc +++ b/chrome/browser/undo/bookmark_undo_service.cc
@@ -16,6 +16,7 @@ #include "components/bookmarks/browser/scoped_group_bookmark_actions.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using bookmarks::BookmarkNodeData; namespace {
diff --git a/chrome/browser/undo/bookmark_undo_service.h b/chrome/browser/undo/bookmark_undo_service.h index c44da964..5e5f196 100644 --- a/chrome/browser/undo/bookmark_undo_service.h +++ b/chrome/browser/undo/bookmark_undo_service.h
@@ -38,22 +38,22 @@ bool ids_reassigned) override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void OnWillRemoveBookmarks(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void OnWillRemoveAllUserBookmarks(bookmarks::BookmarkModel* model) override; void OnWillChangeBookmarkNode(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void OnWillReorderBookmarkNode(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void GroupedBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override; void GroupedBookmarkChangesEnded(bookmarks::BookmarkModel* model) override;
diff --git a/chrome/browser/undo/bookmark_undo_service_test.cc b/chrome/browser/undo/bookmark_undo_service_test.cc index c7ee5fa..cf1593c 100644 --- a/chrome/browser/undo/bookmark_undo_service_test.cc +++ b/chrome/browser/undo/bookmark_undo_service_test.cc
@@ -15,6 +15,7 @@ using base::ASCIIToUTF16; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate index 912fbca6..2624378c 100644 --- a/chrome/browser_tests.isolate +++ b/chrome/browser_tests.isolate
@@ -208,6 +208,13 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/browser_tests.dSYM/', + ], + }, + }], ['OS=="win" and libpeer_target_type=="loadable_module"', { 'variables': { 'files': [
diff --git a/chrome/child/pdf_child_init.cc b/chrome/child/pdf_child_init.cc index 338403cc..45b403a2 100644 --- a/chrome/child/pdf_child_init.cc +++ b/chrome/child/pdf_child_init.cc
@@ -31,13 +31,19 @@ return CreateCompatibleDC(NULL); } +typedef DWORD (WINAPI* GetFontDataPtr) (HDC hdc, + DWORD table, + DWORD offset, + LPVOID buffer, + DWORD length); +GetFontDataPtr g_original_get_font_data = NULL; static base::win::IATPatchFunction g_iat_patch_get_font_data; DWORD WINAPI GetFontDataPatch(HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { - int rv = GetFontData(hdc, table, offset, buffer, length); + int rv = g_original_get_font_data(hdc, table, offset, buffer, length); if (rv == GDI_ERROR && hdc) { HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); @@ -45,7 +51,7 @@ if (GetObject(font, sizeof(LOGFONT), &logfont)) { std::vector<char> font_data; content::ChildThread::Get()->PreCacheFont(logfont); - rv = GetFontData(hdc, table, offset, buffer, length); + rv = g_original_get_font_data(hdc, table, offset, buffer, length); content::ChildThread::Get()->ReleaseCachedFonts(); } } @@ -72,6 +78,8 @@ CreateDCAPatch); g_iat_patch_get_font_data.Patch(current_module_name, "gdi32.dll", "GetFontData", GetFontDataPatch); + g_original_get_font_data = reinterpret_cast<GetFontDataPtr>( + g_iat_patch_get_font_data.original_function()); #endif // OS_WIN }
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 639f2c83..7b603fb 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp
@@ -616,6 +616,7 @@ '../base/base.gyp:base', '../components/components.gyp:bookmarks_java', '../components/components.gyp:dom_distiller_core_java', + '../components/components.gyp:enhanced_bookmarks_launch_location_srcjar', '../components/components.gyp:gcm_driver_java', '../components/components.gyp:invalidation_java', '../components/components.gyp:navigation_interception_java',
diff --git a/chrome/chrome.isolate b/chrome/chrome.isolate index 64ae230..061cc23 100644 --- a/chrome/chrome.isolate +++ b/chrome/chrome.isolate
@@ -77,6 +77,17 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/<(mac_product_name) Framework.framework.dSYM/', + '<(PRODUCT_DIR)/<(mac_product_name) Helper.app.dSYM/', + '<(PRODUCT_DIR)/<(mac_product_name).app.dSYM/', + '<(PRODUCT_DIR)/exif.so.dSYM/', + '<(PRODUCT_DIR)/ffmpegsumo.so.dSYM/', + ], + }, + }], ['OS=="win"', { 'variables': { 'files': [
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index d111cba..e080a31 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -84,8 +84,8 @@ 'browser/android/dom_distiller/feedback_reporter_android.h', 'browser/android/download/chrome_download_delegate.cc', 'browser/android/download/chrome_download_delegate.h', - 'browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc', - 'browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h', + 'browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.cc', + 'browser/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h', 'browser/android/favicon_helper.cc', 'browser/android/favicon_helper.h', 'browser/android/feature_utilities.cc', @@ -1193,6 +1193,12 @@ 'browser/bookmarks/chrome_bookmark_client_factory.h', 'browser/bookmarks/enhanced_bookmarks_features.cc', 'browser/bookmarks/enhanced_bookmarks_features.h', + 'browser/enhanced_bookmarks/android/bookmark_image_service_android.cc', + 'browser/enhanced_bookmarks/android/bookmark_image_service_android.h', + 'browser/enhanced_bookmarks/android/bookmark_image_service_factory.cc', + 'browser/enhanced_bookmarks/android/bookmark_image_service_factory.h', + 'browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.cc', + 'browser/enhanced_bookmarks/android/enhanced_bookmark_tab_helper.h', 'browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.cc', 'browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h', 'browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service_factory.cc', @@ -1311,6 +1317,8 @@ 'browser/search/hotword_service_factory.h', 'browser/signin/easy_unlock_auth_attempt.cc', 'browser/signin/easy_unlock_auth_attempt.h', + 'browser/signin/easy_unlock_metrics.cc', + 'browser/signin/easy_unlock_metrics.h', 'browser/signin/easy_unlock_screenlock_state_handler.cc', 'browser/signin/easy_unlock_screenlock_state_handler.h', 'browser/signin/easy_unlock_service.cc', @@ -1611,7 +1619,7 @@ 'android/java/src/org/chromium/chrome/browser/VoiceSearchTabHelper.java', 'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java', 'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopupLegacy.java', - 'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java', + 'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java', 'android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBarDelegate.java', 'android/java/src/org/chromium/chrome/browser/infobar/DataReductionProxyInfoBarDelegate.java', 'android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBarDelegate.java', @@ -3004,6 +3012,7 @@ '../third_party/npapi/npapi.gyp:npapi', '../third_party/smhasher/smhasher.gyp:cityhash', '../third_party/webrtc/modules/modules.gyp:desktop_capture', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/gl/gl.gyp:gl', '../ui/surface/surface.gyp:surface', '../ui/web_dialogs/web_dialogs.gyp:web_dialogs',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index a57b9cf..75875a6 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -429,8 +429,6 @@ 'browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h', 'browser/chromeos/login/easy_unlock/easy_unlock_refresh_keys_operation.cc', 'browser/chromeos/login/easy_unlock/easy_unlock_refresh_keys_operation.h', - 'browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc', - 'browser/chromeos/login/easy_unlock/easy_unlock_metrics.h', 'browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc', 'browser/chromeos/login/easy_unlock/easy_unlock_reauth.h', 'browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc', @@ -477,8 +475,6 @@ 'browser/chromeos/login/lock/screen_locker_delegate.h', 'browser/chromeos/login/lock/webui_screen_locker.cc', 'browser/chromeos/login/lock/webui_screen_locker.h', - 'browser/chromeos/login/login_utils.cc', - 'browser/chromeos/login/login_utils.h', 'browser/chromeos/login/login_wizard.h', 'browser/chromeos/login/profile_auth_data.cc', 'browser/chromeos/login/profile_auth_data.h', @@ -1090,6 +1086,7 @@ '../breakpad/breakpad.gyp:breakpad_client', '../build/linux/system.gyp:dbus', '../chromeos/chromeos.gyp:chromeos', + '../chromeos/chromeos.gyp:chromeos_test_support', '../chromeos/chromeos.gyp:cryptohome_proto', # browser_chromeos #includes signed_secret.pb.h directly. '../chromeos/chromeos.gyp:cryptohome_signkey_proto', @@ -1143,6 +1140,7 @@ '../third_party/protobuf/protobuf.gyp:protoc#host', '../third_party/re2/re2.gyp:re2', '../third_party/zlib/zlib.gyp:zlib', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/display/display.gyp:display', '../ui/events/devices/events_devices.gyp:events_devices',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 67dedf5e..e64c92a4 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi
@@ -931,6 +931,7 @@ '../chromeos/ime/input_method.gyp:gencode', '../remoting/remoting.gyp:remoting_it2me_host_static', '../third_party/libevent/libevent.gyp:libevent', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', ], 'sources': [ '<@(chrome_browser_extensions_chromeos_sources)',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 16899e2..fc01b9d 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -127,6 +127,8 @@ 'browser/ui/bookmarks/bookmark_utils.h', 'browser/ui/bookmarks/recently_used_folders_combo_model.cc', 'browser/ui/bookmarks/recently_used_folders_combo_model.h', + 'browser/ui/browser_commands_chromeos.cc', + 'browser/ui/browser_commands_chromeos.h', 'browser/ui/browser_commands_mac.cc', 'browser/ui/browser_commands_mac.h', 'browser/ui/browser_content_translate_driver_observer.cc', @@ -997,8 +999,6 @@ 'browser/ui/webui/chromeos/mobile_setup_dialog.h', 'browser/ui/webui/chromeos/mobile_setup_ui.cc', 'browser/ui/webui/chromeos/mobile_setup_ui.h', - 'browser/ui/webui/chromeos/network_config_message_handler.cc', - 'browser/ui/webui/chromeos/network_config_message_handler.h', 'browser/ui/webui/chromeos/network_ui.cc', 'browser/ui/webui/chromeos/network_ui.h', 'browser/ui/webui/chromeos/nfc_debug_ui.cc', @@ -1644,6 +1644,8 @@ 'browser/ui/webui/identity_internals_ui.h', 'browser/ui/webui/inspect_ui.cc', 'browser/ui/webui/inspect_ui.h', + 'browser/ui/webui/md_settings_ui.cc', + 'browser/ui/webui/md_settings_ui.h', 'browser/ui/webui/ntp/app_launcher_handler.cc', 'browser/ui/webui/ntp/app_launcher_handler.h', 'browser/ui/webui/ntp/app_resource_cache_factory.cc', @@ -2734,6 +2736,7 @@ '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', '../third_party/npapi/npapi.gyp:npapi', '../third_party/re2/re2.gyp:re2', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/compositor/compositor.gyp:compositor', '../ui/native_theme/native_theme.gyp:native_theme', '../ui/surface/surface.gyp:surface',
diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi index dd01c01..719d6c4 100644 --- a/chrome/chrome_dll_bundle.gypi +++ b/chrome/chrome_dll_bundle.gypi
@@ -146,6 +146,7 @@ }, { 'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Internet Plug-Ins', + 'files': [], 'conditions': [ ['disable_nacl!=1', { 'conditions': [
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 2713e9b..d027f37d 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi
@@ -190,7 +190,7 @@ '../build/linux/system.gyp:xext', ], }], - ['enable_plugins==1', { + ['OS=="linux" and enable_plugins==1', { 'dependencies': [ '../pdf/pdf.gyp:pdf', ],
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index ffc463b..d9f96749 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi
@@ -116,8 +116,6 @@ 'renderer/extensions/resource_request_policy.h', 'renderer/extensions/sync_file_system_custom_bindings.cc', 'renderer/extensions/sync_file_system_custom_bindings.h', - 'renderer/extensions/tab_finder.cc', - 'renderer/extensions/tab_finder.h', 'renderer/extensions/tabs_custom_bindings.cc', 'renderer/extensions/tabs_custom_bindings.h', 'renderer/extensions/webstore_bindings.cc', @@ -188,6 +186,8 @@ 'renderer/pepper/pepper_shared_memory_message_filter.h', 'renderer/pepper/pepper_uma_host.cc', 'renderer/pepper/pepper_uma_host.h', + 'renderer/plugins/plugin_preroller.cc', + 'renderer/plugins/plugin_preroller.h', ], # For safe_browsing==1 or safe_browsing==2. 'chrome_renderer_basic_safe_browsing_sources': [
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 4c72b47..706756a 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi
@@ -33,10 +33,7 @@ '../extensions/browser/api/bluetooth/bluetooth_apitest.cc', '../extensions/browser/api/bluetooth/bluetooth_private_apitest.cc', '../extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc', - '../extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc', '../extensions/browser/api/cast_channel/cast_channel_apitest.cc', - '../extensions/browser/api/cast_channel/test_util.cc', - '../extensions/browser/api/cast_channel/test_util.h', '../extensions/browser/api/runtime/runtime_apitest.cc', '../extensions/browser/api/serial/serial_apitest.cc', '../extensions/browser/api/usb/usb_manual_apitest.cc', @@ -182,6 +179,7 @@ 'browser/extensions/api/omnibox/omnibox_api_browsertest.cc', 'browser/extensions/api/page_capture/page_capture_apitest.cc', 'browser/extensions/api/permissions/permissions_apitest.cc', + 'browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc', 'browser/extensions/api/preference/preference_apitest.cc', 'browser/extensions/api/preferences_private/preferences_private_apitest.cc', 'browser/extensions/api/processes/processes_apitest.cc', @@ -272,6 +270,7 @@ 'browser/extensions/requirements_checker_browsertest.cc', 'browser/extensions/sandboxed_pages_apitest.cc', 'browser/extensions/shared_module_apitest.cc', + 'browser/extensions/signin/gaia_auth_extension_loader_browsertest.cc', 'browser/extensions/startup_helper_browsertest.cc', 'browser/extensions/stubs_apitest.cc', 'browser/extensions/subscribe_page_action_browsertest.cc', @@ -538,7 +537,6 @@ 'renderer/autofill/password_generation_agent_browsertest.cc', 'renderer/content_settings_observer_browsertest.cc', 'renderer/media/cast_session_browsertest.cc', - 'renderer/printing/print_web_view_helper_browsertest.cc', 'renderer/translate/translate_helper_browsertest.cc', 'renderer/translate/translate_script_browsertest.cc', 'test/base/chrome_render_view_test.cc', @@ -874,7 +872,6 @@ 'test/data/webui/sandboxstatus_browsertest.js', ], 'chrome_interactive_ui_test_sources': [ - '../chrome/browser/ui/webui/options/language_options_interactive_uitest.cc', '../extensions/browser/app_window/app_window_interactive_uitest.cc', '../ui/base/clipboard/clipboard_android_unittest.cc', '../ui/base/clipboard/clipboard_unittest.cc', @@ -887,6 +884,7 @@ 'browser/apps/app_window_intercept_all_keys_uitest.cc', 'browser/apps/guest_view/web_view_interactive_browsertest.cc', 'browser/autofill/autofill_interactive_uitest.cc', + 'browser/autofill/autofill_uitest_util.cc', 'browser/browser_keyevents_browsertest.cc', 'browser/chrome_plugin_interactive_test.cc', 'browser/extensions/api/extension_action/browser_action_interactive_test.cc', @@ -939,6 +937,9 @@ 'browser/ui/startup/startup_browser_creator_interactive_uitest.cc', 'browser/ui/toolbar/test_toolbar_model.cc', 'browser/ui/toolbar/test_toolbar_model.h', + 'browser/ui/webui/options/autofill_options_interactive_uitest.cc', + 'browser/ui/webui/options/language_options_interactive_uitest.cc', + 'browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc', 'test/base/interactive_test_utils.cc', 'test/base/interactive_test_utils.h', 'test/base/interactive_test_utils_aura.cc', @@ -2137,6 +2138,7 @@ }, { # Non-ChromeOS 'sources!': [ 'browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc', + 'browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc', 'browser/extensions/api/terminal/terminal_private_apitest.cc', 'browser/invalidation/profile_invalidation_provider_factory_browsertest.cc', 'browser/net/nss_context_chromeos_browsertest.cc', @@ -2358,11 +2360,6 @@ 'test/data/webui/print_preview.js', ], }], - ['enable_basic_printing==0 and enable_print_preview==0', { - 'sources!': [ - 'renderer/printing/print_web_view_helper_browsertest.cc', - ], - }], ['enable_mdns==1', { 'sources' : [ 'browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index eaad070..6f4e081 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -283,6 +283,7 @@ 'browser/sync/profile_sync_service_android_unittest.cc', 'browser/sync/profile_sync_service_autofill_unittest.cc', 'browser/sync/profile_sync_service_bookmark_unittest.cc', + 'browser/sync/profile_sync_service_factory_unittest.cc', 'browser/sync/profile_sync_service_startup_unittest.cc', 'browser/sync/profile_sync_service_typed_url_unittest.cc', 'browser/sync/profile_sync_service_unittest.cc', @@ -1336,6 +1337,7 @@ 'browser/ui/views/tabs/tab_unittest.cc', 'browser/ui/views/toolbar/reload_button_unittest.cc', 'browser/ui/views/toolbar/test_toolbar_actions_bar_helper_views.cc', + 'browser/ui/views/toolbar/toolbar_action_view_unittest.cc', 'browser/ui/views/translate/translate_bubble_view_unittest.cc', 'browser/ui/views/validation_message_bubble_delegate_unittest.cc', ], @@ -1676,6 +1678,8 @@ 'browser/ui/passwords/manage_passwords_ui_controller_mock.h', 'browser/ui/pdf/pdf_browsertest_base.cc', 'browser/ui/pdf/pdf_browsertest_base.h', + 'browser/ui/toolbar/test_toolbar_action_view_controller.cc', + 'browser/ui/toolbar/test_toolbar_action_view_controller.h', 'browser/ui/test/test_confirm_bubble_model.cc', 'browser/ui/test/test_confirm_bubble_model.h', 'browser/ui/views/find_bar_host_unittest_util_views.cc', @@ -1802,12 +1806,10 @@ 'browser/chromeos/input_method/mock_input_method_engine.h', 'browser/chromeos/input_method/mock_input_method_manager.cc', 'browser/chromeos/input_method/mock_input_method_manager.h', - 'browser/chromeos/login/fake_login_utils.cc', - 'browser/chromeos/login/fake_login_utils.h', - 'browser/chromeos/login/mock_login_utils.cc', - 'browser/chromeos/login/mock_login_utils.h', 'browser/chromeos/login/screens/mock_device_disabled_screen_actor.cc', 'browser/chromeos/login/screens/mock_device_disabled_screen_actor.h', + 'browser/chromeos/login/session/user_session_manager_test_api.cc', + 'browser/chromeos/login/session/user_session_manager_test_api.h', 'browser/chromeos/login/test/oobe_screen_waiter.cc', 'browser/chromeos/login/test/oobe_screen_waiter.h', 'browser/chromeos/login/test/js_checker.cc', @@ -1874,12 +1876,6 @@ 'service', ], }], - ['enable_basic_printing==1 or enable_print_preview==1', { - 'sources': [ - 'renderer/printing/mock_printer.cc', - 'renderer/printing/mock_printer.h', - ], - }], ['enable_extensions==1', { 'dependencies': [ '../components/components.gyp:storage_monitor_test_support',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 6986eee..10b70579 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -259,6 +259,9 @@ const char kDisableMinimizeOnSecondLauncherItemClick[] = "disable-minimize-on-second-launcher-item-click"; +// Disables the new bookmark app system. +const char kDisableNewBookmarkApps[] = "disable-new-bookmark-apps"; + // Disables the new offline error page generated by NetErrorHelper for ChromeOS // and instead uses the old error page generated by OfflineResourceThrottle. const char kDisableNewOfflineErrorPage[] = "disable-new-offline-error-page"; @@ -461,9 +464,6 @@ // Enables the network-related benchmarking extensions. const char kEnableNetBenchmarking[] = "enable-net-benchmarking"; -// Enables the new bookmark app system. -const char kEnableNewBookmarkApps[] = "enable-new-bookmark-apps"; - // Enables NPN with HTTP. It means NPN is enabled but SPDY won't be used. // HTTP is still used for all requests. const char kEnableNpnHttpOnly[] = "enable-npn-http"; @@ -1376,6 +1376,12 @@ return false; } + +bool MdSettingsEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kEnableMaterialDesignSettings); +} + bool SettingsWindowEnabled() { #if defined(OS_CHROMEOS) return !base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index d8772316..83e3394 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -79,6 +79,7 @@ extern const char kDisableIPv6[]; extern const char kDisableJavaScriptHarmonyShipping[]; extern const char kDisableMinimizeOnSecondLauncherItemClick[]; +extern const char kDisableNewBookmarkApps[]; extern const char kDisableNewOfflineErrorPage[]; extern const char kDisableNTPOtherSessionsMenu[]; extern const char kDisableOfflineAutoReload[]; @@ -135,7 +136,6 @@ extern const char kEnableMaterialDesignSettings[]; extern const char kEnableNaCl[]; extern const char kEnableNetBenchmarking[]; -extern const char kEnableNewBookmarkApps[]; extern const char kEnableNpnHttpOnly[]; extern const char kEnableOfflineAutoReload[]; extern const char kEnableOfflineAutoReloadVisibleOnly[]; @@ -397,6 +397,7 @@ #endif bool AboutInSettingsEnabled(); +bool MdSettingsEnabled(); bool NewOfflineErrorPageEnabled(); bool OutOfProcessPdfEnabled(); bool PdfMaterialUIEnabled();
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 65518e95..bde2cf747 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -555,7 +555,15 @@ "extension_types": ["extension", "legacy_packaged_app", "platform_app"], "contexts": ["blessed_extension"] }, + "platformKeys": { + "dependencies": ["permission:platformKeys"], + "contexts": ["blessed_extension"] + }, "platformKeysInternal": [{ + "dependencies": ["permission:platformKeys"], + "internal": true, + "contexts": ["blessed_extension"] + },{ "dependencies": ["permission:enterprise.platformKeys"], "internal": true, "contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index aedc4e1..45057a1 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -675,7 +675,11 @@ "D2DAA9362153E8A5E3CF593E6DF4666421ABAD21", // http://crbug.com/374965 "D7986543275120831B39EF28D1327552FC343960", // http://crbug.com/378067 "A291B26E088FA6BA53FFD72F0916F06EBA7C585A", // http://crbug.com/378067 - "62CCAAD339E6451BBF97C4BBDF758E934A05AD0B" // Hotword triggering + "62CCAAD339E6451BBF97C4BBDF758E934A05AD0B", // Hotword triggering + "07BD6A765FFC289FF755D7CAB2893A40EC337FEC", // http://crbug.com/456214 + "896B85CC7E913E11C34892C1425A093C0701D386", // http://crbug.com/456214 + "11A01C82EF355E674E4F9728A801F5C3CB40D83F", // http://crbug.com/456214 + "F410C88469990EE7947450311D24B8AF2ADB2595" // http://crbug.com/456214 ] }, "mdns": { @@ -742,6 +746,11 @@ "channel": "stable", "extension_types": ["platform_app"] }, + "platformKeys": { + "channel": "dev", + "platforms": ["chromeos"], + "extension_types": ["extension", "platform_app"] + }, "plugin": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"]
diff --git a/chrome/common/extensions/api/document_scan.idl b/chrome/common/extensions/api/document_scan.idl index 97baa91c..a2bdcca 100644 --- a/chrome/common/extensions/api/document_scan.idl +++ b/chrome/common/extensions/api/document_scan.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Use the <code>chrome.document_scan</code> API to discover and retrieve +// Use the <code>chrome.documentScan</code> API to discover and retrieve // images from attached paper document scanners. namespace documentScan { dictionary ScanOptions {
diff --git a/chrome/common/extensions/api/input_method_private.json b/chrome/common/extensions/api/input_method_private.json index f9fd3d4..4b0e5fc 100644 --- a/chrome/common/extensions/api/input_method_private.json +++ b/chrome/common/extensions/api/input_method_private.json
@@ -25,7 +25,7 @@ "description": "The input method config object.", "properties": { "isPhysicalKeyboardAutocorrectEnabled": {"type": "boolean"}, - "isNewQPInputViewEnabled": {"type": "boolean"}, + "isNewMDInputViewEnabled": {"type": "boolean"}, "isVoiceInputEnabled": {"type": "boolean"} } }
diff --git a/chrome/common/extensions/api/platform_keys_internal.idl b/chrome/common/extensions/api/platform_keys_internal.idl index afd68e51..0e2d827 100644 --- a/chrome/common/extensions/api/platform_keys_internal.idl +++ b/chrome/common/extensions/api/platform_keys_internal.idl
@@ -6,11 +6,18 @@ // APIs. [ implemented_in = "chrome/browser/extensions/api/platform_keys/platform_keys_api.h" ] namespace platformKeysInternal { + callback SelectCallback = void (platformKeys.Match[] certs); + // Invoked by <code>sign</code>. // |signature| The signature, a octet string. callback SignCallback = void(ArrayBuffer signature); interface Functions { + // See documentation in platformKeys. + static void selectClientCertificates( + platformKeys.SelectDetails details, + SelectCallback callback); + // Internal version of platformKeys.subtleCrypto.sign and // enterprise.platformKeys.Token.subtleCrypto.sign. // |tokenId| The id of a Token returned by |getTokens|.
diff --git a/chrome/common/extensions/api/schemas.gypi b/chrome/common/extensions/api/schemas.gypi index d02d0a1..f2af6057 100644 --- a/chrome/common/extensions/api/schemas.gypi +++ b/chrome/common/extensions/api/schemas.gypi
@@ -114,6 +114,7 @@ 'file_system_provider_internal.idl', 'first_run_private.json', 'log_private.idl', + 'platform_keys.idl', 'platform_keys_internal.idl', 'wallpaper.json', 'wallpaper_private.json',
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css index 48a6c26..09da2ad9 100644 --- a/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css +++ b/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css
@@ -10,8 +10,8 @@ } html.loading * { - -webkit-transition-delay: 0 !important; - -webkit-transition-duration: 0 !important; + -webkit-transition-delay: 0ms !important; + -webkit-transition-duration: 0ms !important; } body {
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css index f70d6dc..0549332 100644 --- a/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css +++ b/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css
@@ -43,7 +43,7 @@ /* If the options page is loading don't do the transition. */ .loading .overlay, .loading .overlay .page { - -webkit-transition-duration: 0 !important; + -webkit-transition-duration: 0ms !important; } /* keyframes used to pulse the overlay */
diff --git a/chrome/common/extensions/docs/templates/articles/app_usb.html b/chrome/common/extensions/docs/templates/articles/app_usb.html index d886b37..62177c4 100644 --- a/chrome/common/extensions/docs/templates/articles/app_usb.html +++ b/chrome/common/extensions/docs/templates/articles/app_usb.html
@@ -49,12 +49,14 @@ <pre data-filename="manifest.json"> "permissions": [ - "usbDevices": [ - { - "vendorId": 123, - "productId": 456 - } - ] + { + "usbDevices": [ + { + "vendorId": 123, + "productId": 456 + } + ] + } ] </pre>
diff --git a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json index fe901f2c..ec8c38b8 100644 --- a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json +++ b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
@@ -616,6 +616,14 @@ { "title": "OAuth", "href": "/extensions/tut_oauth" + }, + { + "title": "Options", + "href": "/extensions/options" + }, + { + "title": "Options Version 2", + "href": "/extensions/optionsV2" } ] },
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 4ca22c0..af4602e1 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -109,7 +109,8 @@ PermissionMessage::kCopresence}, {APIPermission::kCopresencePrivate, "copresencePrivate"}, {APIPermission::kCryptotokenPrivate, "cryptotokenPrivate"}, - {APIPermission::kDataReductionProxy, "dataReductionProxy", + {APIPermission::kDataReductionProxy, + "dataReductionProxy", APIPermissionInfo::kFlagImpliesFullURLAccess | APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kDocumentScan, @@ -151,6 +152,11 @@ APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_NATIVE_MESSAGING, PermissionMessage::kNativeMessaging}, + {APIPermission::kPlatformKeys, + "platformKeys", + APIPermissionInfo::kFlagNone, + IDS_EXTENSION_PROMPT_WARNING_PLATFORMKEYS, + PermissionMessage::kPlatformKeys}, {APIPermission::kPrivacy, "privacy", APIPermissionInfo::kFlagNone,
diff --git a/chrome/common/extensions/permissions/permissions_data_unittest.cc b/chrome/common/extensions/permissions/permissions_data_unittest.cc index a38b10c..2b91573 100644 --- a/chrome/common/extensions/permissions/permissions_data_unittest.cc +++ b/chrome/common/extensions/permissions/permissions_data_unittest.cc
@@ -215,6 +215,22 @@ EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/"))); EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); + + // Tab-specific permissions should be included in the effective hosts. + GURL tab_url("http://www.example.com/"); + URLPatternSet new_hosts; + new_hosts.AddOrigin(URLPattern::SCHEME_ALL, tab_url); + extension->permissions_data()->UpdateTabSpecificPermissions( + 1, + new PermissionSet(APIPermissionSet(), + ManifestPermissionSet(), + new_hosts, + URLPatternSet())); + EXPECT_TRUE(extension->permissions_data()->GetEffectiveHostPermissions(). + MatchesURL(tab_url)); + extension->permissions_data()->ClearTabSpecificPermissions(1); + EXPECT_FALSE(extension->permissions_data()->GetEffectiveHostPermissions(). + MatchesURL(tab_url)); } TEST(PermissionsDataTest, SocketPermissions) {
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 43de89d..c613faf3 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1206,9 +1206,6 @@ // a preference was reset. const char kPreferenceResetTime[] = "prefs.preference_reset_time"; -// The GCM channel's enabled state. -const char kGCMChannelEnabled[] = "gcm.channel_enabled"; - // How many Service Workers are registered with the Push API (could be zero). const char kPushMessagingRegistrationCount[] = "gcm.push_messaging_registration_count";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index b67c1b61..39cf707 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -402,7 +402,6 @@ extern const char kPreferenceResetTime[]; -extern const char kGCMChannelEnabled[]; extern const char kPushMessagingRegistrationCount[]; extern const char kEasyUnlockAllowed[];
diff --git a/chrome/common/service_process_util_win.cc b/chrome/common/service_process_util_win.cc index 6800353a..b858d707 100644 --- a/chrome/common/service_process_util_win.cc +++ b/chrome/common/service_process_util_win.cc
@@ -67,7 +67,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "ServiceProcessTerminateMonitor_OnObjectSignaled")); + "418183 ServiceProcessTerminateMonitor::OnObjectSignaled")); if (!terminate_task_.is_null()) { terminate_task_.Run();
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 9487e8ccb..a3aedca 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -58,6 +58,7 @@ const char kChromeUIInstantURL[] = "chrome://instant/"; const char kChromeUIInterstitialURL[] = "chrome://interstitials/"; const char kChromeUIInvalidationsURL[] = "chrome://invalidations/"; +const char kChromeUIMdSettingsURL[] = "chrome://md-settings/"; const char kChromeUIMemoryRedirectURL[] = "chrome://memory-redirect/"; const char kChromeUIMemoryURL[] = "chrome://memory/"; const char kChromeUIMetroFlowURL[] = "chrome://make-metro/"; @@ -200,6 +201,7 @@ const char kChromeUIInvalidationsHost[] = "invalidations"; const char kChromeUIKillHost[] = "kill"; const char kChromeUILocalStateHost[] = "local-state"; +const char kChromeUIMdSettingsHost[] = "md-settings"; const char kChromeUIMemoryHost[] = "memory"; const char kChromeUIMemoryInternalsHost[] = "memory-internals"; const char kChromeUIMemoryRedirectHost[] = "memory-redirect";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 864ab11..7fddc01 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -70,6 +70,7 @@ extern const char kChromeUIQuitURL[]; extern const char kChromeUIRestartURL[]; extern const char kChromeUISessionFaviconURL[]; +extern const char kChromeUIMdSettingsURL[]; extern const char kChromeUISettingsURL[]; extern const char kChromeUISettingsFrameURL[]; extern const char kChromeUISuggestions[]; @@ -195,6 +196,7 @@ extern const char kChromeUIMemoryInternalsHost[]; extern const char kChromeUIMemoryRedirectHost[]; extern const char kChromeUIMetroFlowHost[]; +extern const char kChromeUIMdSettingsHost[]; extern const char kChromeUINaClHost[]; extern const char kChromeUINetExportHost[]; extern const char kChromeUINetInternalsHost[];
diff --git a/chrome/common/web_application_info.cc b/chrome/common/web_application_info.cc index 5a01d62c6..6cca5db 100644 --- a/chrome/common/web_application_info.cc +++ b/chrome/common/web_application_info.cc
@@ -12,7 +12,8 @@ WebApplicationInfo::WebApplicationInfo() : mobile_capable(MOBILE_CAPABLE_UNSPECIFIED), - generated_icon_color(SK_ColorTRANSPARENT) { + generated_icon_color(SK_ColorTRANSPARENT), + open_as_window(false) { } WebApplicationInfo::~WebApplicationInfo() {
diff --git a/chrome/common/web_application_info.h b/chrome/common/web_application_info.h index 5ff59ab..74a3a019 100644 --- a/chrome/common/web_application_info.h +++ b/chrome/common/web_application_info.h
@@ -53,6 +53,10 @@ // The color to use if an icon needs to be generated for the web app. SkColor generated_icon_color; + + // Whether the app should be opened in a window. If false, the app will be + // opened in a tab. + bool open_as_window; }; #endif // CHROME_COMMON_WEB_APPLICATION_INFO_H_
diff --git a/chrome/installer/linux/debian/expected_deps_ia32 b/chrome/installer/linux/debian/expected_deps_ia32 index 115bbc32..f3d8eca 100644 --- a/chrome/installer/linux/debian/expected_deps_ia32 +++ b/chrome/installer/linux/debian/expected_deps_ia32
@@ -2,6 +2,7 @@ libasound2 (>= 1.0.23) libc6 (>= 2.11) libcairo2 (>= 1.6.0) +libcap2 (>= 2.10) libcups2 (>= 1.4.0) libdbus-1-3 (>= 1.2.14) libexpat1 (>= 1.95.8)
diff --git a/chrome/installer/linux/debian/expected_deps_x64 b/chrome/installer/linux/debian/expected_deps_x64 index 115bbc32..f3d8eca 100644 --- a/chrome/installer/linux/debian/expected_deps_x64 +++ b/chrome/installer/linux/debian/expected_deps_x64
@@ -2,6 +2,7 @@ libasound2 (>= 1.0.23) libc6 (>= 2.11) libcairo2 (>= 1.6.0) +libcap2 (>= 2.10) libcups2 (>= 1.4.0) libdbus-1-3 (>= 1.2.14) libexpat1 (>= 1.95.8)
diff --git a/chrome/installer/linux/rpm/expected_deps_i386 b/chrome/installer/linux/rpm/expected_deps_i386 index 7ebb9da..215d0f78 100644 --- a/chrome/installer/linux/rpm/expected_deps_i386 +++ b/chrome/installer/linux/rpm/expected_deps_i386
@@ -3,6 +3,7 @@ ld-linux.so.2(GLIBC_2.3) libasound.so.2 libcairo.so.2 +libcap.so.2 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1)
diff --git a/chrome/installer/linux/rpm/expected_deps_x86_64 b/chrome/installer/linux/rpm/expected_deps_x86_64 index 60b6082..5cbde426 100644 --- a/chrome/installer/linux/rpm/expected_deps_x86_64 +++ b/chrome/installer/linux/rpm/expected_deps_x86_64
@@ -3,6 +3,7 @@ ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libasound.so.2()(64bit) libcairo.so.2()(64bit) +libcap.so.2()(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.11)(64bit) libc.so.6(GLIBC_2.2.5)(64bit)
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index d94824d..68ecef44 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc
@@ -285,20 +285,20 @@ << installer::kVisualElementsManifest << " to " << src_path.value(); return true; } else { - // A printf_p-style format string for generating the visual elements + // A printf-style format string for generating the visual elements // manifest. Required arguments, in order, are: // - Localized display name for the product. - // - Relative path to the VisualElements directory. + // - Relative path to the VisualElements directory, three times. static const char kManifestTemplate[] = "<Application>\r\n" " <VisualElements\r\n" - " DisplayName='%1$ls'\r\n" - " Logo='%2$ls\\Logo.png'\r\n" - " SmallLogo='%2$ls\\SmallLogo.png'\r\n" + " DisplayName='%ls'\r\n" + " Logo='%ls\\Logo.png'\r\n" + " SmallLogo='%ls\\SmallLogo.png'\r\n" " ForegroundText='light'\r\n" " BackgroundColor='#323232'>\r\n" " <DefaultTile ShowName='allLogos'/>\r\n" - " <SplashScreen Image='%2$ls\\splash-620x300.png'/>\r\n" + " <SplashScreen Image='%ls\\splash-620x300.png'/>\r\n" " </VisualElements>\r\n" "</Application>"; @@ -314,7 +314,8 @@ // Fill the manifest with the desired values. base::string16 manifest16(base::StringPrintf( - manifest_template.c_str(), display_name.c_str(), elements_dir.c_str())); + manifest_template.c_str(), display_name.c_str(), elements_dir.c_str(), + elements_dir.c_str(), elements_dir.c_str())); // Write the manifest to |src_path|. const std::string manifest(base::UTF16ToUTF8(manifest16));
diff --git a/chrome/interactive_ui_tests.isolate b/chrome/interactive_ui_tests.isolate index d968a7d..1d78389 100644 --- a/chrome/interactive_ui_tests.isolate +++ b/chrome/interactive_ui_tests.isolate
@@ -70,6 +70,13 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/interactive_ui_tests.dSYM/', + ], + }, + }], ['OS=="mac" or OS=="win"', { 'variables': { 'command': [
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index f1aa9aff..ede533a 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -192,12 +192,6 @@ if (enable_print_preview) { deps += [ "//chrome/service" ] } - if (enable_basic_printing || enable_print_preview) { - sources += [ - "printing/mock_printer.cc", - "printing/mock_printer.h", - ] - } if (enable_webrtc) { sources += [
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index aa35794..8ee88ff 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -40,6 +40,7 @@ #include "chrome/renderer/pepper/pepper_helper.h" #include "chrome/renderer/playback_extension.h" #include "chrome/renderer/plugins/chrome_plugin_placeholder.h" +#include "chrome/renderer/plugins/plugin_preroller.h" #include "chrome/renderer/plugins/plugin_uma.h" #include "chrome/renderer/plugins/shadow_dom_plugin_placeholder.h" #include "chrome/renderer/prefetch_helper.h" @@ -627,7 +628,7 @@ const WebPluginParams& original_params, const ChromeViewHostMsg_GetPluginInfo_Output& output) { const ChromeViewHostMsg_GetPluginInfo_Status& status = output.status; - const WebPluginInfo& plugin = output.plugin; + const WebPluginInfo& info = output.plugin; const std::string& actual_mime_type = output.actual_mime_type; const base::string16& group_name = output.group_name; const std::string& identifier = output.group_identifier; @@ -661,12 +662,11 @@ } else { // TODO(bauerb): This should be in content/. WebPluginParams params(original_params); - for (size_t i = 0; i < plugin.mime_types.size(); ++i) { - if (plugin.mime_types[i].mime_type == actual_mime_type) { - AppendParams(plugin.mime_types[i].additional_param_names, - plugin.mime_types[i].additional_param_values, - ¶ms.attributeNames, - ¶ms.attributeValues); + for (size_t i = 0; i < info.mime_types.size(); ++i) { + if (info.mime_types[i].mime_type == actual_mime_type) { + AppendParams(info.mime_types[i].additional_param_names, + info.mime_types[i].additional_param_values, + ¶ms.attributeNames, ¶ms.attributeValues); break; } } @@ -682,9 +682,9 @@ ContentSettingsObserver::Get(render_frame); const ContentSettingsType content_type = - ShouldUseJavaScriptSettingForPlugin(plugin) ? - CONTENT_SETTINGS_TYPE_JAVASCRIPT : - CONTENT_SETTINGS_TYPE_PLUGINS; + ShouldUseJavaScriptSettingForPlugin(info) + ? CONTENT_SETTINGS_TYPE_JAVASCRIPT + : CONTENT_SETTINGS_TYPE_PLUGINS; if ((status_value == ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized || @@ -714,7 +714,7 @@ // In Windows we need to check if we can load NPAPI plugins. // For example, if the render view is in the Ash desktop, we should not. if (status_value == ChromeViewHostMsg_GetPluginInfo_Status::kAllowed && - plugin.type == content::WebPluginInfo::PLUGIN_TYPE_NPAPI) { + info.type == content::WebPluginInfo::PLUGIN_TYPE_NPAPI) { if (observer->AreNPAPIPluginsBlocked()) status_value = ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; @@ -722,12 +722,11 @@ #endif auto create_blocked_plugin = - [&render_frame, &frame, ¶ms, &plugin, &identifier, &group_name]( - int template_id, const base::string16& message, - const GURL& poster_url) { + [&render_frame, &frame, ¶ms, &info, &identifier, &group_name]( + int template_id, const base::string16& message) { return ChromePluginPlaceholder::CreateBlockedPlugin( - render_frame, frame, params, plugin, identifier, group_name, - template_id, message, poster_url); + render_frame, frame, params, info, identifier, group_name, + template_id, message, GURL()); }; switch (status_value) { case ChromeViewHostMsg_GetPluginInfo_Status::kNotFound: { @@ -738,7 +737,7 @@ case ChromeViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: { #if !defined(DISABLE_NACL) && defined(ENABLE_EXTENSIONS) const bool is_nacl_plugin = - plugin.name == ASCIIToUTF16(nacl::kNaClPluginName); + info.name == ASCIIToUTF16(nacl::kNaClPluginName); const bool is_nacl_mime_type = actual_mime_type == nacl::kNaClPluginMimeType; const bool is_pnacl_mime_type = @@ -761,7 +760,7 @@ } else { // NaCl is being invoked as a content handler. Look up the NaCl // module using the MIME type. The app URL is the manifest URL. - manifest_url = GetNaClContentHandlerURL(actual_mime_type, plugin); + manifest_url = GetNaClContentHandlerURL(actual_mime_type, info); app_url = manifest_url; } const Extension* extension = @@ -788,11 +787,10 @@ placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, #if defined(OS_CHROMEOS) - l10n_util::GetStringUTF16(IDS_NACL_PLUGIN_BLOCKED), + l10n_util::GetStringUTF16(IDS_NACL_PLUGIN_BLOCKED)); #else - l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); #endif - GURL()); break; } } @@ -813,7 +811,7 @@ &poster_url, &cross_origin_main_content)) { // TODO(tommycli): Apply throttler behavior to all plugins. - if (plugin.name == base::ASCIIToUTF16(content::kFlashPluginName) && + if (info.name == base::ASCIIToUTF16(content::kFlashPluginName) && status_value == ChromeViewHostMsg_GetPluginInfo_Status:: kPlayImportantContent) { power_saver_mode = @@ -835,7 +833,8 @@ bool is_prerendering = prerender::PrerenderHelper::IsPrerendering(render_frame); if (blocked_for_background_tab || is_prerendering || show_poster) { - placeholder = create_blocked_plugin( + placeholder = ChromePluginPlaceholder::CreateBlockedPlugin( + render_frame, frame, params, info, identifier, group_name, show_poster ? IDR_PLUGIN_POSTER_HTML : IDR_BLOCKED_PLUGIN_HTML, l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), poster_url); @@ -849,8 +848,24 @@ GURL content_origin = GURL(params.url).GetOrigin(); render_frame->WhitelistContentOrigin(content_origin); } + + if (power_saver_mode == + PluginPowerSaverMode::POWER_SAVER_MODE_PERIPHERAL_THROTTLED) { + content::PluginInstanceThrottler* throttler_raw = throttler.get(); + blink::WebPlugin* plugin = + render_frame->CreatePlugin(frame, info, params, throttler.Pass()); + + // PluginPreroller manages its own lifetime. + new PluginPreroller( + render_frame, frame, params, info, identifier, group_name, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), + plugin, throttler_raw); + + return plugin; + } + #endif // defined(ENABLE_PLUGINS) - return render_frame->CreatePlugin(frame, plugin, params, + return render_frame->CreatePlugin(frame, info, params, throttler.Pass()); } case ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported: { @@ -858,7 +873,7 @@ UserMetricsAction("Plugin_NPAPINotSupported")); placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_SUPPORTED_METRO), GURL()); + l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_SUPPORTED_METRO)); render_frame->Send(new ChromeViewHostMsg_NPAPINotSupported( render_frame->GetRoutingID(), identifier)); break; @@ -868,16 +883,14 @@ url); placeholder = create_blocked_plugin( IDR_DISABLED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_DISABLED, group_name), - GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_DISABLED, group_name)); break; } case ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: { #if defined(ENABLE_PLUGIN_INSTALLATION) placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name), - GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name)); placeholder->set_allow_loading(true); render_frame->Send(new ChromeViewHostMsg_BlockedOutdatedPlugin( render_frame->GetRoutingID(), placeholder->CreateRoutingId(), @@ -890,17 +903,15 @@ case ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed: { placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name), - GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name)); break; } case ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized: { placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name), - GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name)); placeholder->set_allow_loading(true); - if (plugin.type != content::WebPluginInfo::PLUGIN_TYPE_NPAPI) { + if (info.type != content::WebPluginInfo::PLUGIN_TYPE_NPAPI) { render_frame->Send(new ChromeViewHostMsg_BlockedUnauthorizedPlugin( render_frame->GetRoutingID(), group_name, @@ -912,7 +923,7 @@ case ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay: { placeholder = create_blocked_plugin( IDR_CLICK_TO_PLAY_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_LOAD, group_name), GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_LOAD, group_name)); placeholder->set_allow_loading(true); RenderThread::Get()->RecordAction( UserMetricsAction("Plugin_ClickToPlay")); @@ -922,7 +933,7 @@ case ChromeViewHostMsg_GetPluginInfo_Status::kBlocked: { placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); placeholder->set_allow_loading(true); RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Blocked")); observer->DidBlockContentType(content_type, group_name); @@ -931,7 +942,7 @@ case ChromeViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy: { placeholder = create_blocked_plugin( IDR_BLOCKED_PLUGIN_HTML, - l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), GURL()); + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); placeholder->set_allow_loading(false); RenderThread::Get()->RecordAction( UserMetricsAction("Plugin_BlockedByPolicy"));
diff --git a/chrome/renderer/chrome_mock_render_thread.cc b/chrome/renderer/chrome_mock_render_thread.cc index bb3e589a42..61b68c0 100644 --- a/chrome/renderer/chrome_mock_render_thread.cc +++ b/chrome/renderer/chrome_mock_render_thread.cc
@@ -4,37 +4,13 @@ #include "chrome/renderer/chrome_mock_render_thread.h" -#include <vector> - -#include "base/values.h" -#include "chrome/renderer/printing/mock_printer.h" -#include "ipc/ipc_sync_message.h" -#include "printing/page_range.h" -#include "printing/print_job_constants.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_CHROMEOS) -#include <fcntl.h> - -#include "base/files/file_util.h" -#endif - #if defined(ENABLE_EXTENSIONS) #include "extensions/common/extension_messages.h" #endif -#if defined(ENABLE_PRINTING) -#include "components/printing/common/print_messages.h" -#endif - -ChromeMockRenderThread::ChromeMockRenderThread() -#if defined(ENABLE_PRINTING) - : printer_(new MockPrinter), - print_dialog_user_response_(true), - print_preview_cancel_page_number_(-1), - print_preview_pages_remaining_(0) -#endif -{ +ChromeMockRenderThread::ChromeMockRenderThread() { } ChromeMockRenderThread::~ChromeMockRenderThread() { @@ -55,37 +31,17 @@ return true; // Some messages we do special handling. +#if defined(ENABLE_EXTENSIONS) bool handled = true; IPC_BEGIN_MESSAGE_MAP(ChromeMockRenderThread, msg) -#if defined(ENABLE_EXTENSIONS) IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToExtension, OnOpenChannelToExtension) -#endif -#if defined(ENABLE_PRINTING) - IPC_MESSAGE_HANDLER(PrintHostMsg_GetDefaultPrintSettings, - OnGetDefaultPrintSettings) - IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint) - IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, - OnDidGetPrintedPagesCount) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, - OnDidGetPreviewPageCount) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) - IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel) -#if defined(OS_WIN) - IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection) -#endif -#if defined(OS_CHROMEOS) - IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting, - OnAllocateTempFileForPrinting) - IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten, - OnTempFileForPrintingWritten) -#endif // defined(OS_CHROMEOS) -#endif // defined(ENABLE_PRINTING) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; +#else + return false; +#endif } #if defined(ENABLE_EXTENSIONS) @@ -98,141 +54,3 @@ *port_id = 0; } #endif - -#if defined(ENABLE_PRINTING) -#if defined(OS_CHROMEOS) -void ChromeMockRenderThread::OnAllocateTempFileForPrinting( - int render_view_id, - base::FileDescriptor* renderer_fd, - int* browser_fd) { - renderer_fd->fd = *browser_fd = -1; - renderer_fd->auto_close = false; - - base::FilePath path; - if (base::CreateTemporaryFile(&path)) { - int fd = open(path.value().c_str(), O_WRONLY); - DCHECK_GE(fd, 0); - renderer_fd->fd = *browser_fd = fd; - } -} - -void ChromeMockRenderThread::OnTempFileForPrintingWritten(int render_view_id, - int browser_fd) { - close(browser_fd); -} -#endif // defined(OS_CHROMEOS) - -void ChromeMockRenderThread::OnGetDefaultPrintSettings( - PrintMsg_Print_Params* params) { - printer_->GetDefaultPrintSettings(params); -} - -void ChromeMockRenderThread::OnScriptedPrint( - const PrintHostMsg_ScriptedPrint_Params& params, - PrintMsg_PrintPages_Params* settings) { - if (print_dialog_user_response_) { - printer_->ScriptedPrint(params.cookie, - params.expected_pages_count, - params.has_selection, - settings); - } -} - -void ChromeMockRenderThread::OnDidGetPrintedPagesCount( - int cookie, int number_pages) { - printer_->SetPrintedPagesCount(cookie, number_pages); -} - -void ChromeMockRenderThread::OnDidPrintPage( - const PrintHostMsg_DidPrintPage_Params& params) { - printer_->PrintPage(params); -} - -void ChromeMockRenderThread::OnDidGetPreviewPageCount( - const PrintHostMsg_DidGetPreviewPageCount_Params& params) { - print_preview_pages_remaining_ = params.page_count; -} - -void ChromeMockRenderThread::OnDidPreviewPage( - const PrintHostMsg_DidPreviewPage_Params& params) { - DCHECK_GE(params.page_number, printing::FIRST_PAGE_INDEX); - print_preview_pages_remaining_--; -} - -void ChromeMockRenderThread::OnCheckForCancel(int32 preview_ui_id, - int preview_request_id, - bool* cancel) { - *cancel = - (print_preview_pages_remaining_ == print_preview_cancel_page_number_); -} - -void ChromeMockRenderThread::OnUpdatePrintSettings( - int document_cookie, - const base::DictionaryValue& job_settings, - PrintMsg_PrintPages_Params* params, - bool* canceled) { - if (canceled) - *canceled = false; - // Check and make sure the required settings are all there. - // We don't actually care about the values. - std::string dummy_string; - int margins_type = 0; - if (!job_settings.GetBoolean(printing::kSettingLandscape, NULL) || - !job_settings.GetBoolean(printing::kSettingCollate, NULL) || - !job_settings.GetInteger(printing::kSettingColor, NULL) || - !job_settings.GetBoolean(printing::kSettingPrintToPDF, NULL) || - !job_settings.GetBoolean(printing::kIsFirstRequest, NULL) || - !job_settings.GetString(printing::kSettingDeviceName, &dummy_string) || - !job_settings.GetInteger(printing::kSettingDuplexMode, NULL) || - !job_settings.GetInteger(printing::kSettingCopies, NULL) || - !job_settings.GetInteger(printing::kPreviewUIID, NULL) || - !job_settings.GetInteger(printing::kPreviewRequestID, NULL) || - !job_settings.GetInteger(printing::kSettingMarginsType, &margins_type)) { - return; - } - - // Just return the default settings. - const base::ListValue* page_range_array; - printing::PageRanges new_ranges; - if (job_settings.GetList(printing::kSettingPageRange, &page_range_array)) { - for (size_t index = 0; index < page_range_array->GetSize(); ++index) { - const base::DictionaryValue* dict; - if (!page_range_array->GetDictionary(index, &dict)) - continue; - printing::PageRange range; - if (!dict->GetInteger(printing::kSettingPageRangeFrom, &range.from) || - !dict->GetInteger(printing::kSettingPageRangeTo, &range.to)) { - continue; - } - // Page numbers are 1-based in the dictionary. - // Page numbers are 0-based for the printing context. - range.from--; - range.to--; - new_ranges.push_back(range); - } - } - std::vector<int> pages(printing::PageRange::GetPages(new_ranges)); - printer_->UpdateSettings(document_cookie, params, pages, margins_type); - - job_settings.GetBoolean(printing::kSettingShouldPrintSelectionOnly, - ¶ms->params.selection_only); - job_settings.GetBoolean(printing::kSettingShouldPrintBackgrounds, - ¶ms->params.should_print_backgrounds); -} - -MockPrinter* ChromeMockRenderThread::printer() { - return printer_.get(); -} - -void ChromeMockRenderThread::set_print_dialog_user_response(bool response) { - print_dialog_user_response_ = response; -} - -void ChromeMockRenderThread::set_print_preview_cancel_page_number(int page) { - print_preview_cancel_page_number_ = page; -} - -int ChromeMockRenderThread::print_preview_pages_remaining() const { - return print_preview_pages_remaining_; -} -#endif // defined(ENABLE_PRINTING)
diff --git a/chrome/renderer/chrome_mock_render_thread.h b/chrome/renderer/chrome_mock_render_thread.h index ea3a1e9e..f97629d9 100644 --- a/chrome/renderer/chrome_mock_render_thread.h +++ b/chrome/renderer/chrome_mock_render_thread.h
@@ -7,24 +7,11 @@ #include <string> -#include "base/compiler_specific.h" #include "content/public/test/mock_render_thread.h" -namespace base { -class DictionaryValue; -} - -class MockPrinter; struct ExtensionMsg_ExternalConnectionInfo; -struct PrintHostMsg_DidGetPreviewPageCount_Params; -struct PrintHostMsg_DidPreviewPage_Params; -struct PrintHostMsg_DidPrintPage_Params; -struct PrintHostMsg_ScriptedPrint_Params; -struct PrintMsg_PrintPages_Params; -struct PrintMsg_Print_Params; -// Extends content::MockRenderThread to know about printing and -// extension messages. +// Extends content::MockRenderThread to know about extension messages. class ChromeMockRenderThread : public content::MockRenderThread { public: ChromeMockRenderThread(); @@ -40,21 +27,6 @@ void set_io_message_loop_proxy( const scoped_refptr<base::MessageLoopProxy>& proxy); -#if defined(ENABLE_PRINTING) - // Returns the pseudo-printer instance. - MockPrinter* printer(); - - // Call with |response| set to true if the user wants to print. - // False if the user decides to cancel. - void set_print_dialog_user_response(bool response); - - // Cancel print preview when print preview has |page| remaining pages. - void set_print_preview_cancel_page_number(int page); - - // Get the number of pages to generate for print preview. - int print_preview_pages_remaining() const; -#endif - private: // Overrides base class implementation to add custom handling for // print and extensions. @@ -69,51 +41,6 @@ int* port_id); #endif -#if defined(ENABLE_PRINTING) -#if defined(OS_CHROMEOS) || defined(OS_ANDROID) - void OnAllocateTempFileForPrinting(int render_view_id, - base::FileDescriptor* renderer_fd, - int* browser_fd); - void OnTempFileForPrintingWritten(int render_view_id, int browser_fd); -#endif - - // PrintWebViewHelper expects default print settings. - void OnGetDefaultPrintSettings(PrintMsg_Print_Params* setting); - - // PrintWebViewHelper expects final print settings from the user. - void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params, - PrintMsg_PrintPages_Params* settings); - - void OnDidGetPrintedPagesCount(int cookie, int number_pages); - void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params); - void OnDidGetPreviewPageCount( - const PrintHostMsg_DidGetPreviewPageCount_Params& params); - void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params); - void OnCheckForCancel(int32 preview_ui_id, - int preview_request_id, - bool* cancel); - - - // For print preview, PrintWebViewHelper will update settings. - void OnUpdatePrintSettings(int document_cookie, - const base::DictionaryValue& job_settings, - PrintMsg_PrintPages_Params* params, - bool* canceled); - - // A mock printer device used for printing tests. - scoped_ptr<MockPrinter> printer_; - - // True to simulate user clicking print. False to cancel. - bool print_dialog_user_response_; - - // Simulates cancelling print preview if |print_preview_pages_remaining_| - // equals this. - int print_preview_cancel_page_number_; - - // Number of pages to generate for print preview. - int print_preview_pages_remaining_; -#endif - scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; DISALLOW_COPY_AND_ASSIGN(ChromeMockRenderThread);
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 4fe2ff4..9045848 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -23,7 +23,6 @@ #include "chrome/renderer/extensions/page_capture_custom_bindings.h" #include "chrome/renderer/extensions/platform_keys_natives.h" #include "chrome/renderer/extensions/sync_file_system_custom_bindings.h" -#include "chrome/renderer/extensions/tab_finder.h" #include "chrome/renderer/extensions/tabs_custom_bindings.h" #include "chrome/renderer/extensions/webstore_bindings.h" #include "content/public/renderer/render_thread.h" @@ -189,6 +188,8 @@ source_map->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); source_map->RegisterSource("pageCapture", IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("platformKeys", + IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS); source_map->RegisterSource("platformKeys.internalAPI", IDR_PLATFORM_KEYS_INTERNAL_API_JS); source_map->RegisterSource("platformKeys.Key", IDR_PLATFORM_KEYS_KEY_JS);
diff --git a/chrome/renderer/media/cast_session_delegate.cc b/chrome/renderer/media/cast_session_delegate.cc index d44a62b3..4be9fe3 100644 --- a/chrome/renderer/media/cast_session_delegate.cc +++ b/chrome/renderer/media/cast_session_delegate.cc
@@ -4,9 +4,11 @@ #include "chrome/renderer/media/cast_session_delegate.h" +#include "base/callback_helpers.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/strings/stringprintf.h" #include "chrome/common/chrome_version_info.h" #include "chrome/renderer/media/cast_threads.h" #include "chrome/renderer/media/cast_transport_sender_ipc.h" @@ -54,8 +56,8 @@ audio_frame_input_available_callback_ = callback; cast_sender_->InitializeAudio( config, - base::Bind(&CastSessionDelegate::InitializationResultCB, - weak_factory_.GetWeakPtr(), error_callback)); + base::Bind(&CastSessionDelegate::OnOperationalStatusChange, + weak_factory_.GetWeakPtr(), true, error_callback)); } void CastSessionDelegate::StartVideo( @@ -76,8 +78,8 @@ cast_sender_->InitializeVideo( config, - base::Bind(&CastSessionDelegate::InitializationResultCB, - weak_factory_.GetWeakPtr(), error_callback), + base::Bind(&CastSessionDelegate::OnOperationalStatusChange, + weak_factory_.GetWeakPtr(), false, error_callback), create_vea_cb, create_video_encode_mem_cb); } @@ -206,44 +208,51 @@ // TODO(hubbe): Call javascript UDPTransport error function. } -void CastSessionDelegate::InitializationResultCB( +void CastSessionDelegate::OnOperationalStatusChange( + bool is_for_audio, const ErrorCallback& error_callback, - media::cast::CastInitializationStatus result) const { + media::cast::OperationalStatus status) { DCHECK(cast_sender_); - switch (result) { - case media::cast::STATUS_AUDIO_INITIALIZED: - audio_frame_input_available_callback_.Run( - cast_sender_->audio_frame_input()); + switch (status) { + case media::cast::STATUS_UNINITIALIZED: + case media::cast::STATUS_CODEC_REINIT_PENDING: + // Not an error. + // TODO(miu): As an optimization, signal the client to pause sending more + // frames until the state becomes STATUS_INITIALIZED again. break; - case media::cast::STATUS_VIDEO_INITIALIZED: - video_frame_input_available_callback_.Run( - cast_sender_->video_frame_input()); + case media::cast::STATUS_INITIALIZED: + // Once initialized, run the "frame input available" callback to allow the + // client to begin sending frames. If STATUS_INITIALIZED is encountered + // again, do nothing since this is only an indication that the codec has + // successfully re-initialized. + if (is_for_audio) { + if (!audio_frame_input_available_callback_.is_null()) { + base::ResetAndReturn(&audio_frame_input_available_callback_).Run( + cast_sender_->audio_frame_input()); + } + } else { + if (!video_frame_input_available_callback_.is_null()) { + base::ResetAndReturn(&video_frame_input_available_callback_).Run( + cast_sender_->video_frame_input()); + } + } break; - case media::cast::STATUS_INVALID_CAST_ENVIRONMENT: - error_callback.Run("Invalid cast environment."); + case media::cast::STATUS_INVALID_CONFIGURATION: + error_callback.Run(base::StringPrintf("Invalid %s configuration.", + is_for_audio ? "audio" : "video")); break; - case media::cast::STATUS_INVALID_CRYPTO_CONFIGURATION: - error_callback.Run("Invalid encryption keys."); + case media::cast::STATUS_UNSUPPORTED_CODEC: + error_callback.Run(base::StringPrintf("%s codec not supported.", + is_for_audio ? "Audio" : "Video")); break; - case media::cast::STATUS_UNSUPPORTED_AUDIO_CODEC: - error_callback.Run("Audio codec not supported."); + case media::cast::STATUS_CODEC_INIT_FAILED: + error_callback.Run(base::StringPrintf("%s codec initialization failed.", + is_for_audio ? "Audio" : "Video")); break; - case media::cast::STATUS_UNSUPPORTED_VIDEO_CODEC: - error_callback.Run("Video codec not supported."); - break; - case media::cast::STATUS_INVALID_AUDIO_CONFIGURATION: - error_callback.Run("Invalid audio configuration."); - break; - case media::cast::STATUS_INVALID_VIDEO_CONFIGURATION: - error_callback.Run("Invalid video configuration."); - break; - case media::cast::STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED: - error_callback.Run("Hardware video encoder not supported."); - break; - case media::cast::STATUS_AUDIO_UNINITIALIZED: - case media::cast::STATUS_VIDEO_UNINITIALIZED: - NOTREACHED() << "Not an error."; + case media::cast::STATUS_CODEC_RUNTIME_ERROR: + error_callback.Run(base::StringPrintf("%s codec runtime error.", + is_for_audio ? "Audio" : "Video")); break; } }
diff --git a/chrome/renderer/media/cast_session_delegate.h b/chrome/renderer/media/cast_session_delegate.h index a89892c2..fb0dd097 100644 --- a/chrome/renderer/media/cast_session_delegate.h +++ b/chrome/renderer/media/cast_session_delegate.h
@@ -86,12 +86,17 @@ void GetStatsAndReset(bool is_audio, const StatsCallback& callback); protected: - // Callback with the result of the initialization. - // If this callback is called with STATUS_INITIALIZED it will report back - // to the sinks that it's ready to accept incoming audio / video frames. - void InitializationResultCB( + // Called to report back operational status changes. The first time this is + // called with STATUS_INITIALIZED will result in running the "frame input + // available" callback, to indicate the session is ready to accept incoming + // audio/video frames. If this is called with an error that has halted the + // session, the |error_callback| provided to StartXXX() will be run. This + // method may be called multiple times during the session to indicate codec + // re-initializations are taking place and/or runtime errors have occurred. + void OnOperationalStatusChange( + bool is_for_audio, const ErrorCallback& error_callback, - media::cast::CastInitializationStatus result) const; + media::cast::OperationalStatus result); private: void StatusNotificationCB(
diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.cc b/chrome/renderer/plugins/chrome_plugin_placeholder.cc index 7be0698..4a1720f 100644 --- a/chrome/renderer/plugins/chrome_plugin_placeholder.cc +++ b/chrome/renderer/plugins/chrome_plugin_placeholder.cc
@@ -148,7 +148,7 @@ content::RenderFrame* render_frame, WebLocalFrame* frame, const WebPluginParams& params, - const content::WebPluginInfo& plugin, + const content::WebPluginInfo& info, const std::string& identifier, const base::string16& name, int template_id, @@ -177,7 +177,7 @@ if (poster_url.is_valid()) blocked_plugin->BlockForPowerSaverPoster(); #endif - blocked_plugin->SetPluginInfo(plugin); + blocked_plugin->SetPluginInfo(info); blocked_plugin->SetIdentifier(identifier); return blocked_plugin; }
diff --git a/chrome/renderer/plugins/plugin_preroller.cc b/chrome/renderer/plugins/plugin_preroller.cc new file mode 100644 index 0000000..34d830f --- /dev/null +++ b/chrome/renderer/plugins/plugin_preroller.cc
@@ -0,0 +1,88 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/plugins/plugin_preroller.h" + +#include "base/base64.h" +#include "chrome/grit/renderer_resources.h" +#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" +#include "third_party/WebKit/public/platform/WebRect.h" +#include "third_party/WebKit/public/web/WebElement.h" +#include "third_party/WebKit/public/web/WebPlugin.h" +#include "third_party/WebKit/public/web/WebPluginContainer.h" +#include "ui/gfx/codec/png_codec.h" + +PluginPreroller::PluginPreroller(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + const base::string16& message, + blink::WebPlugin* plugin, + content::PluginInstanceThrottler* throttler) + : RenderFrameObserver(render_frame), + frame_(frame), + params_(params), + info_(info), + identifier_(identifier), + name_(name), + message_(message), + plugin_(plugin), + throttler_(throttler) { + DCHECK(plugin); + DCHECK(throttler); + throttler_->AddObserver(this); +} + +PluginPreroller::~PluginPreroller() { + if (throttler_) + throttler_->RemoveObserver(this); +} + +void PluginPreroller::OnKeyframeExtracted(const SkBitmap* bitmap) { + std::vector<unsigned char> png_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data)) { + DLOG(ERROR) << "Provided keyframe could not be encoded as PNG."; + return; + } + + base::StringPiece png_as_string(reinterpret_cast<char*>(&png_data[0]), + png_data.size()); + + std::string data_url_header = "data:image/png;base64,"; + std::string data_url_body; + base::Base64Encode(png_as_string, &data_url_body); + keyframe_data_url_ = GURL(data_url_header + data_url_body); +} + +void PluginPreroller::OnThrottleStateChange() { + if (!throttler_->IsThrottled()) + return; + + ChromePluginPlaceholder* placeholder = + ChromePluginPlaceholder::CreateBlockedPlugin( + render_frame(), frame_, params_, info_, identifier_, name_, + IDR_PLUGIN_POSTER_HTML, message_, keyframe_data_url_); + placeholder->SetPremadePlugin(plugin_, throttler_); + placeholder->set_power_saver_mode( + content::PluginPowerSaverMode::POWER_SAVER_MODE_PERIPHERAL_THROTTLED); + placeholder->set_allow_loading(true); + + blink::WebPluginContainer* container = plugin_->container(); + container->setPlugin(placeholder->plugin()); + + bool success = placeholder->plugin()->initialize(container); + DCHECK(success); + + container->invalidate(); + container->reportGeometry(); + + delete this; +} + +void PluginPreroller::OnThrottlerDestroyed() { + throttler_ = nullptr; + delete this; +}
diff --git a/chrome/renderer/plugins/plugin_preroller.h b/chrome/renderer/plugins/plugin_preroller.h new file mode 100644 index 0000000..78e34b3a --- /dev/null +++ b/chrome/renderer/plugins/plugin_preroller.h
@@ -0,0 +1,63 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PLUGINS_PLUGIN_PREROLLER_H_ +#define CHROME_RENDERER_PLUGINS_PLUGIN_PREROLLER_H_ + +#include "base/macros.h" +#include "content/public/common/webplugininfo.h" +#include "content/public/renderer/plugin_instance_throttler.h" +#include "content/public/renderer/render_frame_observer.h" +#include "third_party/WebKit/public/web/WebPluginParams.h" +#include "url/gurl.h" + +namespace blink { +class WebLocalFrame; +class WebPlugin; +} + +class SkBitmap; + +// This class manages a plugin briefly for the purposes of keyframe extraction. +// Once a keyframe has been extracted, this class will replace the plugin with +// a ChromePluginPlaceholder. The actual plugin will continue to live in a +// throttled state. This class manages its own lifetime. +class PluginPreroller : public content::PluginInstanceThrottler::Observer, + public content::RenderFrameObserver { + public: + // Does not take ownership of either |plugin| or |throttler|. + PluginPreroller(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + const base::string16& message, + blink::WebPlugin* plugin, + content::PluginInstanceThrottler* throttler); + + ~PluginPreroller() override; + + private: + // content::PluginInstanceThrottler::Observer methods: + void OnKeyframeExtracted(const SkBitmap* bitmap) override; + void OnThrottleStateChange() override; + void OnThrottlerDestroyed() override; + + blink::WebLocalFrame* frame_; + blink::WebPluginParams params_; + content::WebPluginInfo info_; + std::string identifier_; + base::string16 name_; + base::string16 message_; + + blink::WebPlugin* plugin_; + content::PluginInstanceThrottler* throttler_; + + GURL keyframe_data_url_; + + DISALLOW_COPY_AND_ASSIGN(PluginPreroller); +}; + +#endif // CHROME_RENDERER_PLUGINS_PLUGIN_PREROLLER_H_
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index 309edacb..9dcf6261 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -728,7 +728,7 @@ // TODO(dtseng): Make into set listing all hosting node roles. if (nodeData.role == schema.RoleType.webView) { - if (nodeImpl.childTreeID !== nodeData.intAttributes.childTreeId) + if (nodeImpl.pendingChildFrame === undefined) nodeImpl.pendingChildFrame = true; if (nodeImpl.pendingChildFrame) {
diff --git a/chrome/renderer/resources/extensions/platform_keys/internal_api.js b/chrome/renderer/resources/extensions/platform_keys/internal_api.js index b152116..41afe5f0 100644 --- a/chrome/renderer/resources/extensions/platform_keys/internal_api.js +++ b/chrome/renderer/resources/extensions/platform_keys/internal_api.js
@@ -6,4 +6,5 @@ .Binding.create('platformKeysInternal') .generate(); +exports.selectClientCertificates = binding.selectClientCertificates; exports.sign = binding.sign;
diff --git a/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js b/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js new file mode 100644 index 0000000..c9eb659 --- /dev/null +++ b/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js
@@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Custom binding for the platformKeys API. + +var binding = require('binding').Binding.create('platformKeys'); +var SubtleCrypto = require('platformKeys.SubtleCrypto').SubtleCrypto; +var internalAPI = require('platformKeys.internalAPI'); + +binding.registerCustomHook(function(api) { + var apiFunctions = api.apiFunctions; + var subtleCrypto = new SubtleCrypto('' /* tokenId */); + + apiFunctions.setHandleRequest( + 'selectClientCertificates', function(details, callback) { + internalAPI.selectClientCertificates(details, callback); + }); + + apiFunctions.setHandleRequest( + 'subtleCrypto', function() { return subtleCrypto }); +}); + +exports.binding = binding.generate();
diff --git a/chrome/renderer/resources/neterror.css b/chrome/renderer/resources/neterror.css index 4939d0e4..dae5f2b3 100644 --- a/chrome/renderer/resources/neterror.css +++ b/chrome/renderer/resources/neterror.css
@@ -37,6 +37,7 @@ .icon { -webkit-user-select: none; + content: ''; } .icon-generic { @@ -153,6 +154,7 @@ .error-code { color: #A0A0A0; + font-size: .825em; margin-top: 15px; } @@ -165,11 +167,8 @@ /* Decrease padding at low sizes. */ @media (max-width: 640px), (max-height: 640px) { - body { - margin: 15px; - } h1 { - margin: 10px 0 15px; + margin: 0 0 15px; } #content-top { margin: 15px; @@ -282,8 +281,9 @@ color: #2b2b2b; font-size: 1em; line-height: 1.55; - margin: 100px auto 0; + margin: 0 auto; max-width: 600px; + padding-top: 100px; width: 100%; } @@ -320,11 +320,10 @@ display: none; } -@media (max-width: 400px) { +@media (max-width: 420px) { .suggested-left > #control-buttons, .suggested-right > #control-buttons { float: none; - margin: 50px 0 20px; } } @@ -345,3 +344,9 @@ margin-top: 30px; } } + +@media (min-height: 240px) and (orientation: landscape) { + .offline .interstitial-wrapper { + margin-bottom: 20px; + } +}
diff --git a/chrome/renderer/resources/neterror.html b/chrome/renderer/resources/neterror.html index 1dd7f03..d397f4a4 100644 --- a/chrome/renderer/resources/neterror.html +++ b/chrome/renderer/resources/neterror.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;.style.fontSize:fontsize;lang:language"> +<html i18n-values="dir:textdirection;lang:language"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, @@ -7,66 +7,66 @@ <title i18n-content="title"></title> <link rel="stylesheet" href="../../browser/resources/security_warnings/interstitial_v2.css"> <link rel="stylesheet" href="neterror.css"> + <script src="../../browser/resources/security_warnings/interstitial_v2_mobile.js"></script> <script src="neterror.js"></script> <script src="offline.js"></script> </head> -<body id="t" i18n-values=".style.fontFamily:fontfamily"> +<body id="t" i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> <div id="main-frame-error" class="interstitial-wrapper"> - <img class="icon" - jseval="updateIconClass(this.classList, iconClass)"> - <div id="main-message"> - <h1 i18n-content="heading"></h1> - <p hidden></p> - <div id="buttons" class="nav-wrapper"> - <div id="control-buttons" hidden> - <button id="reload-button" - class="blue-button text-button" - onclick="trackClick(this.trackingId); - reloadButtonClick(this.url);" - jsselect="reloadButton" - jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId" - jscontent="msg"></button> - <button id="stale-load-button" - class="blue-button text-button" - onclick="loadStaleButtonClick()" - jsselect="staleLoadButton" - jscontent="msg" jsvalues="title:title"></button> - </div> - <button id="details-button" class="text-button small-link" - onclick="detailsButtonClick(); toggleHelpBox()" - jsdisplay="details" jscontent="details" - jsvalues=".detailsText:details; .hideDetailsText:hideDetails;"> + <div id="main-content"> + <img class="icon" + jseval="updateIconClass(this.classList, iconClass)"> + <div id="main-message"> + <h1 i18n-content="heading"></h1> + <p hidden></p> </div> </div> - <!-- Outer and inner divs are needed both for margins and sizing. --> - <div id="help-box-outer" class="hidden"> - <div id="details"> - <div jsselect="summary"> - <span jsvalues=".innerHTML:msg"></span> - </div> - <div class="suggestions" jsselect="suggestions"> - <div class="suggestion-header" jsvalues=".innerHTML:header"></div> - <div class="suggestion-body" jsvalues=".innerHTML:body"></div> - </div> - <button class="text-button" id="diagnose-button" - onclick="diagnoseErrors()" jscontent="diagnose" - jsdisplay="diagnose"></button> - <div id="diagnose-frame" class="hidden"></div> - <form class="suggestions" jsdisplay="searchUrl" - jsvalues=".url:searchUrl; .trackingId:searchTrackingId" - onsubmit="trackClick(this.trackingId); return search(this.url);"> - <div class="suggestion-header" jscontent="searchHeader"></div> - <div id="search-container"> - <input type="text" name="q" id="search-box" - jsvalues=".value:searchTerms" /> - <button type="submit" id="search-button" class="blue-button" - jsvalues="aria-label:searchHeader"> - <img id="search-image"> - </button> - </div> - </form> - <div class="error-code" jscontent="errorCode"></div> + <div id="buttons" class="nav-wrapper"> + <div id="control-buttons" hidden> + <button id="reload-button" + class="blue-button text-button" + onclick="trackClick(this.trackingId); + reloadButtonClick(this.url);" + jsselect="reloadButton" + jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId" + jscontent="msg"></button> + <button id="stale-load-button" + class="blue-button text-button" + onclick="loadStaleButtonClick()" + jsselect="staleLoadButton" + jscontent="msg" jsvalues="title:title"></button> </div> + <button id="details-button" class="text-button small-link" + onclick="detailsButtonClick(); toggleHelpBox()" + jsdisplay="details" jscontent="details" + jsvalues=".detailsText:details; .hideDetailsText:hideDetails;"></button> + </div> + <div id="details" class="hidden"> + <div jsselect="summary"> + <span jsvalues=".innerHTML:msg"></span> + </div> + <div class="suggestions" jsselect="suggestions"> + <div class="suggestion-header" jsvalues=".innerHTML:header"></div> + <div class="suggestion-body" jsvalues=".innerHTML:body"></div> + </div> + <button class="text-button" id="diagnose-button" + onclick="diagnoseErrors()" jscontent="diagnose" + jsdisplay="diagnose"></button> + <div id="diagnose-frame" class="hidden"></div> + <form class="suggestions" jsdisplay="searchUrl" + jsvalues=".url:searchUrl; .trackingId:searchTrackingId" + onsubmit="trackClick(this.trackingId); return search(this.url);"> + <div class="suggestion-header" jscontent="searchHeader"></div> + <div id="search-container"> + <input type="text" name="q" id="search-box" + jsvalues=".value:searchTerms" /> + <button type="submit" id="search-button" class="blue-button" + jsvalues="aria-label:searchHeader"> + <img id="search-image"> + </button> + </div> + </form> + <div class="error-code" jscontent="errorCode"></div> </div> </div> <div id="sub-frame-error">
diff --git a/chrome/renderer/resources/neterror.js b/chrome/renderer/resources/neterror.js index 81de561..6b3a9619 100644 --- a/chrome/renderer/resources/neterror.js +++ b/chrome/renderer/resources/neterror.js
@@ -3,13 +3,17 @@ // found in the LICENSE file. function toggleHelpBox() { - var helpBoxOuter = document.getElementById('help-box-outer'); + var helpBoxOuter = document.getElementById('details'); helpBoxOuter.classList.toggle('hidden'); var detailsButton = document.getElementById('details-button'); if (helpBoxOuter.classList.contains('hidden')) detailsButton.innerText = detailsButton.detailsText; else detailsButton.innerText = detailsButton.hideDetailsText; + + // Details appears over the main content on small screens. + if (mobileNav) + document.getElementById('main-content').classList.toggle('hidden'); } function diagnoseErrors() { @@ -53,6 +57,8 @@ if (newClass == 'icon-offline') { document.body.classList.add('offline'); new Runner('.interstitial-wrapper'); + } else { + document.body.classList.add('neterror'); } } @@ -136,7 +142,7 @@ if (loadTimeData.valueExists('summary') && !loadTimeData.getValue('summary').msg) { detailsButton.style.display = 'none'; - document.getElementById('help-box-outer').style.display = 'block'; + document.getElementById('details').style.display = 'block'; } </if>
diff --git a/chrome/renderer/resources/plugin_poster.html b/chrome/renderer/resources/plugin_poster.html index b372878..790f4d98 100644 --- a/chrome/renderer/resources/plugin_poster.html +++ b/chrome/renderer/resources/plugin_poster.html
@@ -3,6 +3,12 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no"> +<script> +function notifyDidFinishLoading() { + if (plugin.didFinishLoading) + plugin.didFinishLoading(); +} +</script> <link rel="stylesheet" href="plugin_placeholders.css"></link> <style> #outer { @@ -10,21 +16,25 @@ } #plugin_icon { - opacity: 0.0; + opacity: 0.2; } #outer:hover #plugin_icon { - opacity: 0.4; + opacity: 1.0; +} + +#inner { + margin-top: -23px; } </style> </head> -<body i18n-values=".style.background-image:background"> -<div i18n-values="title:name" id="outer" onclick="plugin.load()"> -<p id="debug"> </p> -<div id="inner"> -<div><img id="plugin_icon" src="plugin_blocked.png" /></div> -</div> -</div> +<body i18n-values=".style.background-image:background" onload="notifyDidFinishLoading();"> + <div i18n-values="title:name" id="outer" onclick="plugin.load()"> + <div id="inner"> + <div><img id="plugin_icon" src="play.png" /></div> + <p id="debug"> </p> + </div> + </div> </body> </html>
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index da0a535..0917b360 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -74,6 +74,7 @@ <include name="IDR_OMNIBOX_CUSTOM_BINDINGS_JS" file="extensions\omnibox_custom_bindings.js" type="BINDATA" /> <include name="IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS" file="extensions\page_action_custom_bindings.js" type="BINDATA" /> <include name="IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS" file="extensions\page_capture_custom_bindings.js" type="BINDATA" /> + <include name="IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS" file="extensions\platform_keys_custom_bindings.js" type="BINDATA" /> <include name="IDR_PLATFORM_KEYS_INTERNAL_API_JS" file="extensions\platform_keys\internal_api.js" type="BINDATA" /> <include name="IDR_PLATFORM_KEYS_KEY_JS" file="extensions\platform_keys\key.js" type="BINDATA" /> <include name="IDR_PLATFORM_KEYS_SUBTLE_CRYPTO_JS" file="extensions\platform_keys\subtle_crypto.js" type="BINDATA" />
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc index 6c17a9c..9e7d00d 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
@@ -266,9 +266,8 @@ net::SpawnedTestServer::kLocalhost, base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); ASSERT_TRUE(https_server.Start()); - std::string host_str("host.net"); // Must outlive replace_host. GURL::Replacements replace_host; - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("host.net"); GURL test_url = https_server.GetURL("/files/title1.html"); ui_test_utils::NavigateToURL(browser(), test_url.ReplaceComponents(replace_host));
diff --git a/chrome/renderer/web_apps.cc b/chrome/renderer/web_apps.cc index 0d26dfa..7f1500c 100644 --- a/chrome/renderer/web_apps.cc +++ b/chrome/renderer/web_apps.cc
@@ -147,8 +147,8 @@ // "apple-touch-icon-precomposed". if (LowerCaseEqualsASCII(rel, "icon") || LowerCaseEqualsASCII(rel, "shortcut icon") || - (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableNewBookmarkApps) && + (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableNewBookmarkApps) && (LowerCaseEqualsASCII(rel, "apple-touch-icon") || LowerCaseEqualsASCII(rel, "apple-touch-icon-precomposed")))) { AddInstallIcon(elem, &app_info->icons);
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc index 2d787352..b9aa994 100644 --- a/chrome/service/cloud_print/print_system_win.cc +++ b/chrome/service/cloud_print/print_system_win.cc
@@ -92,7 +92,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "PrintSystemWatcherWin_OnObjectSignaled")); + "418183 PrintSystemWatcherWin::OnObjectSignaled")); crash_keys::ScopedPrinterInfo crash_key(printer_info_); DWORD change = 0;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 1c24f05..c266709 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -797,6 +797,7 @@ } else { sources -= [ "../browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc", + "../browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc", "../browser/extensions/api/terminal/terminal_private_apitest.cc", "../browser/invalidation/profile_invalidation_provider_factory_browsertest.cc", "../browser/net/nss_context_chromeos_browsertest.cc", @@ -980,9 +981,6 @@ "data/webui/print_preview.js", ] } - if (!enable_basic_printing && !enable_print_preview) { - sources -= [ "../renderer/printing/print_web_view_helper_browsertest.cc" ] - } if (enable_mdns) { sources += [ "../browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc" ] }
diff --git a/chrome/test/base/chrome_process_util.cc b/chrome/test/base/chrome_process_util.cc index fe6d0c6..282cab0 100644 --- a/chrome/test/base/chrome_process_util.cc +++ b/chrome/test/base/chrome_process_util.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/process/kill.h" +#include "base/process/process.h" #include "base/process/process_iterator.h" #include "base/time/time.h" #include "chrome/common/chrome_constants.h" @@ -49,15 +50,12 @@ void TerminateAllChromeProcesses(const ChromeProcessList& process_pids) { ChromeProcessList::const_iterator it; for (it = process_pids.begin(); it != process_pids.end(); ++it) { - base::ProcessHandle handle; - if (!base::OpenProcessHandle(*it, &handle)) { + base::Process process = base::Process::Open(*it); + if (process.IsValid()) { // Ignore processes for which we can't open the handle. We don't // guarantee that all processes will terminate, only try to do so. - continue; + base::KillProcess(process.Handle(), content::RESULT_CODE_KILLED, true); } - - base::KillProcess(handle, content::RESULT_CODE_KILLED, true); - base::CloseProcessHandle(handle); } }
diff --git a/chrome/test/base/extension_js_browser_test.h b/chrome/test/base/extension_js_browser_test.h index 439e169..34cecdd 100644 --- a/chrome/test/base/extension_js_browser_test.h +++ b/chrome/test/base/extension_js_browser_test.h
@@ -17,7 +17,7 @@ public: ExtensionJSBrowserTest(); - ~ExtensionJSBrowserTest() override; + virtual ~ExtensionJSBrowserTest(); protected: // Waits for an extension to load; returns immediately if already loaded.
diff --git a/chrome/test/base/extension_load_waiter_one_shot.h b/chrome/test/base/extension_load_waiter_one_shot.h index 15cae65..47d22d6 100644 --- a/chrome/test/base/extension_load_waiter_one_shot.h +++ b/chrome/test/base/extension_load_waiter_one_shot.h
@@ -19,16 +19,16 @@ class ExtensionLoadWaiterOneShot : public content::NotificationObserver { public: ExtensionLoadWaiterOneShot(); - ~ExtensionLoadWaiterOneShot() override; + virtual ~ExtensionLoadWaiterOneShot(); // Waits for extension with |extension_id| to load. The id should be a pointer // to a static char array. void WaitForExtension(const char* extension_id, const base::Closure& load_cb); // content::NotificationObserver overrides. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; // Get the browser context associated with the loaded extension. Returns // NULL if |WaitForExtension| was not previously called.
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index b72e260..ab05492b 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -104,8 +104,9 @@ Profile* profile) override {} void ShowUpdateChromeDialog() override {} void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override {} - void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info, - const std::string& extension_id) override {} + void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const ShowBookmarkAppBubbleCallback& callback) override {} void ShowTranslateBubble(content::WebContents* contents, translate::TranslateStep step, translate::TranslateErrors::Type error_type,
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 3c2a90f..100a079 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -568,7 +568,8 @@ HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse( this, BuildHistoryService)); if (!history_service->Init( - no_db, history::HistoryDatabaseParamsForPath(this->GetPath()))) { + no_db, GetPrefs()->GetString(prefs::kAcceptLanguages), + history::HistoryDatabaseParamsForPath(GetPath()))) { HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr); return false; }
diff --git a/chrome/test/data/extensions/api_test/active_tab/background.js b/chrome/test/data/extensions/api_test/active_tab/background.js index cdafdc62..74e587b4 100644 --- a/chrome/test/data/extensions/api_test/active_tab/background.js +++ b/chrome/test/data/extensions/api_test/active_tab/background.js
@@ -10,12 +10,47 @@ var RoleType = chrome.automation.RoleType; -chrome.browserAction.onClicked.addListener(function() { - chrome.tabs.executeScript({ code: 'true' }, callbackPass()); +function canXhr(url) { + assertFalse(url == null); + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + var success = true; + try { + xhr.send(); + } catch(e) { + assertEq('NetworkError', e.name); + success = false; + } + return success; +} + +var cachedUrl = null; +var iframeDone = null; + +chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { + if (request.message == 'xhr') { + sendResponse({url: cachedUrl}); + } else { + assertTrue(request.success); + iframeDone(); + } +}); + +var iframeUrl = chrome.extension.getURL('iframe.html'); +var injectIframe = + 'var iframe = document.createElement("iframe");\n' + + 'iframe.src = "' + iframeUrl + '";\n' + + 'document.body.appendChild(iframe);\n'; + +chrome.browserAction.onClicked.addListener(function(tab) { + iframeDone = chrome.test.callbackAdded(); + cachedUrl = tab.url; + chrome.tabs.executeScript({ code: injectIframe }, callbackPass()); + assertTrue(canXhr(tab.url)); + chrome.automation.getTree(callbackPass(function(rootNode) { assertFalse(rootNode == undefined); assertEq(RoleType.rootWebArea, rootNode.role); - chrome.test.succeed(); })); }); @@ -27,4 +62,6 @@ chrome.automation.getTree(callbackFail( 'Cannot request automation tree on url "' + details.url + '". Extension manifest must request permission to access this host.')); + + assertFalse(canXhr(details.url)); });
diff --git a/chrome/test/data/extensions/api_test/active_tab/iframe.html b/chrome/test/data/extensions/api_test/active_tab/iframe.html new file mode 100644 index 0000000..395d3279 --- /dev/null +++ b/chrome/test/data/extensions/api_test/active_tab/iframe.html
@@ -0,0 +1,4 @@ +<!doctype html> +<html> +<script src="iframe.js"></script> +</html>
diff --git a/chrome/test/data/extensions/api_test/active_tab/iframe.js b/chrome/test/data/extensions/api_test/active_tab/iframe.js new file mode 100644 index 0000000..b4c59cc --- /dev/null +++ b/chrome/test/data/extensions/api_test/active_tab/iframe.js
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function canXhr(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + var success = true; + try { + xhr.send(); + } catch(e) { + assertEq('NetworkError', e.name); + success = false; + } + return success; +} + +document.addEventListener('DOMContentLoaded', function() { + chrome.runtime.sendMessage({message:'xhr'}, function(response) { + var success = canXhr(response.url); + chrome.runtime.sendMessage({success:success}); + }); +});
diff --git a/chrome/test/data/extensions/api_test/active_tab/manifest.json b/chrome/test/data/extensions/api_test/active_tab/manifest.json index f3638e2e..7c7ec34 100644 --- a/chrome/test/data/extensions/api_test/active_tab/manifest.json +++ b/chrome/test/data/extensions/api_test/active_tab/manifest.json
@@ -18,5 +18,7 @@ "automation": true, - "manifest_version": 2 + "manifest_version": 2, + + "web_accessible_resources": [ "iframe.html" ] }
diff --git a/chrome/test/data/extensions/api_test/management/test/launchType.js b/chrome/test/data/extensions/api_test/management/test/launchType.js index 77499eb..b2d40f3 100644 --- a/chrome/test/data/extensions/api_test/management/test/launchType.js +++ b/chrome/test/data/extensions/api_test/management/test/launchType.js
@@ -31,8 +31,6 @@ types.push("OPEN_AS_REGULAR_TAB"); types.push("OPEN_AS_WINDOW"); - types.push("OPEN_AS_PINNED_TAB"); - types.push("OPEN_FULL_SCREEN"); return types; }
diff --git a/chrome/test/data/extensions/api_test/platform_keys/OWNERS b/chrome/test/data/extensions/api_test/platform_keys/OWNERS new file mode 100644 index 0000000..713045b6 --- /dev/null +++ b/chrome/test/data/extensions/api_test/platform_keys/OWNERS
@@ -0,0 +1 @@ +pneubeck@chromium.org
diff --git a/chrome/test/data/extensions/api_test/platform_keys/basic.html b/chrome/test/data/extensions/api_test/platform_keys/basic.html new file mode 100644 index 0000000..957ba1c --- /dev/null +++ b/chrome/test/data/extensions/api_test/platform_keys/basic.html
@@ -0,0 +1,6 @@ +<!-- + * Copyright 2015 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<script src="basic.js"></script>
diff --git a/chrome/test/data/extensions/api_test/platform_keys/basic.js b/chrome/test/data/extensions/api_test/platform_keys/basic.js new file mode 100644 index 0000000..9c643e5 --- /dev/null +++ b/chrome/test/data/extensions/api_test/platform_keys/basic.js
@@ -0,0 +1,234 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +var systemTokenEnabled = (location.href.indexOf("systemTokenEnabled") != -1); + +var assertEq = chrome.test.assertEq; +var assertTrue = chrome.test.assertTrue; +var assertThrows = chrome.test.assertThrows; +var fail = chrome.test.fail; +var succeed = chrome.test.succeed; +var callbackPass = chrome.test.callbackPass; +var callbackFail= chrome.test.callbackFail; + +// A X.509 client certificate in DER encoding. +var clientCert1 = new Uint8Array([ + 0x30, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x10, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x0f, 0x31, 0x0d, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x04, 0x42, 0x20, 0x43, + 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x38, 0x31, 0x34, 0x30, + 0x32, 0x34, 0x36, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x38, + 0x31, 0x31, 0x30, 0x32, 0x34, 0x36, 0x33, 0x37, 0x5a, 0x30, 0x18, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0d, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x41, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd5, 0xdf, 0xba, 0x34, + 0xcb, 0xc2, 0x03, 0xb5, 0x37, 0x7a, 0x61, 0x89, 0x1a, 0xb5, 0x1a, 0xb9, + 0x27, 0x7f, 0xa9, 0x2c, 0xba, 0xa1, 0x36, 0xac, 0x83, 0x6d, 0xb8, 0x45, + 0x9e, 0x35, 0x82, 0xa4, 0xde, 0xa3, 0x69, 0x38, 0x25, 0x84, 0x57, 0x00, + 0x8c, 0x41, 0x84, 0x86, 0x6d, 0x78, 0x41, 0xd4, 0x10, 0x99, 0x1b, 0x15, + 0x18, 0xa6, 0x04, 0x2f, 0x92, 0xa0, 0x1c, 0x29, 0xc3, 0xe0, 0x5d, 0xe2, + 0x90, 0x11, 0x2c, 0xfa, 0xac, 0x18, 0x0d, 0xfe, 0x5e, 0x8d, 0x5c, 0x5a, + 0x01, 0x4a, 0xf7, 0x2c, 0xc9, 0x6e, 0x39, 0x8e, 0x14, 0x30, 0xd9, 0xfc, + 0xf6, 0x6a, 0xee, 0x9d, 0xa3, 0xba, 0x23, 0xfe, 0x5d, 0xaa, 0x2f, 0x96, + 0x07, 0x65, 0x38, 0xca, 0xa4, 0x3c, 0xd2, 0x93, 0x21, 0xb0, 0xb6, 0xdb, + 0xfb, 0x40, 0x12, 0x00, 0x01, 0x99, 0x30, 0x41, 0x67, 0xe2, 0x2f, 0x65, + 0x63, 0x71, 0xaa, 0xa6, 0xef, 0x45, 0x23, 0x05, 0x8b, 0xb4, 0x28, 0x6c, + 0x35, 0xbf, 0x41, 0x73, 0x61, 0xf1, 0x9e, 0x77, 0x8c, 0xa7, 0x51, 0xcf, + 0xc7, 0x51, 0x63, 0xc7, 0x00, 0xab, 0x4e, 0xa3, 0xe5, 0x8f, 0xfe, 0x3c, + 0x45, 0xfa, 0x9e, 0xd2, 0x29, 0xbc, 0x59, 0x94, 0x7d, 0x14, 0xc9, 0x36, + 0xdf, 0xcd, 0x0a, 0xb5, 0x9f, 0xbf, 0xac, 0xfd, 0x1d, 0x2b, 0x6d, 0xe5, + 0x13, 0x30, 0x14, 0x71, 0xde, 0x77, 0xdf, 0x83, 0xf3, 0x6d, 0x2c, 0xcd, + 0x16, 0xc0, 0xa5, 0xdc, 0xf2, 0x1f, 0x65, 0x86, 0x37, 0x91, 0x2f, 0x31, + 0x66, 0x7e, 0x1a, 0x4b, 0x42, 0xb7, 0x29, 0xe1, 0xcd, 0x1d, 0xc9, 0x72, + 0x0e, 0x65, 0x8e, 0xa9, 0x4c, 0x74, 0x2e, 0x90, 0xb7, 0xe0, 0x91, 0x0c, + 0xe8, 0xfe, 0x92, 0x26, 0xa7, 0x17, 0x9a, 0xb6, 0x25, 0x7f, 0x66, 0x89, + 0x2f, 0xbf, 0x54, 0xa7, 0x51, 0x4c, 0xe6, 0x8f, 0x4d, 0x34, 0xa1, 0xc3, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0x6d, 0x3e, 0xc3, 0xd4, 0xc8, 0xd1, 0xfc, 0xec, 0x0e, 0xd3, + 0xca, 0xc8, 0x4c, 0x8d, 0xfe, 0xab, 0x51, 0xfb, 0x1c, 0xa4, 0xf6, 0x3c, + 0x13, 0x07, 0x76, 0x58, 0x7f, 0x61, 0x34, 0x9c, 0xb6, 0xfd, 0x9a, 0xc5, + 0x7e, 0xc7, 0xb7, 0xe0, 0x89, 0xfb, 0xc5, 0x67, 0x76, 0x75, 0xee, 0xab, + 0xd9, 0xbf, 0xfb, 0xaa, 0x3e, 0xe9, 0x5a, 0x4a, 0xc1, 0x83, 0xc3, 0xc6, + 0xa0, 0x01, 0x8e, 0xb1, 0xf8, 0x0d, 0x08, 0x9a, 0x26, 0xa7, 0xb7, 0x3c, + 0x19, 0xb0, 0x76, 0x77, 0x57, 0x03, 0xc3, 0x61, 0xcf, 0x56, 0x7e, 0x59, + 0x25, 0x10, 0x11, 0xbb, 0x4d, 0x20, 0xd5, 0x49, 0x51, 0x0d, 0xc9, 0x19, + 0xbb, 0x50, 0x4e, 0xd1, 0xf7, 0x62, 0x21, 0x84, 0x02, 0x9b, 0x9b, 0xfa, + 0xca, 0xef, 0xde, 0x7f, 0x6c, 0xa0, 0x1e, 0xf6, 0x50, 0x87, 0x26, 0xeb, + 0x2a, 0xfd, 0xe3, 0x69, 0x4b, 0x12, 0x10, 0x9b, 0xe3, 0xf5, 0x96, 0x33, + 0x23, 0xb5, 0x06, 0x31, 0x42, 0x26, 0x8c, 0x07, 0xcc, 0x0a, 0x19, 0x4a, + 0xa5, 0x92, 0x44, 0xa3, 0x22, 0x5a, 0x69, 0xad, 0x4a, 0x96, 0x61, 0xb7, + 0xa8, 0x6f, 0xbe, 0x31, 0x30, 0xb2, 0x1d, 0xee, 0x5a, 0x21, 0x87, 0xa7, + 0x33, 0x51, 0x02, 0xe4, 0x24, 0x86, 0xab, 0x8e, 0xaa, 0x94, 0xf4, 0x25, + 0x6e, 0x3f, 0x53, 0x42, 0xce, 0x12, 0x91, 0x99, 0x23, 0x52, 0x1d, 0xba, + 0xdf, 0x59, 0x11, 0x0f, 0x34, 0x2e, 0x8e, 0x58, 0xac, 0xdf, 0x6b, 0x1a, + 0x08, 0xa3, 0x03, 0x46, 0x0f, 0xc0, 0x11, 0x72, 0x66, 0xc4, 0xe8, 0x92, + 0x5a, 0x20, 0x06, 0xfe, 0xe2, 0x2b, 0xe9, 0xb3, 0x9b, 0x70, 0x1a, 0xb9, + 0x53, 0x21, 0xad, 0xd7, 0x5f, 0xa1, 0xab, 0x26, 0x97, 0x17, 0x0b, 0xba, + 0xb0, 0x8b, 0x2d, 0xdb, 0x0c, 0x4e, 0xed, 0x75, 0x8b, 0x72, 0x46, 0xb0, + 0x6b, 0x23, 0x11, 0xba, 0x1e, 0x03 +]); + +// The distinguished name of the CA that issued clientCert1 in DER encoding. +var ca1DistinguishedNameDER = new Uint8Array([ + 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x04, 0x42, 0x20, 0x43, 0x41 +]); + +// A X.509 client certificate in DER encoding. +var clientCert2 = new Uint8Array([ + 0x30, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x10, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x0f, 0x31, 0x0d, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x04, 0x45, 0x20, 0x43, + 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x38, 0x31, 0x34, 0x30, + 0x32, 0x34, 0x36, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x38, + 0x31, 0x31, 0x30, 0x32, 0x34, 0x36, 0x33, 0x37, 0x5a, 0x30, 0x18, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0d, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x44, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe7, 0xb2, 0x44, 0x6e, + 0xf9, 0xef, 0x0a, 0x10, 0xd3, 0xeb, 0x66, 0x39, 0x09, 0x93, 0x96, 0x40, + 0x22, 0x3f, 0xe4, 0xbc, 0xfb, 0x89, 0xca, 0x55, 0x20, 0x71, 0x8e, 0x04, + 0x18, 0x82, 0xa4, 0x36, 0x18, 0x85, 0x26, 0x3f, 0x8b, 0x26, 0xc0, 0x44, + 0x02, 0x8b, 0x8c, 0xaf, 0xf7, 0xab, 0x72, 0x0a, 0x8f, 0x33, 0x42, 0x9f, + 0xf1, 0x4d, 0x12, 0x14, 0x61, 0x68, 0xb3, 0x54, 0x57, 0x72, 0x4b, 0xfc, + 0xc5, 0x61, 0xf6, 0xfc, 0x5a, 0x34, 0xce, 0x1f, 0x04, 0x1e, 0xf6, 0xe6, + 0x32, 0x94, 0xf7, 0x11, 0xe3, 0x80, 0xe4, 0x61, 0x06, 0xc2, 0x0c, 0x2c, + 0xa8, 0x24, 0x02, 0x9d, 0x1c, 0xc1, 0xe6, 0xe8, 0x0b, 0xf5, 0x43, 0x17, + 0x6c, 0x47, 0x59, 0x4a, 0x6f, 0x8d, 0x0f, 0x97, 0x4f, 0xac, 0x59, 0x13, + 0x02, 0xe9, 0x93, 0x02, 0xa2, 0x16, 0x15, 0x85, 0xda, 0x20, 0xb9, 0x87, + 0x3f, 0x18, 0x78, 0xca, 0xd6, 0xe0, 0x15, 0x55, 0xe5, 0x5b, 0xd2, 0x60, + 0x4d, 0xd5, 0x60, 0x24, 0xc8, 0xfc, 0xba, 0x3c, 0x4e, 0x07, 0xca, 0xee, + 0xa3, 0x7c, 0x32, 0xbf, 0x9a, 0xe2, 0xe2, 0x02, 0xe7, 0x87, 0x65, 0x77, + 0xfb, 0xca, 0x3d, 0xe0, 0x4e, 0x4a, 0x3f, 0xe3, 0xc6, 0x98, 0xa7, 0x56, + 0x3a, 0x17, 0x54, 0x42, 0xc5, 0xae, 0xaf, 0x05, 0xf4, 0x9b, 0xb8, 0x30, + 0xe6, 0xee, 0x3a, 0x1c, 0x31, 0x35, 0x4b, 0x73, 0xd6, 0xd3, 0x7c, 0x4c, + 0x52, 0x4d, 0x1f, 0xf8, 0x0f, 0x14, 0x97, 0xd9, 0xd5, 0xd7, 0x67, 0xd6, + 0xd7, 0xbb, 0xa5, 0x52, 0xe9, 0xd2, 0xad, 0x68, 0x8c, 0x61, 0x02, 0x95, + 0x8d, 0xb4, 0xe1, 0x37, 0x0c, 0x3f, 0x30, 0x64, 0x05, 0x4f, 0x76, 0x49, + 0x9c, 0x50, 0xdb, 0x76, 0xa5, 0xad, 0xd2, 0x2d, 0xb4, 0xc3, 0xd2, 0xd2, + 0xad, 0x0d, 0x64, 0x9a, 0xd6, 0xcf, 0x85, 0xba, 0x0c, 0x61, 0x00, 0xe3, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0xce, 0x8a, 0x6b, 0xa8, 0x70, 0x1a, 0xa3, 0xbb, 0x54, 0x2b, + 0x78, 0x29, 0x84, 0xb3, 0x08, 0xfa, 0x4f, 0x0a, 0x98, 0xcd, 0x10, 0x1e, + 0x04, 0x05, 0x2d, 0xe9, 0x0d, 0xd0, 0x84, 0xc1, 0x49, 0x21, 0x74, 0x30, + 0x2d, 0x7e, 0xfe, 0xec, 0x69, 0xa6, 0x6c, 0x5a, 0xa1, 0x7e, 0x17, 0xd1, + 0xb3, 0x84, 0x8c, 0xa0, 0xc1, 0x88, 0xc6, 0x45, 0xa6, 0x26, 0x82, 0xae, + 0xa6, 0x54, 0xed, 0xc2, 0x80, 0x49, 0xe2, 0xe1, 0x94, 0x06, 0x02, 0x42, + 0xbf, 0x8d, 0x9a, 0xc2, 0xbc, 0x0c, 0x1e, 0x4a, 0x02, 0x74, 0xb0, 0x7e, + 0x90, 0x04, 0x23, 0xc2, 0x12, 0x52, 0x14, 0xe8, 0xc5, 0xb2, 0xb8, 0xef, + 0x77, 0x7e, 0x6b, 0xac, 0xa0, 0xcc, 0x68, 0xa8, 0x02, 0x2d, 0xa6, 0x6a, + 0xd2, 0x17, 0x7f, 0xbd, 0x14, 0x21, 0x8b, 0xe3, 0x07, 0x02, 0xcd, 0x7f, + 0xe2, 0x01, 0x63, 0xfa, 0xe1, 0xfd, 0x9a, 0x43, 0xf9, 0x81, 0x52, 0x56, + 0x7f, 0xd2, 0x42, 0x71, 0xad, 0x90, 0xfe, 0xb4, 0xe3, 0xee, 0xf9, 0x76, + 0x14, 0x86, 0x4e, 0x4b, 0x9b, 0x7f, 0x94, 0x51, 0xc8, 0x5c, 0xce, 0x56, + 0x5d, 0xc5, 0xee, 0x2d, 0xb4, 0xe4, 0xd1, 0x15, 0xd8, 0x49, 0x59, 0x4f, + 0x12, 0xd8, 0x5e, 0xad, 0x8f, 0x9e, 0x50, 0xab, 0x61, 0x18, 0x0d, 0xdf, + 0xbc, 0x56, 0xf3, 0x75, 0x89, 0x1b, 0x0f, 0x19, 0xdf, 0x2d, 0x6e, 0x81, + 0x85, 0xdc, 0xc7, 0x28, 0x6a, 0x4b, 0x70, 0x6d, 0x85, 0x8c, 0x9d, 0x7d, + 0xe1, 0x5d, 0x62, 0xbb, 0x47, 0x18, 0xdc, 0xe8, 0x83, 0xc3, 0x27, 0xaf, + 0x5b, 0xec, 0x58, 0x07, 0x95, 0xe9, 0xe4, 0x9f, 0x94, 0xb4, 0x2a, 0x4a, + 0x67, 0xaa, 0xd7, 0x57, 0x37, 0x1b, 0x21, 0x07, 0x11, 0xd5, 0x4e, 0xca, + 0x1e, 0x72, 0x8c, 0x43, 0xfe, 0xcf, 0xb9, 0xea, 0x68, 0xea, 0x5d, 0xd7, + 0xd3, 0x32, 0xfb, 0x8a, 0x29, 0xf6 +]); + +// Some array comparison. Note: not lexicographical! +function compareArrays(array1, array2) { + if (array1.length < array2.length) + return -1; + if (array1.length > array2.length) + return 1; + for (var i = 0; i < array1.length; i++) { + if (array1[i] < array2[i]) + return -1; + if (array1[i] > array2[i]) + return 1; + } + return 0; +} + +/** + * @param {ArrayBufferView[]} certs + * @return {ArrayBufferView[]} |certs| sorted in some order. + */ +function sortCerts(certs) { + return certs.sort(compareArrays); +} + +function assertCertsSelected(request, expectedCerts, callback) { + chrome.platformKeys.selectClientCertificates( + {interactive: false, request: request}, + callbackPass(function(actualMatches) { + assertEq(expectedCerts.length, actualMatches.length, + 'Number of stored certs not as expected'); + if (expectedCerts.length == actualMatches.length) { + var actualCerts = actualMatches.map(function(match) { + return new Uint8Array(match.certificate); + }); + actualCerts = sortCerts(actualCerts); + expectedCerts = sortCerts(expectedCerts); + for (var i = 0; i < expectedCerts.length; i++) { + assertEq(expectedCerts[i], actualCerts[i], + 'Certs at index ' + i + ' differ'); + } + } + if (callback) + callback(); + })); +} + +function testStaticMethods() { + assertTrue(!!chrome.platformKeys, "No platformKeys namespace."); + assertTrue(!!chrome.platformKeys.selectClientCertificates, + "No selectClientCertificates function."); + succeed(); +} + +function testSelectAllCerts() { + var requestAll = { + certificateTypes: [], + certificateAuthorities: [] + }; + var expectedCerts = [clientCert1]; + if (systemTokenEnabled) + expectedCerts.push(clientCert2); + assertCertsSelected(requestAll, expectedCerts); +} + +function testSelectCA1Certs() { + var requestCA1 = { + certificateTypes: [], + certificateAuthorities: [ca1DistinguishedNameDER.buffer] + }; + assertCertsSelected(requestCA1, [clientCert1]); +} + +function runTests() { + var tests = [ + testStaticMethods, + testSelectAllCerts, + testSelectCA1Certs + ]; + + chrome.test.runTests(tests); +} + +runTests();
diff --git a/chrome/test/data/extensions/api_test/platform_keys/manifest.json b/chrome/test/data/extensions/api_test/platform_keys/manifest.json new file mode 100644 index 0000000..c392f9d --- /dev/null +++ b/chrome/test/data/extensions/api_test/platform_keys/manifest.json
@@ -0,0 +1,8 @@ +{ + "name": "Basic tests", + "version": "0.1", + "manifest_version": 2, + "permissions": [ + "platformKeys" + ] +}
diff --git a/chrome/test/data/predictor/dns_prefetch.html b/chrome/test/data/predictor/dns_prefetch.html new file mode 100644 index 0000000..ab2a63c00 --- /dev/null +++ b/chrome/test/data/predictor/dns_prefetch.html
@@ -0,0 +1 @@ +<link rel="dns-prefetch" href="http://chromium.org/">
diff --git a/chrome/test/data/webrtc/peerconnection.js b/chrome/test/data/webrtc/peerconnection.js index 96d3c8d..78d63cf 100644 --- a/chrome/test/data/webrtc/peerconnection.js +++ b/chrome/test/data/webrtc/peerconnection.js
@@ -57,7 +57,7 @@ success_('createOffer'); setLocalDescription(peerConnection, localOffer); - returnToTest('ok-' + JSON.stringify(localOffer)); + returnToTest('ok-' + stringifyDOMObject_(localOffer)); }, function(error) { failure_('createOffer', error); }, constraints); @@ -89,7 +89,7 @@ function(answer) { success_('createAnswer'); setLocalDescription(peerConnection, answer); - returnToTest('ok-' + JSON.stringify(answer)); + returnToTest('ok-' + stringifyDOMObject_(answer)); }, function(error) { failure_('createAnswer', error); }, constraints); @@ -178,7 +178,7 @@ return; } - returnToTest(JSON.stringify(gIceCandidates)); + returnToTest(stringifyDOMObject_(gIceCandidates)); } /** @@ -245,7 +245,7 @@ /** @private */ function failure_(method, error) { - throw failTest(method + '() failed: ' + JSON.stringify(error)); + throw failTest(method + '() failed: ' + stringifyDOMObject_(error)); } /** @private */ @@ -280,6 +280,28 @@ } /** + * Stringifies a DOM object. + * + * This function stringifies not only own properties but also DOM attributes + * which are on a prototype chain. Note that JSON.stringify only stringifies + * own properties. + * @private + */ +function stringifyDOMObject_(object) +{ + function deepCopy(src) { + if (typeof src != "object") + return src; + var dst = Array.isArray(src) ? [] : {}; + for (var property in src) { + dst[property] = deepCopy(src[property]); + } + return dst; + } + return JSON.stringify(deepCopy(object)); +} + +/** * Parses JSON-encoded session descriptions and ICE candidates. * @private */
diff --git a/chrome/test/data/webui/print_preview.js b/chrome/test/data/webui/print_preview.js index 3a5037ee..55425bb 100644 --- a/chrome/test/data/webui/print_preview.js +++ b/chrome/test/data/webui/print_preview.js
@@ -192,10 +192,10 @@ var noAnimationStyle = document.createElement('style'); noAnimationStyle.textContent = '* {' + - ' -webkit-transition-duration: 0s !important;' + - ' -webkit-transition-delay: 0s !important;' + - ' -webkit-animation-duration: 0s !important;' + - ' -webkit-animation-delay: 0s !important;' + + ' -webkit-transition-duration: 0ms !important;' + + ' -webkit-transition-delay: 0ms !important;' + + ' -webkit-animation-duration: 0ms !important;' + + ' -webkit-animation-delay: 0ms !important;' + '}'; document.querySelector('head').appendChild(noAnimationStyle); }
diff --git a/chrome/test/perf/perf_test.cc b/chrome/test/perf/perf_test.cc index d9c6556..f04ee2d 100644 --- a/chrome/test/perf/perf_test.cc +++ b/chrome/test/perf/perf_test.cc
@@ -7,6 +7,7 @@ #include <stdio.h> #include "base/logging.h" +#include "base/process/process.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "chrome/test/base/chrome_process_util.h" @@ -52,17 +53,17 @@ std::string output; ChromeProcessList::const_iterator it; for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) { - base::ProcessHandle process_handle; - if (!base::OpenProcessHandle(*it, &process_handle)) { + base::Process process = base::Process::Open(*it); + if (!process.IsValid()) { NOTREACHED(); return output; } // TODO(sgk): if/when base::ProcessMetrics returns real stats on mac: // scoped_ptr<base::ProcessMetrics> process_metrics( - // base::ProcessMetrics::CreateProcessMetrics(process_handle)); + // base::ProcessMetrics::CreateProcessMetrics(process.Handle())); scoped_ptr<ChromeTestProcessMetrics> process_metrics( - ChromeTestProcessMetrics::CreateProcessMetrics(process_handle)); + ChromeTestProcessMetrics::CreateProcessMetrics(process.Handle())); base::IoCounters io_counters; memset(&io_counters, 0, sizeof(io_counters)); @@ -109,8 +110,6 @@ total_byte_r += total_byte; } } - - base::CloseProcessHandle(process_handle); } std::string t_name(test_name); @@ -268,17 +267,17 @@ std::string output; ChromeProcessList::const_iterator it; for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) { - base::ProcessHandle process_handle; - if (!base::OpenProcessHandle(*it, &process_handle)) { + base::Process process = base::Process::Open(*it); + if (!process.IsValid()) { NOTREACHED(); return output; } // TODO(sgk): if/when base::ProcessMetrics returns real stats on mac: // scoped_ptr<base::ProcessMetrics> process_metrics( - // base::ProcessMetrics::CreateProcessMetrics(process_handle)); + // base::ProcessMetrics::CreateProcessMetrics(process.Handle())); scoped_ptr<ChromeTestProcessMetrics> process_metrics( - ChromeTestProcessMetrics::CreateProcessMetrics(process_handle)); + ChromeTestProcessMetrics::CreateProcessMetrics(process.Handle())); size_t current_virtual_size = process_metrics->GetPagefileUsage(); size_t current_working_set_size = process_metrics->GetWorkingSetSize(); @@ -310,8 +309,6 @@ renderer_total_peak_working_set_size += peak_working_set_size; } #endif - - base::CloseProcessHandle(process_handle); } std::string trace_name(test_name);
diff --git a/chrome/third_party/chromevox/chromevox/background/chrome_shared2.css b/chrome/third_party/chromevox/chromevox/background/chrome_shared2.css index 60c7d5a..701921a 100644 --- a/chrome/third_party/chromevox/chromevox/background/chrome_shared2.css +++ b/chrome/third_party/chromevox/chromevox/background/chrome_shared2.css
@@ -12,8 +12,8 @@ } html.loading * { - -webkit-transition-delay: 0 !important; - -webkit-transition-duration: 0 !important; + -webkit-transition-delay: 0ms !important; + -webkit-transition-duration: 0ms !important; } body {
diff --git a/chrome/unit_tests.isolate b/chrome/unit_tests.isolate index a03f8a5..3c12a334 100644 --- a/chrome/unit_tests.isolate +++ b/chrome/unit_tests.isolate
@@ -80,6 +80,13 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/unit_tests.dSYM/', + ], + }, + }], ['OS=="linux" or OS=="mac"', { 'variables': { 'read_only': 1,
diff --git a/chromecast/OWNERS b/chromecast/OWNERS index 45c91cca..470605e 100644 --- a/chromecast/OWNERS +++ b/chromecast/OWNERS
@@ -1,4 +1,3 @@ damienv@chromium.org gunsch@chromium.org -kolla@chromium.org lcwu@chromium.org
diff --git a/chromecast/browser/media/cma_message_filter_host.cc b/chromecast/browser/media/cma_message_filter_host.cc index ae80db1..246c034 100644 --- a/chromecast/browser/media/cma_message_filter_host.cc +++ b/chromecast/browser/media/cma_message_filter_host.cc
@@ -17,6 +17,7 @@ #include "chromecast/media/cma/pipeline/media_pipeline_client.h" #include "chromecast/media/cma/pipeline/video_pipeline_client.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" #include "media/base/bind_to_current_loop.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/quad_f.h" @@ -164,7 +165,32 @@ if (!media_pipeline) return; - FORWARD_CALL(media_pipeline, SetCdm, process_id_, render_frame_id, cdm_id); + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&CmaMessageFilterHost::SetCdmOnUiThread, + this, media_pipeline, render_frame_id, cdm_id)); +} + +void CmaMessageFilterHost::SetCdmOnUiThread( + MediaPipelineHost* media_pipeline, + int render_frame_id, + int cdm_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + content::RenderProcessHost* host = + content::RenderProcessHost::FromID(process_id_); + if (!host) { + LOG(ERROR) << "RenderProcessHost not alive for ID: " << process_id_; + return; + } + + ::media::BrowserCdm* cdm = host->GetBrowserCdm(render_frame_id, cdm_id); + if (!cdm) { + LOG(ERROR) << "Could not find BrowserCdm (" << render_frame_id << "," + << cdm_id << ")"; + return; + } + FORWARD_CALL(media_pipeline, SetCdm, cdm); } void CmaMessageFilterHost::CreateAvPipe(
diff --git a/chromecast/browser/media/cma_message_filter_host.h b/chromecast/browser/media/cma_message_filter_host.h index 763727c..d899c9f 100644 --- a/chromecast/browser/media/cma_message_filter_host.h +++ b/chromecast/browser/media/cma_message_filter_host.h
@@ -63,6 +63,9 @@ void CreateMedia(int media_id, LoadType load_type); void DestroyMedia(int media_id); void SetCdm(int media_id, int render_frame_id, int cdm_id); + void SetCdmOnUiThread(MediaPipelineHost* media_pipeline, + int render_frame_id, + int cdm_id); void CreateAvPipe(int media_id, TrackId track_id, size_t shared_mem_size); void OnAvPipeSet(int media_id, TrackId track_id,
diff --git a/chromecast/browser/media/media_pipeline_host.cc b/chromecast/browser/media/media_pipeline_host.cc index 2120e52..df28699d 100644 --- a/chromecast/browser/media/media_pipeline_host.cc +++ b/chromecast/browser/media/media_pipeline_host.cc
@@ -153,13 +153,9 @@ media_pipeline_->GetAudioPipeline()->SetVolume(volume); } -void MediaPipelineHost::SetCdm( - int render_process_id, int render_frame_id, int cdm_id) { +void MediaPipelineHost::SetCdm(::media::BrowserCdm* cdm) { DCHECK(thread_checker_.CalledOnValidThread()); - - // TODO(gunsch): crbug.com/444930. Find a way to get - // content::BrowserCdmManager since it is not under content/public/. - NOTIMPLEMENTED(); + media_pipeline_->SetCdm(cdm); } void MediaPipelineHost::NotifyPipeWrite(TrackId track_id) {
diff --git a/chromecast/browser/media/media_pipeline_host.h b/chromecast/browser/media/media_pipeline_host.h index ccbb7c6..32b9cdb 100644 --- a/chromecast/browser/media/media_pipeline_host.h +++ b/chromecast/browser/media/media_pipeline_host.h
@@ -24,6 +24,7 @@ namespace media { class AudioDecoderConfig; +class BrowserCdm; class VideoDecoderConfig; } @@ -60,7 +61,7 @@ void SetPlaybackRate(float playback_rate); void SetVolume(TrackId track_id, float playback_rate); - void SetCdm(int render_process_id, int render_frame_id, int cdm_id); + void SetCdm(::media::BrowserCdm* cdm); void NotifyPipeWrite(TrackId track_id);
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 6b7bad4e..5e5c3b8 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -34,7 +34,6 @@ "//third_party/icu", "//third_party/libxml", "//third_party/protobuf:protobuf_lite", - "//ui/gfx/geometry", "//url", ":cryptohome_proto", ":power_manager_proto", @@ -84,8 +83,6 @@ "login/auth/mock_auth_attempt_state_resolver.h", "login/auth/mock_auth_status_consumer.cc", "login/auth/mock_auth_status_consumer.h", - "login/auth/mock_authenticator.cc", - "login/auth/mock_authenticator.h", "login/auth/mock_url_fetchers.cc", "login/auth/mock_url_fetchers.h", "network/fake_network_device_handler.cc",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 89a4b21b..5e75479 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -6752.0.0 \ No newline at end of file +6767.0.0 \ No newline at end of file
diff --git a/chromeos/accelerometer/accelerometer_reader.cc b/chromeos/accelerometer/accelerometer_reader.cc index 4d68ebf0..19d78c89 100644 --- a/chromeos/accelerometer/accelerometer_reader.cc +++ b/chromeos/accelerometer/accelerometer_reader.cc
@@ -40,7 +40,7 @@ "scan_elements/in_accel_%s_%s_index"; // The names of the accelerometers. Matches up with the enum AccelerometerSource -// in ui/accelerometer/accelerometer_types.h. +// in chromeos/accelerometer/accelerometer_types.h. const char kAccelerometerNames[ACCELEROMETER_SOURCE_COUNT][5] = {"lid", "base"}; // The axes on each accelerometer. @@ -120,7 +120,7 @@ } // Adjust the directions of accelerometers to match the AccelerometerUpdate - // type specified in ui/accelerometer/accelerometer_types.h. + // type specified in chromeos/accelerometer/accelerometer_types.h. configuration->data.scale[ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f; for (int i = 0; i < 3; ++i) { configuration->data.scale[ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *=
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc index ce25eabf..c3e7c2d 100644 --- a/chromeos/audio/cras_audio_handler.cc +++ b/chromeos/audio/cras_audio_handler.cc
@@ -39,6 +39,14 @@ return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end(); } +bool IsNodeInTheList(uint64 node_id, const AudioNodeList& node_list) { + for (size_t i = 0; i < node_list.size(); ++i) { + if (node_id == node_list[i].id) + return true; + } + return false; +} + } // namespace CrasAudioHandler::AudioObserver::AudioObserver() { @@ -728,7 +736,8 @@ } bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, - bool is_input) { + bool is_input, + AudioNodeList* new_discovered) { size_t num_old_devices = 0; size_t num_new_devices = 0; for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); @@ -737,34 +746,41 @@ ++num_old_devices; } + bool new_or_changed_device = false; + new_discovered->clear(); for (AudioNodeList::const_iterator it = new_nodes.begin(); it != new_nodes.end(); ++it) { if (is_input == it->is_input) { ++num_new_devices; // Look to see if the new device not in the old device list. AudioDevice device(*it); - if (FoundNewOrChangedDevice(device)) - return true; + DeviceStatus status = CheckDeviceStatus(device); + if (status == NEW_DEVICE) + new_discovered->push_back(*it); + if (status == NEW_DEVICE || status == CHANGED_DEVICE) { + new_or_changed_device = true; + } } } - return num_old_devices != num_new_devices; + return new_or_changed_device || (num_old_devices != num_new_devices); } -bool CrasAudioHandler::FoundNewOrChangedDevice(const AudioDevice& device) { +CrasAudioHandler::DeviceStatus CrasAudioHandler::CheckDeviceStatus( + const AudioDevice& device) { const AudioDevice* device_found = GetDeviceFromId(device.id); if (!device_found) - return true; + return NEW_DEVICE; if (!IsSameAudioDevice(device, *device_found)) { LOG(WARNING) << "Different Audio devices with same id:" << " new device: " << device.ToString() << " old device: " << device_found->ToString(); - return true; + return CHANGED_DEVICE; } else if (device.active != device_found->active) { - return true; + return CHANGED_DEVICE; } - return false; + return OLD_DEVICE; } void CrasAudioHandler::NotifyActiveNodeChanged(bool is_input) { @@ -786,8 +802,12 @@ ++old_output_device_size; } - bool output_devices_changed = HasDeviceChange(nodes, false); - bool input_devices_changed = HasDeviceChange(nodes, true); + AudioNodeList hotplug_output_nodes; + AudioNodeList hotplug_input_nodes; + bool output_devices_changed = + HasDeviceChange(nodes, false, &hotplug_output_nodes); + bool input_devices_changed = + HasDeviceChange(nodes, true, &hotplug_input_nodes); audio_devices_.clear(); has_alternative_input_ = false; has_alternative_output_ = false; @@ -823,6 +843,13 @@ } } + // If the previous active device is removed from the new node list, + // reset active_output_node_id_. + if (!GetDeviceFromId(active_output_node_id_)) + active_output_node_id_ = 0; + if (!GetDeviceFromId(active_input_node_id_)) + active_input_node_id_ = 0; + // If audio nodes change is caused by unplugging some non-active audio // devices, the previously set active audio device will stay active. // Otherwise, switch to a new active audio device according to their priority. @@ -836,7 +863,14 @@ active_input_node_id_ = 0; NotifyActiveNodeChanged(true); } else { - SwitchToDevice(input_devices_pq_.top(), true); + // If user has hot plugged a new node, we should change to the active + // device to the new node if it has the highest priority; otherwise, + // we should keep the existing active node chosen by user. + // For all other cases, we will choose the node with highest priority. + if (!active_input_node_id_ || hotplug_input_nodes.empty() || + IsNodeInTheList(input_devices_pq_.top().id, hotplug_input_nodes)) { + SwitchToDevice(input_devices_pq_.top(), true); + } } } if (output_devices_changed && @@ -849,7 +883,11 @@ active_output_node_id_ = 0; NotifyActiveNodeChanged(false); } else { - SwitchToDevice(output_devices_pq_.top(), true); + // ditto input node case. + if (!active_output_node_id_ || hotplug_output_nodes.empty() || + IsNodeInTheList(output_devices_pq_.top().id, hotplug_output_nodes)) { + SwitchToDevice(output_devices_pq_.top(), true); + } } } }
diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h index e16161f0..28a858b9 100644 --- a/chromeos/audio/cras_audio_handler.h +++ b/chromeos/audio/cras_audio_handler.h
@@ -269,7 +269,10 @@ // Returns true if there is any device change for for input or output, // specified by |is_input|. - bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input); + // The new discovered nodes are returned in |new_discovered|. + bool HasDeviceChange(const AudioNodeList& new_nodes, + bool is_input, + AudioNodeList* new_discovered); // Handles dbus callback for GetNodes. void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); @@ -290,9 +293,15 @@ // Removes |node_id| from additional active nodes. void RemoveActiveNodeInternal(uint64 node_id, bool notify); - // Returns true if |device| is not found in audio_devices_, or it is found - // but changed its |active| property. - bool FoundNewOrChangedDevice(const AudioDevice& device); + enum DeviceStatus { + OLD_DEVICE, + NEW_DEVICE, + CHANGED_DEVICE, + }; + + // Checks if |device| is a newly discovered, changed, or existing device for + // the nodes sent from NodesChanged signal. + DeviceStatus CheckDeviceStatus(const AudioDevice& device); void NotifyActiveNodeChanged(bool is_input);
diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc index bc87b09..574b421ab 100644 --- a/chromeos/audio/cras_audio_handler_unittest.cc +++ b/chromeos/audio/cras_audio_handler_unittest.cc
@@ -2377,4 +2377,55 @@ EXPECT_EQ(1, test_observer_->active_input_node_changed_count()); } +// Test the case in which an HDMI output is plugged in with other higher +// priority +// output devices already plugged and user has manually selected an active +// output. +// The hotplug of hdmi output should not change user's selection of active +// device. +// crbug.com/447826. +TEST_F(CrasAudioHandlerTest, HotPlugHDMINotChangeActiveOutput) { + AudioNodeList audio_nodes; + AudioNode internal_speaker(kInternalSpeaker); + audio_nodes.push_back(internal_speaker); + AudioNode usb_headset(kUSBHeadphone1); + usb_headset.plugged_time = 80000000; + audio_nodes.push_back(usb_headset); + SetUpCrasAudioHandler(audio_nodes); + + // Verify the audio devices size. + AudioDeviceList audio_devices; + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(audio_nodes.size(), audio_devices.size()); + + // Verify the USB headset is selected as active output by default. + EXPECT_EQ(usb_headset.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); + + // Manually set the active output to internal speaker. + AudioDevice internal_output(kInternalSpeaker); + cras_audio_handler_->SwitchToDevice(internal_output, true); + + // Verify the active output is switched to internal speaker. + EXPECT_EQ(internal_speaker.id, + cras_audio_handler_->GetPrimaryActiveOutputNode()); + EXPECT_LT(kInternalSpeaker.plugged_time, usb_headset.plugged_time); + const AudioDevice* usb_device = GetDeviceFromId(usb_headset.id); + EXPECT_FALSE(usb_device->active); + + // Plug in HDMI output. + audio_nodes.clear(); + internal_speaker.active = true; + audio_nodes.push_back(internal_speaker); + usb_headset.active = false; + audio_nodes.push_back(usb_headset); + AudioNode hdmi(kHDMIOutput); + hdmi.plugged_time = 90000000; + audio_nodes.push_back(hdmi); + ChangeAudioNodes(audio_nodes); + + // The active output should not change. + EXPECT_EQ(kInternalSpeaker.id, + cras_audio_handler_->GetPrimaryActiveOutputNode()); +} + } // namespace chromeos
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 7175ebf..91efc3a 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp
@@ -294,6 +294,8 @@ 'login/auth/online_attempt.h', 'login/auth/online_attempt_host.cc', 'login/auth/online_attempt_host.h', + 'login/auth/stub_authenticator.cc', + 'login/auth/stub_authenticator.h', 'login/auth/test_attempt_state.cc', 'login/auth/test_attempt_state.h', 'login/auth/user_context.cc', @@ -522,7 +524,6 @@ '../third_party/icu/icu.gyp:icui18n', '../third_party/libxml/libxml.gyp:libxml', '../third_party/protobuf/protobuf.gyp:protobuf_lite', - '../ui/gfx/gfx.gyp:gfx_geometry', '../url/url.gyp:url_lib', 'cryptohome_proto', 'ime/input_method.gyp:gencode', @@ -578,8 +579,6 @@ 'login/auth/mock_auth_attempt_state_resolver.h', 'login/auth/mock_auth_status_consumer.cc', 'login/auth/mock_auth_status_consumer.h', - 'login/auth/mock_authenticator.cc', - 'login/auth/mock_authenticator.h', 'login/auth/mock_url_fetchers.cc', 'login/auth/mock_url_fetchers.h', 'network/fake_network_device_handler.cc',
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 5c019c9b..f2f5f038 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -116,7 +116,7 @@ const char kEnableNewKoreanIme[] = "enable-new-korean-ime"; // If this switch is set, the input view keyboard will be in materia design. -const char kEnableNewQPInputView[] = "enable-new-qp-input-view"; +const char kEnableNewMDInputView[] = "enable-new-md-input-view"; // If this switch is set, the options for suggestions as typing on physical // keyboard will be disabled.
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 23cb788..dfcece50 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -61,7 +61,8 @@ CHROMEOS_EXPORT extern const char kEnableKioskMode[]; CHROMEOS_EXPORT extern const char kEnableNetworkPortalNotification[]; CHROMEOS_EXPORT extern const char kEnableNewKoreanIme[]; -CHROMEOS_EXPORT extern const char kEnableNewQPInputView[]; +CHROMEOS_EXPORT extern const char kEnableNewMDInputView[]; +CHROMEOS_EXPORT extern const char kEnablePhysicalKeyboardAutocorrect[]; CHROMEOS_EXPORT extern const char kEnableRequestTabletSite[]; CHROMEOS_EXPORT extern const char kEnableScreenshotTestingWithMode[]; CHROMEOS_EXPORT extern const char kEnableTouchpadThreeFingerClick[];
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc b/chromeos/dbus/bluetooth_gatt_characteristic_client.cc index fc516d83..fda19ed 100644 --- a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc +++ b/chromeos/dbus/bluetooth_gatt_characteristic_client.cc
@@ -13,6 +13,13 @@ namespace chromeos { +namespace { + +// TODO(armansito): Move this constant to cros_system_api. +const char kValueProperty[] = "Value"; + +} // namespace + // static const char BluetoothGattCharacteristicClient::kNoResponseError[] = "org.chromium.Error.NoResponse"; @@ -27,6 +34,7 @@ : dbus::PropertySet(object_proxy, interface_name, callback) { RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty, &uuid); RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty, &service); + RegisterProperty(kValueProperty, &value); RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty, ¬ifying); RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty, &flags); @@ -210,21 +218,6 @@ VLOG(2) << "Remote GATT characteristic added: " << object_path.value(); FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_, GattCharacteristicAdded(object_path)); - - // Connect the "ValueUpdated" signal. - dbus::ObjectProxy* object_proxy = - object_manager_->GetObjectProxy(object_path); - DCHECK(object_proxy); - - object_proxy->ConnectToSignal( - bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, - bluetooth_gatt_characteristic::kValueUpdatedSignal, - base::Bind(&BluetoothGattCharacteristicClientImpl::ValueUpdatedReceived, - weak_ptr_factory_.GetWeakPtr(), - object_path), - base::Bind( - &BluetoothGattCharacteristicClientImpl::ValueUpdatedConnected, - weak_ptr_factory_.GetWeakPtr())); } // dbus::ObjectManager::Interface override. @@ -260,35 +253,6 @@ property_name)); } - // Called by dbus:: when a "ValueUpdated" signal is received. - void ValueUpdatedReceived(const dbus::ObjectPath& object_path, - dbus::Signal* signal) { - DCHECK(signal); - const uint8* bytes = NULL; - size_t length = 0; - dbus::MessageReader reader(signal); - if (!reader.PopArrayOfBytes(&bytes, &length)) { - LOG(WARNING) << "ValueUpdated signal has incorrect parameters: " - << signal->ToString(); - return; - } - - std::vector<uint8> value; - if (bytes) - value.assign(bytes, bytes + length); - - FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, - observers_, - GattCharacteristicValueUpdated(object_path, value)); - } - - // Called by dbus:: when the "ValueUpdated" signal is initially connected. - void ValueUpdatedConnected(const std::string& interface_name, - const std::string& signal_name, - bool success) { - LOG_IF(WARNING, !success) << "Failed to connect to the ValueUpdated signal"; - } - // Called when a response for successful method call is received. void OnSuccess(const base::Closure& callback, dbus::Response* response) { DCHECK(response);
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_client.h b/chromeos/dbus/bluetooth_gatt_characteristic_client.h index 651bd18..b040b56 100644 --- a/chromeos/dbus/bluetooth_gatt_characteristic_client.h +++ b/chromeos/dbus/bluetooth_gatt_characteristic_client.h
@@ -6,6 +6,7 @@ #define CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ #include <string> +#include <vector> #include "base/basictypes.h" #include "base/callback.h" @@ -29,6 +30,11 @@ // [read-only] dbus::Property<dbus::ObjectPath> service; + // The cached value of the characteristic. This property gets updated only + // after a successful read request and when a notification or indication is + // received. [read-only] + dbus::Property<std::vector<uint8_t>> value; + // Whether or not this characteristic is currently sending ValueUpdated // signals. [read-only] dbus::Property<bool> notifying; @@ -36,11 +42,11 @@ // List of flags representing the GATT "Characteristic Properties bit field" // and properties read from the GATT "Characteristic Extended Properties" // descriptor bit field. [read-only, optional] - dbus::Property<std::vector<std::string> > flags; + dbus::Property<std::vector<std::string>> flags; // Array of object paths representing the descriptors of this // characteristic. [read-only] - dbus::Property<std::vector<dbus::ObjectPath> > descriptors; + dbus::Property<std::vector<dbus::ObjectPath>> descriptors; Properties(dbus::ObjectProxy* object_proxy, const std::string& interface_name, @@ -67,13 +73,6 @@ virtual void GattCharacteristicPropertyChanged( const dbus::ObjectPath& object_path, const std::string& property_name) {} - - // Called when a "ValueUpdated" signal is received from the remote GATT - // characteristic with object path |object_path| with characteristic value - // |value|. - virtual void GattCharacteristicValueUpdated( - const dbus::ObjectPath& object_path, - const std::vector<uint8>& value) {} }; // Callbacks used to report the result of asynchronous methods.
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_client.cc b/chromeos/dbus/bluetooth_gatt_descriptor_client.cc index bb8c3f8..65bba57 100644 --- a/chromeos/dbus/bluetooth_gatt_descriptor_client.cc +++ b/chromeos/dbus/bluetooth_gatt_descriptor_client.cc
@@ -13,6 +13,13 @@ namespace chromeos { +namespace { + +// TODO(armansito): Move this constant to cros_system_api. +const char kValueProperty[] = "Value"; + +} // namespace + // static const char BluetoothGattDescriptorClient::kNoResponseError[] = "org.chromium.Error.NoResponse"; @@ -28,6 +35,7 @@ RegisterProperty(bluetooth_gatt_descriptor::kUUIDProperty, &uuid); RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty, &characteristic); + RegisterProperty(kValueProperty, &value); } BluetoothGattDescriptorClient::Properties::~Properties() {
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_client.h b/chromeos/dbus/bluetooth_gatt_descriptor_client.h index 0db53fe..15d3d9c34a 100644 --- a/chromeos/dbus/bluetooth_gatt_descriptor_client.h +++ b/chromeos/dbus/bluetooth_gatt_descriptor_client.h
@@ -6,6 +6,7 @@ #define CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ #include <string> +#include <vector> #include "base/basictypes.h" #include "base/callback.h" @@ -29,6 +30,10 @@ // [read-only] dbus::Property<dbus::ObjectPath> characteristic; + // The cached value of the descriptor. This property gets updated only after + // a successful read request. [read-only] + dbus::Property<std::vector<uint8_t>> value; + Properties(dbus::ObjectProxy* object_proxy, const std::string& interface_name, const PropertyChangedCallback& callback);
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc index ec04474..1f3a9bf 100644 --- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc +++ b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
@@ -176,14 +176,16 @@ } return; } + base::Closure completed_callback; if (!IsHeartRateVisible()) { completed_callback = base::Bind(error_callback, kUnknownCharacteristicError, ""); } else { - std::vector<uint8> value; - value.push_back(0x06); // Location is "foot". - completed_callback = base::Bind(callback, value); + std::vector<uint8> value = {0x06}; // Location is "foot". + completed_callback = base::Bind( + &FakeBluetoothGattCharacteristicClient::DelayedReadValueCallback, + weak_ptr_factory_.GetWeakPtr(), object_path, callback, value); } if (extra_requests_ > 0) { @@ -191,6 +193,7 @@ new DelayedCallback(completed_callback, extra_requests_); return; } + completed_callback.Run(); } @@ -488,12 +491,7 @@ VLOG(2) << "Updating heart rate value."; std::vector<uint8> measurement = GetHeartRateMeasurementValue(); - - FOR_EACH_OBSERVER( - BluetoothGattCharacteristicClient::Observer, - observers_, - GattCharacteristicValueUpdated( - dbus::ObjectPath(heart_rate_measurement_path_), measurement)); + heart_rate_measurement_properties_->value.ReplaceValue(measurement); base::MessageLoop::current()->PostDelayedTask( FROM_HERE, @@ -504,6 +502,17 @@ kHeartRateMeasurementNotificationIntervalMs)); } +void FakeBluetoothGattCharacteristicClient::DelayedReadValueCallback( + const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const std::vector<uint8_t>& value) { + Properties* properties = GetProperties(object_path); + DCHECK(properties); + + properties->value.ReplaceValue(value); + callback.Run(value); +} + std::vector<uint8> FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementValue() { // TODO(armansito): We should make sure to properly pack this struct to ensure
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h index f93bc74a1..3934a4c 100644 --- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h +++ b/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
@@ -128,6 +128,12 @@ // is a random value within a reasonable range. std::vector<uint8> GetHeartRateMeasurementValue(); + // Callback that executes a delayed ReadValue action by updating the + // appropriate "Value" property and invoking the ValueCallback. + void DelayedReadValueCallback(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const std::vector<uint8_t>& value); + // If true, characteristics of the Heart Rate Service are visible. Use // IsHeartRateVisible() to check the value. bool heart_rate_visible_;
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc index dd335ada..f1f30f53 100644 --- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc +++ b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
@@ -6,6 +6,8 @@ #include "base/bind.h" #include "base/logging.h" +#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { @@ -101,7 +103,25 @@ return; } - callback.Run(iter->second->value); + // Assign the value of the descriptor as necessary + Properties* properties = iter->second->properties.get(); + if (properties->uuid.value() == kClientCharacteristicConfigurationUUID) { + BluetoothGattCharacteristicClient::Properties* chrc_props = + DBusThreadManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->GetProperties(properties->characteristic.value()); + DCHECK(chrc_props); + + uint8_t value_byte = chrc_props->notifying.value() ? 0x01 : 0x00; + const std::vector<uint8_t>& cur_value = properties->value.value(); + + if (!cur_value.size() || cur_value[0] != value_byte) { + std::vector<uint8_t> value = {value_byte, 0x00}; + properties->value.ReplaceValue(value); + } + } + + callback.Run(iter->second->properties->value.value()); } void FakeBluetoothGattDescriptorClient::WriteValue( @@ -151,9 +171,6 @@ DescriptorData* data = new DescriptorData(); data->properties.reset(properties); - data->value.push_back(1); // Notifications enabled. - data->value.push_back(0); - properties_[object_path] = data; NotifyDescriptorAdded(object_path);
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h index c9ec82a..ce7cb67 100644 --- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h +++ b/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
@@ -82,7 +82,6 @@ ~DescriptorData(); scoped_ptr<Properties> properties; - std::vector<uint8> value; }; typedef std::map<dbus::ObjectPath, DescriptorData*> PropertiesMap; PropertiesMap properties_;
diff --git a/chromeos/login/auth/mock_authenticator.cc b/chromeos/login/auth/mock_authenticator.cc deleted file mode 100644 index fdd9429..0000000 --- a/chromeos/login/auth/mock_authenticator.cc +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/login/auth/mock_authenticator.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/logging.h" - -namespace chromeos { - -MockAuthenticator::MockAuthenticator(AuthStatusConsumer* consumer, - const UserContext& expected_user_context) - : Authenticator(consumer), - expected_user_context_(expected_user_context), - message_loop_(base::MessageLoopProxy::current()) { -} - -void MockAuthenticator::CompleteLogin(content::BrowserContext* ignored, - const UserContext& user_context) { - if (expected_user_context_ != user_context) - NOTREACHED(); - OnAuthSuccess(); -} - -void MockAuthenticator::AuthenticateToLogin(content::BrowserContext* ignored, - const UserContext& user_context) { - if (user_context == expected_user_context_) { - message_loop_->PostTask( - FROM_HERE, base::Bind(&MockAuthenticator::OnAuthSuccess, this)); - return; - } - GoogleServiceAuthError error( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); - message_loop_->PostTask( - FROM_HERE, - base::Bind(&MockAuthenticator::OnAuthFailure, - this, - AuthFailure::FromNetworkAuthFailure(error))); -} - -void MockAuthenticator::AuthenticateToUnlock(const UserContext& user_context) { - AuthenticateToLogin(NULL /* not used */, user_context); -} - -void MockAuthenticator::LoginAsSupervisedUser(const UserContext& user_context) { - UserContext new_user_context = user_context; - new_user_context.SetUserIDHash(user_context.GetUserID()); - consumer_->OnAuthSuccess(new_user_context); -} - -void MockAuthenticator::LoginOffTheRecord() { - consumer_->OnOffTheRecordAuthSuccess(); -} - -void MockAuthenticator::LoginAsPublicSession(const UserContext& user_context) { - UserContext logged_in_user_context = user_context; - logged_in_user_context.SetUserIDHash(logged_in_user_context.GetUserID()); - consumer_->OnAuthSuccess(logged_in_user_context); -} - -void MockAuthenticator::LoginAsKioskAccount(const std::string& app_user_id, - bool use_guest_mount) { - UserContext user_context(expected_user_context_.GetUserID()); - user_context.SetUserIDHash(expected_user_context_.GetUserID()); - consumer_->OnAuthSuccess(user_context); -} - -void MockAuthenticator::OnAuthSuccess() { - // If we want to be more like the real thing, we could save the user ID - // in AuthenticateToLogin, but there's not much of a point. - UserContext user_context(expected_user_context_); - user_context.SetUserIDHash(expected_user_context_.GetUserID()); - consumer_->OnAuthSuccess(user_context); -} - -void MockAuthenticator::OnAuthFailure(const AuthFailure& failure) { - consumer_->OnAuthFailure(failure); -} - -void MockAuthenticator::RecoverEncryptedData(const std::string& old_password) { -} - -void MockAuthenticator::ResyncEncryptedData() { -} - -void MockAuthenticator::SetExpectedCredentials( - const UserContext& user_context) { - expected_user_context_ = user_context; -} - -MockAuthenticator::~MockAuthenticator() { -} - -} // namespace chromeos
diff --git a/chromeos/login/auth/stub_authenticator.cc b/chromeos/login/auth/stub_authenticator.cc new file mode 100644 index 0000000..8a3e30f --- /dev/null +++ b/chromeos/login/auth/stub_authenticator.cc
@@ -0,0 +1,108 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/login/auth/stub_authenticator.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" + +namespace chromeos { + +namespace { + +// As defined in /chromeos/dbus/cryptohome_client.cc. +static const char kUserIdHashSuffix[] = "-hash"; + +} // anonymous namespace + +StubAuthenticator::StubAuthenticator(AuthStatusConsumer* consumer, + const UserContext& expected_user_context) + : Authenticator(consumer), + expected_user_context_(expected_user_context), + message_loop_(base::MessageLoopProxy::current()) { +} + +void StubAuthenticator::CompleteLogin(content::BrowserContext* context, + const UserContext& user_context) { + authentication_context_ = context; + if (expected_user_context_ != user_context) + NOTREACHED(); + OnAuthSuccess(); +} + +void StubAuthenticator::AuthenticateToLogin(content::BrowserContext* context, + const UserContext& user_context) { + authentication_context_ = context; + if (user_context == expected_user_context_) { + message_loop_->PostTask( + FROM_HERE, base::Bind(&StubAuthenticator::OnAuthSuccess, this)); + return; + } + GoogleServiceAuthError error( + GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); + message_loop_->PostTask( + FROM_HERE, base::Bind(&StubAuthenticator::OnAuthFailure, this, + AuthFailure::FromNetworkAuthFailure(error))); +} + +void StubAuthenticator::AuthenticateToUnlock(const UserContext& user_context) { + AuthenticateToLogin(NULL /* not used */, user_context); +} + +void StubAuthenticator::LoginAsSupervisedUser(const UserContext& user_context) { + UserContext new_user_context = user_context; + new_user_context.SetUserIDHash(user_context.GetUserID() + kUserIdHashSuffix); + consumer_->OnAuthSuccess(new_user_context); +} + +void StubAuthenticator::LoginOffTheRecord() { + consumer_->OnOffTheRecordAuthSuccess(); +} + +void StubAuthenticator::LoginAsPublicSession(const UserContext& user_context) { + UserContext logged_in_user_context = user_context; + logged_in_user_context.SetIsUsingOAuth(false); + logged_in_user_context.SetUserIDHash(logged_in_user_context.GetUserID() + + kUserIdHashSuffix); + consumer_->OnAuthSuccess(logged_in_user_context); +} + +void StubAuthenticator::LoginAsKioskAccount(const std::string& app_user_id, + bool use_guest_mount) { + UserContext user_context(expected_user_context_.GetUserID()); + user_context.SetIsUsingOAuth(false); + user_context.SetUserIDHash(expected_user_context_.GetUserID() + + kUserIdHashSuffix); + consumer_->OnAuthSuccess(user_context); +} + +void StubAuthenticator::OnAuthSuccess() { + // If we want to be more like the real thing, we could save the user ID + // in AuthenticateToLogin, but there's not much of a point. + UserContext user_context(expected_user_context_); + user_context.SetUserIDHash(expected_user_context_.GetUserID() + + kUserIdHashSuffix); + consumer_->OnAuthSuccess(user_context); +} + +void StubAuthenticator::OnAuthFailure(const AuthFailure& failure) { + consumer_->OnAuthFailure(failure); +} + +void StubAuthenticator::RecoverEncryptedData(const std::string& old_password) { +} + +void StubAuthenticator::ResyncEncryptedData() { +} + +void StubAuthenticator::SetExpectedCredentials( + const UserContext& user_context) { + expected_user_context_ = user_context; +} + +StubAuthenticator::~StubAuthenticator() { +} + +} // namespace chromeos
diff --git a/chromeos/login/auth/mock_authenticator.h b/chromeos/login/auth/stub_authenticator.h similarity index 80% rename from chromeos/login/auth/mock_authenticator.h rename to chromeos/login/auth/stub_authenticator.h index e36eb6cf..0fa11c4d 100644 --- a/chromeos/login/auth/mock_authenticator.h +++ b/chromeos/login/auth/stub_authenticator.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_LOGIN_AUTH_MOCK_AUTHENTICATOR_H_ -#define CHROMEOS_LOGIN_AUTH_MOCK_AUTHENTICATOR_H_ +#ifndef CHROMEOS_LOGIN_AUTH_STUB_AUTHENTICATOR_H_ +#define CHROMEOS_LOGIN_AUTH_STUB_AUTHENTICATOR_H_ #include <string> @@ -11,7 +11,6 @@ #include "chromeos/chromeos_export.h" #include "chromeos/login/auth/authenticator.h" #include "chromeos/login/auth/user_context.h" -#include "testing/gtest/include/gtest/gtest.h" namespace content { class BrowserContext; @@ -21,9 +20,9 @@ class AuthStatusConsumer; -class CHROMEOS_EXPORT MockAuthenticator : public Authenticator { +class CHROMEOS_EXPORT StubAuthenticator : public Authenticator { public: - MockAuthenticator(AuthStatusConsumer* consumer, + StubAuthenticator(AuthStatusConsumer* consumer, const UserContext& expected_user_context); // Authenticator: @@ -45,15 +44,15 @@ virtual void SetExpectedCredentials(const UserContext& user_context); protected: - ~MockAuthenticator() override; + ~StubAuthenticator() override; private: UserContext expected_user_context_; scoped_refptr<base::MessageLoopProxy> message_loop_; - DISALLOW_COPY_AND_ASSIGN(MockAuthenticator); + DISALLOW_COPY_AND_ASSIGN(StubAuthenticator); }; } // namespace chromeos -#endif // CHROMEOS_LOGIN_AUTH_MOCK_AUTHENTICATOR_H_ +#endif // CHROMEOS_LOGIN_AUTH_STUB_AUTHENTICATOR_H_
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 04669f79..be67c522 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -288,14 +288,6 @@ &onc::kNetworkConfigurationSignature, *user_settings_copy, &validation_result); - - // Fill in HexSSID field from contents of SSID field if not set already. - if (user_settings_copy) { - onc::FillInHexSSIDFieldsInOncObject( - onc::kNetworkConfigurationSignature, validated_user_settings.get()); - } - - if (validation_result == onc::Validator::INVALID) { InvokeErrorCallback(service_path, error_callback, kInvalidUserSettings); return; @@ -303,6 +295,12 @@ if (validation_result == onc::Validator::VALID_WITH_WARNINGS) LOG(WARNING) << "Validation of ONC user settings produced warnings."; + // Fill in HexSSID field from contents of SSID field if not set already. + if (user_settings_copy) { + onc::FillInHexSSIDFieldsInOncObject(onc::kNetworkConfigurationSignature, + validated_user_settings.get()); + } + const base::DictionaryValue* network_policy = GetByGUID(policies->per_network_config, guid); VLOG(2) << "This configuration is " << (network_policy ? "" : "not ")
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index ee889cff..1fc34f56 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -150,6 +150,10 @@ personal_data_(client->GetPersonalDataManager()), autocomplete_history_manager_( new AutocompleteHistoryManager(driver, client)), + address_form_event_logger_( + new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)), + credit_card_form_event_logger_( + new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)), has_logged_autofill_enabled_(false), has_logged_address_suggestions_count_(false), did_show_suggestions_(false), @@ -461,13 +465,28 @@ field, bounding_box, display_warning); + + // Need to refresh models before using the form_event_loggers. + bool is_autofill_possible = RefreshDataModels(); + FormStructure* form_structure = NULL; AutofillField* autofill_field = NULL; - if (RefreshDataModels() && - driver_->RendererIsAvailable() && + bool got_autofillable_form = GetCachedFormAndField(form, field, &form_structure, &autofill_field) && - // Don't send suggestions for forms that aren't auto-fillable. - form_structure->IsAutofillable()) { + // Don't send suggestions or track forms that aren't auto-fillable. + form_structure->IsAutofillable(); + + // Logging interactions of forms that are autofillable. + if (got_autofillable_form) { + if (autofill_field->Type().group() == CREDIT_CARD) + credit_card_form_event_logger_->OnDidInteractWithAutofillableForm(); + else + address_form_event_logger_->OnDidInteractWithAutofillableForm(); + } + + if (is_autofill_possible && + driver_->RendererIsAvailable() && + got_autofillable_form) { AutofillType type = autofill_field->Type(); bool is_filling_credit_card = (type.group() == CREDIT_CARD); if (is_filling_credit_card) { @@ -476,7 +495,6 @@ suggestions = GetProfileSuggestions(*form_structure, field, *autofill_field); } - if (!suggestions.empty()) { // Don't provide Autofill suggestions when Autofill is disabled, and don't // provide credit card suggestions for non-HTTPS pages. However, provide a @@ -831,6 +849,10 @@ void AutofillManager::Reset() { form_structures_.clear(); + address_form_event_logger_.reset( + new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)); + credit_card_form_event_logger_.reset( + new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)); has_logged_autofill_enabled_ = false; has_logged_address_suggestions_count_ = false; did_show_suggestions_ = false; @@ -856,6 +878,10 @@ personal_data_(personal_data), autocomplete_history_manager_( new AutocompleteHistoryManager(driver, client)), + address_form_event_logger_( + new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)), + credit_card_form_event_logger_( + new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)), has_logged_autofill_enabled_(false), has_logged_address_suggestions_count_(false), did_show_suggestions_(false), @@ -870,15 +896,48 @@ DCHECK(client_); } -bool AutofillManager::RefreshDataModels() const { +bool AutofillManager::RefreshDataModels() { if (!IsAutofillEnabled()) return false; // No autofill data to return if the profiles are empty. - if (personal_data_->GetProfiles().empty() && - personal_data_->GetCreditCards().empty()) { - return false; + const std::vector<AutofillProfile*>& profiles = + personal_data_->GetProfiles(); + const std::vector<CreditCard*>& credit_cards = + personal_data_->GetCreditCards(); + + // Updating the FormEventLoggers for addresses and credit cards. + { + bool is_server_data_available = false; + bool is_local_data_available = false; + for (CreditCard* credit_card : credit_cards) { + if (credit_card->record_type() == CreditCard::LOCAL_CARD) + is_local_data_available = true; + else + is_server_data_available = true; + } + credit_card_form_event_logger_->set_is_server_data_available( + is_server_data_available); + credit_card_form_event_logger_->set_is_local_data_available( + is_local_data_available); } + { + bool is_server_data_available = false; + bool is_local_data_available = false; + for (AutofillProfile* profile : profiles) { + if (profile->record_type() == AutofillProfile::LOCAL_PROFILE) + is_local_data_available = true; + else + is_server_data_available = true; + } + address_form_event_logger_->set_is_server_data_available( + is_server_data_available); + address_form_event_logger_->set_is_local_data_available( + is_local_data_available); + } + + if (profiles.empty() && credit_cards.empty()) + return false; return true; }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index eb61b56..442ebcc 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_download_manager.h" #include "components/autofill/core/browser/autofill_driver.h" +#include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/card_unmask_delegate.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -239,7 +240,7 @@ void OnDidGetRealPan(const std::string& real_pan) override; // Returns false if Autofill is disabled or if no Autofill data is available. - bool RefreshDataModels() const; + bool RefreshDataModels(); // Unpacks |unique_id| and fills |form_group| and |variant| with the // appropriate data source and variant index. Sets |is_credit_card| to true @@ -343,6 +344,10 @@ // Handles single-field autocomplete form data. scoped_ptr<AutocompleteHistoryManager> autocomplete_history_manager_; + // Utilities for logging form events. + scoped_ptr<AutofillMetrics::FormEventLogger> address_form_event_logger_; + scoped_ptr<AutofillMetrics::FormEventLogger> credit_card_form_event_logger_; + // Have we logged whether Autofill is enabled for this page load? bool has_logged_autofill_enabled_; // Have we logged an address suggestions count metric for this page?
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index 21ca9f8..32ecb840 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -465,4 +465,40 @@ UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions); } +AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card) + : is_for_credit_card_(is_for_credit_card), + is_server_data_available_(false), + is_local_data_available_(false), + has_logged_interacted_(false) {}; + +void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm() { + if (!has_logged_interacted_) { + has_logged_interacted_ = true; + Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE); + } +} + +void AutofillMetrics::FormEventLogger::Log(FormEvent event) const { + DCHECK_LT(event, NUM_FORM_EVENTS); + std::string name("Autofill.FormEvents."); + if (is_for_credit_card_) + name += "CreditCard"; + else + name += "Address"; + LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS); + + // Logging again in a different histogram for segmentation purposes. + // TODO(waltercacau): Re-evaluate if we still need such fine grained + // segmentation. http://crbug.com/454018 + if (!is_server_data_available_ && !is_local_data_available_) + name += ".WithNoData"; + else if (is_server_data_available_ && !is_local_data_available_) + name += ".WithOnlyServerData"; + else if (!is_server_data_available_ && is_local_data_available_) + name += ".WithOnlyLocalData"; + else + name += ".WithBothServerAndLocalData"; + LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h index 92539ba7..3780097 100644 --- a/components/autofill/core/browser/autofill_metrics.h +++ b/components/autofill/core/browser/autofill_metrics.h
@@ -243,6 +243,18 @@ NUM_USER_HAPPINESS_METRICS, }; + // Form Events for autofill. + // These events are triggered separetly for address and credit card forms. + enum FormEvent { + // User interacted with a field of this kind of form. Logged only once per + // page load. + FORM_EVENT_INTERACTED_ONCE = 0, + // TODO(waltercacau): Remove the 2 here once we add more events. + // This circumvents an assertion that gets triggered when you have + // only one bucket. + NUM_FORM_EVENTS = 2, + }; + // For measuring the network request time of various Wallet API calls. See // WalletClient::RequestType. enum WalletApiCallMetric { @@ -415,6 +427,35 @@ // form. static void LogAddressSuggestionsCount(size_t num_suggestions); + // Utility to autofill form events in the relevant histograms depending on + // the presence of server and/or local data. + class FormEventLogger { + public: + FormEventLogger(bool is_for_credit_card); + + // Should be called when the user interacted with an autofillable form. + void OnDidInteractWithAutofillableForm(); + + // Sets if server data is available or not. If not called assumed false. + inline void set_is_server_data_available(bool is_server_data_available) { + is_server_data_available_ = is_server_data_available; + } + + // Sets if server data is available or not. If not called assumed false. + inline void set_is_local_data_available(bool is_local_data_available) { + is_local_data_available_ = is_local_data_available; + } + + private: + // Logs a form event. + void Log(FormEvent event) const; + + bool is_for_credit_card_; + bool is_server_data_available_; + bool is_local_data_available_; + bool has_logged_interacted_; + }; + private: DISALLOW_IMPLICIT_CONSTRUCTORS(AutofillMetrics); };
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 426c1ef0..faf5e9d 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -6,6 +6,7 @@ #include <vector> +#include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "base/prefs/pref_service.h" #include "base/run_loop.h" @@ -20,6 +21,8 @@ #include "components/autofill/core/browser/test_autofill_client.h" #include "components/autofill/core/browser/test_autofill_driver.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/autofill/core/common/autofill_pref_names.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_field_data.h" #include "components/webdata/common/web_data_results.h" @@ -36,7 +39,8 @@ class TestPersonalDataManager : public PersonalDataManager { public: TestPersonalDataManager() - : PersonalDataManager("en-US"), autofill_enabled_(true) { + : PersonalDataManager("en-US"), + autofill_enabled_(true) { CreateTestAutofillProfiles(&web_profiles_); } @@ -46,21 +50,104 @@ // Overridden to avoid a trip to the database. This should be a no-op except // for the side-effect of logging the profile count. void LoadProfiles() override { - std::vector<AutofillProfile*> profiles; - web_profiles_.release(&profiles); - WDResult<std::vector<AutofillProfile*> > result(AUTOFILL_PROFILES_RESULT, - profiles); - pending_profiles_query_ = 123; - OnWebDataServiceRequestDone(pending_profiles_query_, &result); + { + std::vector<AutofillProfile*> profiles; + web_profiles_.release(&profiles); + WDResult<std::vector<AutofillProfile*> > result(AUTOFILL_PROFILES_RESULT, + profiles); + pending_profiles_query_ = 123; + OnWebDataServiceRequestDone(pending_profiles_query_, &result); + } + { + std::vector<AutofillProfile*> profiles; + server_profiles_.release(&profiles); + WDResult<std::vector<AutofillProfile*> > result(AUTOFILL_PROFILES_RESULT, + profiles); + pending_server_profiles_query_ = 124; + OnWebDataServiceRequestDone(pending_server_profiles_query_, &result); + } } // Overridden to avoid a trip to the database. - void LoadCreditCards() override {} + void LoadCreditCards() override { + { + std::vector<CreditCard*> credit_cards; + local_credit_cards_.release(&credit_cards); + WDResult<std::vector<CreditCard*> > result( + AUTOFILL_CREDITCARDS_RESULT, credit_cards); + pending_creditcards_query_ = 125; + OnWebDataServiceRequestDone(pending_creditcards_query_, &result); + } + { + std::vector<CreditCard*> credit_cards; + server_credit_cards_.release(&credit_cards); + WDResult<std::vector<CreditCard*> > result( + AUTOFILL_CREDITCARDS_RESULT, credit_cards); + pending_server_creditcards_query_ = 126; + OnWebDataServiceRequestDone(pending_server_creditcards_query_, &result); + } + } void set_autofill_enabled(bool autofill_enabled) { autofill_enabled_ = autofill_enabled; } + // Removes all existing profiles and creates 0 or 1 local profiles and 0 or 1 + // server profile according to the paramters. + void RecreateProfiles(bool include_local_profile, + bool include_server_profile) { + web_profiles_.clear(); + server_profiles_.clear(); + if (include_local_profile) { + AutofillProfile* profile = new AutofillProfile; + test::SetProfileInfo(profile, "Elvis", "Aaron", + "Presley", "theking@gmail.com", "RCA", + "3734 Elvis Presley Blvd.", "Apt. 10", + "Memphis", "Tennessee", "38116", "US", + "12345678901"); + profile->set_guid("00000000-0000-0000-0000-000000000001"); + web_profiles_.push_back(profile); + } + if (include_server_profile) { + AutofillProfile* profile = new AutofillProfile( + AutofillProfile::SERVER_PROFILE, "server_id"); + test::SetProfileInfo(profile, "Charles", "Hardin", + "Holley", "buddy@gmail.com", "Decca", + "123 Apple St.", "unit 6", "Lubbock", + "Texas", "79401", "US", "2345678901"); + profile->set_guid("00000000-0000-0000-0000-000000000002"); + server_profiles_.push_back(profile); + } + Refresh(); + } + + // Removes all existing credit cards and creates 0 or 1 local profiles and + // 0 or 1 server profile according to the paramters. + void RecreateCreditCards(bool include_local_credit_card, + bool include_masked_server_credit_card, + bool include_full_server_credit_card) { + local_credit_cards_.clear(); + server_credit_cards_.clear(); + if (include_local_credit_card) { + CreditCard* credit_card = new CreditCard; + credit_card->set_guid("10000000-0000-0000-0000-000000000001"); + local_credit_cards_.push_back(credit_card); + } + if (include_masked_server_credit_card) { + CreditCard* credit_card = new CreditCard( + CreditCard::MASKED_SERVER_CARD, "server_id"); + credit_card->set_guid("10000000-0000-0000-0000-000000000002"); + server_credit_cards_.push_back(credit_card); + } + if (include_full_server_credit_card) { + CreditCard* credit_card = new CreditCard( + CreditCard::FULL_SERVER_CARD, "server_id"); + credit_card->set_guid("10000000-0000-0000-0000-000000000003"); + server_credit_cards_.push_back(credit_card); + } + Refresh(); + } + bool IsAutofillEnabled() const override { return autofill_enabled_; } private: @@ -774,6 +861,314 @@ } } +// Test that we log interacted form event for credit cards only once. +TEST_F(AutofillMetricsTest, CreditCardInteractedOnce) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + FormFieldData field; + std::vector<ServerFieldType> field_types; + test::CreateTestFormField("Month", "card_month", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_EXP_MONTH); + test::CreateTestFormField("Year", "card_year", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); + test::CreateTestFormField("Credit card", "card", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_NUMBER); + + // Simulate having seen this form on page load. + // |form_structure| will be owned by |autofill_manager_|. + autofill_manager_->AddSeenForm(form, field_types, field_types); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + + { + // Simulate activating the autofill popup for the credit card field twice. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + autofill_manager_->OnQueryFormFieldAutofill(1, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } +} + +// Test that we log interacted form event for address only once. +TEST_F(AutofillMetricsTest, AddressInteractedOnce) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + FormFieldData field; + std::vector<ServerFieldType> field_types; + test::CreateTestFormField("State", "state", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_STATE); + test::CreateTestFormField("City", "city", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_CITY); + test::CreateTestFormField("Street", "street", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); + + // Simulate having seen this form on page load. + // |form_structure| will be owned by |autofill_manager_|. + autofill_manager_->AddSeenForm(form, field_types, field_types); + + { + // Simulate activating the autofill popup for the street field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + + { + // Simulate activating the autofill popup for the street field twice. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + autofill_manager_->OnQueryFormFieldAutofill(1, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } +} + +// Test that we log interacted form event for credit cards only once. +TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) { + // Enabling server card. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + ::autofill::switches::kEnableWalletCardImport); + autofill_client_.GetPrefs()->SetBoolean( + ::autofill::prefs::kAutofillWalletImportEnabled, true); + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + FormFieldData field; + std::vector<ServerFieldType> field_types; + test::CreateTestFormField("Month", "card_month", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_EXP_MONTH); + test::CreateTestFormField("Year", "card_year", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); + test::CreateTestFormField("Credit card", "card", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(CREDIT_CARD_NUMBER); + + // Simulate having seen this form on page load. + // |form_structure| will be owned by |autofill_manager_|. + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateCreditCards( + false /* include_local_credit_card */, + false /* include_masked_server_credit_card */, + false /* include_full_server_credit_card */); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard.WithNoData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateCreditCards( + true /* include_local_credit_card */, + false /* include_masked_server_credit_card */, + false /* include_full_server_credit_card */); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard.WithOnlyLocalData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateCreditCards( + false /* include_local_credit_card */, + true /* include_masked_server_credit_card */, + false /* include_full_server_credit_card */); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard.WithOnlyServerData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateCreditCards( + false /* include_local_credit_card */, + false /* include_masked_server_credit_card */, + true /* include_full_server_credit_card */); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard.WithOnlyServerData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateCreditCards( + true /* include_local_credit_card */, + false /* include_masked_server_credit_card */, + true /* include_full_server_credit_card */); + + { + // Simulate activating the autofill popup for the credit card field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.CreditCard.WithBothServerAndLocalData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } +} + +// Test that we log interacted form event for address only once. +TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + FormFieldData field; + std::vector<ServerFieldType> field_types; + test::CreateTestFormField("State", "state", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_STATE); + test::CreateTestFormField("City", "city", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_CITY); + test::CreateTestFormField("Street", "street", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); + + // Simulate having seen this form on page load. + // |form_structure| will be owned by |autofill_manager_|. + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateProfiles(false /* include_local_profile */, + false /* include_server_profile */); + + { + // Simulate activating the autofill popup for the street field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address.WithNoData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateProfiles(true /* include_local_profile */, + false /* include_server_profile */); + + { + // Simulate activating the autofill popup for the street field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address.WithOnlyLocalData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateProfiles(false /* include_local_profile */, + true /* include_server_profile */); + + { + // Simulate activating the autofill popup for the street field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address.WithOnlyServerData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } + + // Reset the autofill manager state. + autofill_manager_->Reset(); + autofill_manager_->AddSeenForm(form, field_types, field_types); + personal_data_->RecreateProfiles(true /* include_local_profile */, + true /* include_server_profile */); + + { + // Simulate activating the autofill popup for the street field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect(), + false); + histogram_tester.ExpectUniqueSample( + "Autofill.FormEvents.Address.WithBothServerAndLocalData", + AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); + } +} + + // Test that we log that Autofill is enabled when filling a form. TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { base::HistogramTester histogram_tester;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index fcc36877..131f3ae 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1203,21 +1203,26 @@ const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( bool record_metrics) const { #if defined(OS_MACOSX) && !defined(OS_IOS) - if (!pref_service_->GetBoolean(prefs::kAutofillUseMacAddressBook)) - return web_profiles(); + bool use_auxiliary_profiles = + pref_service_->GetBoolean(prefs::kAutofillUseMacAddressBook); #else - if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled)) - return web_profiles(); + bool use_auxiliary_profiles = + pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled); #endif // defined(OS_MACOSX) && !defined(OS_IOS) profiles_.clear(); // Populates |auxiliary_profiles_|. - LoadAuxiliaryProfiles(record_metrics); + if (use_auxiliary_profiles) + LoadAuxiliaryProfiles(record_metrics); - profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end()); - profiles_.insert( - profiles_.end(), auxiliary_profiles_.begin(), auxiliary_profiles_.end()); + profiles_.insert(profiles_.end(), web_profiles().begin(), + web_profiles().end()); + if (use_auxiliary_profiles) { + profiles_.insert( + profiles_.end(), auxiliary_profiles_.begin(), + auxiliary_profiles_.end()); + } profiles_.insert( profiles_.end(), server_profiles_.begin(), server_profiles_.end()); return profiles_;
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index 4ac72bb..0bedb64 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -23,6 +23,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/webdata/common/web_data_service_consumer.h" +class Browser; class PrefService; class RemoveAutofillTester; @@ -241,6 +242,8 @@ int, std::vector<autofill::AutofillProfile>*); friend void autofill_helper::SetCreditCards( int, std::vector<autofill::CreditCard>*); + friend void SetTestProfiles( + Browser* browser, std::vector<AutofillProfile>* profiles); // Sets |web_profiles_| to the contents of |profiles| and updates the web // database by adding, updating and removing profiles.
diff --git a/components/bookmarks/browser/bookmark_client.h b/components/bookmarks/browser/bookmark_client.h index b620b7be..3ea0269 100644 --- a/components/bookmarks/browser/bookmark_client.h +++ b/components/bookmarks/browser/bookmark_client.h
@@ -16,8 +16,6 @@ #include "components/favicon_base/favicon_types.h" #include "components/keyed_service/core/keyed_service.h" -class BookmarkNode; -class BookmarkPermanentNode; class GURL; namespace base { @@ -26,6 +24,9 @@ namespace bookmarks { +class BookmarkNode; +class BookmarkPermanentNode; + // This class abstracts operations that depends on the embedder's environment, // e.g. Chrome. class BookmarkClient : public KeyedService {
diff --git a/components/bookmarks/browser/bookmark_expanded_state_tracker.h b/components/bookmarks/browser/bookmark_expanded_state_tracker.h index 9efc1d0..a632226 100644 --- a/components/bookmarks/browser/bookmark_expanded_state_tracker.h +++ b/components/bookmarks/browser/bookmark_expanded_state_tracker.h
@@ -9,12 +9,12 @@ #include "components/bookmarks/browser/base_bookmark_model_observer.h" -class BookmarkNode; class PrefService; namespace bookmarks { class BookmarkModel; +class BookmarkNode; // BookmarkExpandedStateTracker is used to track a set of expanded nodes. The // nodes are persisted in preferences. If an expanded node is removed from the
diff --git a/components/bookmarks/browser/bookmark_index.h b/components/bookmarks/browser/bookmark_index.h index 4e07bf05..b639fbfb 100644 --- a/components/bookmarks/browser/bookmark_index.h +++ b/components/bookmarks/browser/bookmark_index.h
@@ -14,11 +14,10 @@ #include "base/strings/string16.h" #include "components/query_parser/query_parser.h" -class BookmarkNode; - namespace bookmarks { class BookmarkClient; +class BookmarkNode; struct BookmarkMatch; // BookmarkIndex maintains an index of the titles and URLs of bookmarks for
diff --git a/components/bookmarks/browser/bookmark_match.h b/components/bookmarks/browser/bookmark_match.h index 20d0bf49c..5bcab5e 100644 --- a/components/bookmarks/browser/bookmark_match.h +++ b/components/bookmarks/browser/bookmark_match.h
@@ -9,10 +9,10 @@ #include <utility> #include <vector> -class BookmarkNode; - namespace bookmarks { +class BookmarkNode; + struct BookmarkMatch { // Each MatchPosition is the [begin, end) positions of a match within a // string.
diff --git a/components/bookmarks/browser/bookmark_model_observer.h b/components/bookmarks/browser/bookmark_model_observer.h index 92d4db9b..a946d53 100644 --- a/components/bookmarks/browser/bookmark_model_observer.h +++ b/components/bookmarks/browser/bookmark_model_observer.h
@@ -7,12 +7,12 @@ #include <set> -class BookmarkNode; class GURL; namespace bookmarks { class BookmarkModel; +class BookmarkNode; // Observer for the BookmarkModel. class BookmarkModelObserver {
diff --git a/components/bookmarks/browser/bookmark_model_unittest.cc b/components/bookmarks/browser/bookmark_model_unittest.cc index 15dff7c2..1ee3554 100644 --- a/components/bookmarks/browser/bookmark_model_unittest.cc +++ b/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -265,7 +265,7 @@ BookmarkPermanentNode* ReloadModelWithExtraNode() { BookmarkPermanentNode* extra_node = new BookmarkPermanentNode(100); - bookmarks::BookmarkPermanentNodeList extra_nodes; + BookmarkPermanentNodeList extra_nodes; extra_nodes.push_back(extra_node); client_.SetExtraNodesToLoad(extra_nodes.Pass()); @@ -722,15 +722,14 @@ // Make sure folder is in the most recently modified. std::vector<const BookmarkNode*> most_recent_folders = - bookmarks::GetMostRecentlyModifiedUserFolders(model_.get(), 1); + GetMostRecentlyModifiedUserFolders(model_.get(), 1); ASSERT_EQ(1U, most_recent_folders.size()); ASSERT_EQ(folder, most_recent_folders[0]); // Nuke the folder and do another fetch, making sure folder isn't in the // returned list. model_->Remove(folder->parent(), 0); - most_recent_folders = - bookmarks::GetMostRecentlyModifiedUserFolders(model_.get(), 1); + most_recent_folders = GetMostRecentlyModifiedUserFolders(model_.get(), 1); ASSERT_EQ(1U, most_recent_folders.size()); ASSERT_TRUE(most_recent_folders[0] != folder); } @@ -763,7 +762,7 @@ // Make sure order is honored. std::vector<const BookmarkNode*> recently_added; - bookmarks::GetMostRecentlyAddedEntries(model_.get(), 2, &recently_added); + GetMostRecentlyAddedEntries(model_.get(), 2, &recently_added); ASSERT_EQ(2U, recently_added.size()); ASSERT_TRUE(n1 == recently_added[0]); ASSERT_TRUE(n2 == recently_added[1]); @@ -771,7 +770,7 @@ // swap 1 and 2, then check again. recently_added.clear(); SwapDateAdded(n1, n2); - bookmarks::GetMostRecentlyAddedEntries(model_.get(), 4, &recently_added); + GetMostRecentlyAddedEntries(model_.get(), 4, &recently_added); ASSERT_EQ(4U, recently_added.size()); ASSERT_TRUE(n2 == recently_added[0]); ASSERT_TRUE(n1 == recently_added[1]); @@ -1129,12 +1128,9 @@ EXPECT_TRUE(model_->IsBookmarked(GURL("http://youtube.com"))); EXPECT_FALSE(model_->IsBookmarked(GURL("http://reddit.com"))); - EXPECT_TRUE( - bookmarks::IsBookmarkedByUser(model_.get(), GURL("http://google.com"))); - EXPECT_FALSE( - bookmarks::IsBookmarkedByUser(model_.get(), GURL("http://youtube.com"))); - EXPECT_FALSE( - bookmarks::IsBookmarkedByUser(model_.get(), GURL("http://reddit.com"))); + EXPECT_TRUE(IsBookmarkedByUser(model_.get(), GURL("http://google.com"))); + EXPECT_FALSE(IsBookmarkedByUser(model_.get(), GURL("http://youtube.com"))); + EXPECT_FALSE(IsBookmarkedByUser(model_.get(), GURL("http://reddit.com"))); } // Verifies that GetMostRecentlyAddedUserNodeForURL skips bookmarks that
diff --git a/components/bookmarks/browser/bookmark_node.cc b/components/bookmarks/browser/bookmark_node.cc index cd9fe0e..f1a7945d 100644 --- a/components/bookmarks/browser/bookmark_node.cc +++ b/components/bookmarks/browser/bookmark_node.cc
@@ -10,6 +10,8 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +namespace bookmarks { + namespace { // Whitespace characters to strip from bookmark titles. @@ -133,3 +135,5 @@ bool BookmarkPermanentNode::IsVisible() const { return visible_ || !empty(); } + +} // namespace bookmarks
diff --git a/components/bookmarks/browser/bookmark_node.h b/components/bookmarks/browser/bookmark_node.h index fd3fd1a..3d24462 100644 --- a/components/bookmarks/browser/bookmark_node.h +++ b/components/bookmarks/browser/bookmark_node.h
@@ -14,8 +14,8 @@ #include "url/gurl.h" namespace bookmarks { + class BookmarkModel; -} // BookmarkNode --------------------------------------------------------------- @@ -117,7 +117,7 @@ // HistoryContentsProvider. private: - friend class bookmarks::BookmarkModel; + friend class BookmarkModel; // A helper function to initialize various fields during construction. void Initialize(int64 id); @@ -211,4 +211,6 @@ DISALLOW_COPY_AND_ASSIGN(BookmarkPermanentNode); }; +} // namespace bookmarks + #endif // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_NODE_H_
diff --git a/components/bookmarks/browser/bookmark_node_data_views.cc b/components/bookmarks/browser/bookmark_node_data_views.cc index 136d80ef..64cd1f6 100644 --- a/components/bookmarks/browser/bookmark_node_data_views.cc +++ b/components/bookmarks/browser/bookmark_node_data_views.cc
@@ -8,15 +8,10 @@ #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/clipboard/clipboard.h" +#include "url/url_constants.h" namespace bookmarks { -namespace { - -const char kJavaScriptScheme[] = "javascript"; - -} // namespace - // static const ui::OSExchangeData::CustomFormat& BookmarkNodeData::GetBookmarkCustomFormat() { @@ -35,7 +30,7 @@ // If there is only one element and it is a URL, write the URL to the // clipboard. if (has_single_url()) { - if (elements[0].url.SchemeIs(kJavaScriptScheme)) { + if (elements[0].url.SchemeIs(url::kJavaScriptScheme)) { data->SetString(base::UTF8ToUTF16(elements[0].url.spec())); } else { data->SetURL(elements[0].url, elements[0].title);
diff --git a/components/bookmarks/browser/bookmark_utils.h b/components/bookmarks/browser/bookmark_utils.h index c10bc08..67928ee 100644 --- a/components/bookmarks/browser/bookmark_utils.h +++ b/components/bookmarks/browser/bookmark_utils.h
@@ -12,7 +12,6 @@ #include "base/strings/utf_offset_string_conversions.h" #include "components/bookmarks/browser/bookmark_node_data.h" -class BookmarkNode; class GURL; namespace user_prefs { @@ -26,6 +25,7 @@ class BookmarkClient; class BookmarkModel; +class BookmarkNode; // Fields to use when finding matching bookmarks. struct QueryFields {
diff --git a/components/bookmarks/test/bookmark_test_helpers.h b/components/bookmarks/test/bookmark_test_helpers.h index aeffd425..d1230af 100644 --- a/components/bookmarks/test/bookmark_test_helpers.h +++ b/components/bookmarks/test/bookmark_test_helpers.h
@@ -7,10 +7,10 @@ #include <string> -class BookmarkNode; - namespace bookmarks { + class BookmarkModel; +class BookmarkNode; namespace test {
diff --git a/components/browser_watcher/exit_code_watcher_win_unittest.cc b/components/browser_watcher/exit_code_watcher_win_unittest.cc index a5ba3337..3e1728c 100644 --- a/components/browser_watcher/exit_code_watcher_win_unittest.cc +++ b/components/browser_watcher/exit_code_watcher_win_unittest.cc
@@ -77,10 +77,7 @@ static const int kExitCode = 0xCAFEBABE; - ExitCodeWatcherTest() : - cmd_line_(base::CommandLine::NO_PROGRAM), - process_(base::kNullProcessHandle) { - } + ExitCodeWatcherTest() : cmd_line_(base::CommandLine::NO_PROGRAM) {} virtual void SetUp() override { Super::SetUp(); @@ -88,15 +85,6 @@ override_manager_.OverrideRegistry(HKEY_CURRENT_USER); } - virtual void TearDown() override { - if (process_ != base::kNullProcessHandle) { - base::CloseProcessHandle(process_); - process_ = base::kNullProcessHandle; - } - - Super::TearDown(); - } - base::Process OpenSelfWithAccess(uint32 access) { return base::Process::OpenWithAccess(base::GetCurrentProcId(), access); } @@ -121,7 +109,6 @@ protected: base::CommandLine cmd_line_; - base::ProcessHandle process_; registry_util::RegistryOverrideManager override_manager_; };
diff --git a/components/browser_watcher/watcher_client_win_unittest.cc b/components/browser_watcher/watcher_client_win_unittest.cc index ca24e81..089fded 100644 --- a/components/browser_watcher/watcher_client_win_unittest.cc +++ b/components/browser_watcher/watcher_client_win_unittest.cc
@@ -10,8 +10,8 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" -#include "base/process/process_handle.h" #include "base/process/kill.h" +#include "base/process/process.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/test/multiprocess_test.h"
diff --git a/components/browser_watcher/watcher_metrics_provider_win.cc b/components/browser_watcher/watcher_metrics_provider_win.cc index 0848046..2798ae56 100644 --- a/components/browser_watcher/watcher_metrics_provider_win.cc +++ b/components/browser_watcher/watcher_metrics_provider_win.cc
@@ -8,7 +8,7 @@ #include <vector> #include "base/metrics/sparse_histogram.h" -#include "base/process/process_handle.h" +#include "base/process/process.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" @@ -51,10 +51,9 @@ // This is more expensive than the above check, but should also be very rare, // as this only happens more than once for a given PID if a user is running // multiple Chrome instances concurrently. - base::ProcessHandle process = base::kNullProcessHandle; - if (base::OpenProcessHandle(static_cast<base::ProcessId>(pid), &process)) { - base::CloseProcessHandle(process); - + base::Process process = + base::Process::Open(static_cast<base::ProcessId>(pid)); + if (process.IsValid()) { // The fact that it was possible to open the process says it's live. return false; }
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc index 4b97bae..4bfc2d7e 100644 --- a/components/component_updater/component_updater_service.cc +++ b/components/component_updater/component_updater_service.cc
@@ -100,6 +100,7 @@ Status Start() override; Status Stop() override; Status RegisterComponent(const CrxComponent& component) override; + Status UnregisterComponent(const std::string& crx_id) override; std::vector<std::string> GetComponentIDs() const override; OnDemandUpdater& GetOnDemandUpdater() override; void MaybeThrottle(const std::string& crx_id, @@ -108,7 +109,7 @@ // Context for a crx download url request. struct CRXContext { - ComponentInstaller* installer; + scoped_refptr<ComponentInstaller> installer; std::vector<uint8_t> pk_hash; std::string id; std::string fingerprint; @@ -154,6 +155,9 @@ void ProcessPendingItems(); + // Uninstall and remove all unregistered work items. + void UninstallUnregisteredItems(); + // Find a component that is ready to update. CrxUpdateItem* FindReadyComponent() const; @@ -432,6 +436,7 @@ CrxUpdateItem* uit = FindUpdateItemById(id); if (uit) { uit->component = component; + uit->unregistered = false; return kReplaced; } @@ -461,6 +466,19 @@ return kOk; } +ComponentUpdateService::Status CrxUpdateService::UnregisterComponent( + const std::string& crx_id) { + auto it = std::find_if(work_items_.begin(), work_items_.end(), + CrxUpdateItem::FindById(crx_id)); + if (it == work_items_.end()) + return kError; + + (*it)->unregistered = true; + + ScheduleNextRun(kStepDelayShort); + return kOk; +} + std::vector<std::string> CrxUpdateService::GetComponentIDs() const { DCHECK(thread_checker_.CalledOnValidThread()); std::vector<std::string> component_ids; @@ -492,7 +510,7 @@ scoped_refptr<base::SequencedTaskRunner> CrxUpdateService::GetSequencedTaskRunner() { - return config_->GetSequencedTaskRunner(); + return blocking_task_runner_; } bool CrxUpdateService::GetComponentDetails(const std::string& component_id, @@ -524,10 +542,26 @@ return; } + UninstallUnregisteredItems(); + if (!CheckForUpdates()) ScheduleNextRun(kStepDelayLong); } +void CrxUpdateService::UninstallUnregisteredItems() { + std::vector<CrxUpdateItem*> new_work_items; + for (CrxUpdateItem* item : work_items_) { + scoped_ptr<CrxUpdateItem> owned_item(item); + if (owned_item->unregistered) { + const bool success = owned_item->component.installer->Uninstall(); + DCHECK(success); + } else { + new_work_items.push_back(owned_item.release()); + } + } + new_work_items.swap(work_items_); +} + CrxUpdateItem* CrxUpdateService::FindReadyComponent() const { class Helper { public: @@ -781,6 +815,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); CrxUpdateItem* crx = FindUpdateItemById(crx_context->id); + DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || crx->status == CrxUpdateItem::kDownloading); @@ -895,6 +930,7 @@ const bool is_success = error == ComponentUnpacker::kNone; CrxUpdateItem* item = FindUpdateItemById(component_id); + if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) { item->diff_error_category = error_category; item->diff_error_code = error;
diff --git a/components/component_updater/component_updater_service.h b/components/component_updater/component_updater_service.h index 5670619..ac60a7f8 100644 --- a/components/component_updater/component_updater_service.h +++ b/components/component_updater/component_updater_service.h
@@ -124,6 +124,14 @@ virtual Status RegisterComponent( const update_client::CrxComponent& component) = 0; + // Unregisters the component with the given ID. This means that the component + // is not going to be included in future update checks. If a download or + // update operation for the component is currently in progress, it will + // silently finish without triggering the next step. + // Note that the installer for the component is responsible for removing any + // existing versions of the component from disk. + virtual Status UnregisterComponent(const std::string& crx_id) = 0; + // Returns a list of registered components. virtual std::vector<std::string> GetComponentIDs() const = 0;
diff --git a/components/component_updater/default_component_installer.cc b/components/component_updater/default_component_installer.cc index 65889732..027b1cbf 100644 --- a/components/component_updater/default_component_installer.cc +++ b/components/component_updater/default_component_installer.cc
@@ -17,16 +17,18 @@ #include "components/component_updater/component_updater_service.h" #include "components/component_updater/default_component_installer.h" #include "components/update_client/component_unpacker.h" -#include "components/update_client/update_client.h" +#include "components/update_client/utils.h" using update_client::CrxComponent; namespace component_updater { namespace { + // Version "0" corresponds to no installed version. By the server's conventions, // we represent it as a dotted quad. const char kNullVersion[] = "0.0.0.0"; + } // namespace ComponentInstallerTraits::~ComponentInstallerTraits() { @@ -40,7 +42,6 @@ } DefaultComponentInstaller::~DefaultComponentInstaller() { - DCHECK(thread_checker_.CalledOnValidThread()); } void DefaultComponentInstaller::Register(ComponentUpdateService* cus) { @@ -55,8 +56,7 @@ task_runner_->PostTask( FROM_HERE, base::Bind(&DefaultComponentInstaller::StartRegistration, - base::Unretained(this), - cus)); + this, cus)); } void DefaultComponentInstaller::OnUpdateError(int error) { @@ -78,6 +78,8 @@ bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, const base::FilePath& unpack_path) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + std::string manifest_version; manifest.GetStringASCII("version", &manifest_version); base::Version version(manifest_version.c_str()); @@ -103,11 +105,8 @@ current_manifest_->DeepCopy()); main_task_runner_->PostTask( FROM_HERE, - base::Bind(&ComponentInstallerTraits::ComponentReady, - base::Unretained(installer_traits_.get()), - current_version_, - GetInstallDirectory(), - base::Passed(&manifest_copy))); + base::Bind(&DefaultComponentInstaller::ComponentReady, + this, base::Passed(&manifest_copy))); return true; } @@ -123,6 +122,13 @@ return true; } +bool DefaultComponentInstaller::Uninstall() { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&DefaultComponentInstaller::UninstallOnTaskRunner, this)); + return true; +} + void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { DCHECK(task_runner_.get()); DCHECK(task_runner_->RunsTasksOnCurrentThread()); @@ -197,8 +203,34 @@ main_task_runner_->PostTask( FROM_HERE, base::Bind(&DefaultComponentInstaller::FinishRegistration, - base::Unretained(this), - cus)); + this, cus)); +} + +void DefaultComponentInstaller::UninstallOnTaskRunner() { + DCHECK(task_runner_.get()); + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + const base::FilePath base_dir = installer_traits_->GetBaseDirectory(); + + base::FileEnumerator file_enumerator(base_dir, false, + base::FileEnumerator::DIRECTORIES); + for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); + path = file_enumerator.Next()) { + base::Version version(path.BaseName().MaybeAsASCII()); + + // Ignore folders that don't have valid version names. These folders are not + // managed by the component installer, so do not try to remove them. + if (!version.IsValid()) + continue; + + if (!base::DeleteFile(path, true)) + DLOG(ERROR) << "Couldn't delete " << path.value(); + } + + // Delete the base directory if it's empty now. + if (base::IsDirectoryEmpty(base_dir)) { + if (base::DeleteFile(base_dir, false)) + DLOG(ERROR) << "Couldn't delete " << base_dir.value(); + } } base::FilePath DefaultComponentInstaller::GetInstallDirectory() { @@ -230,8 +262,13 @@ scoped_ptr<base::DictionaryValue> manifest_copy( current_manifest_->DeepCopy()); + ComponentReady(manifest_copy.Pass()); +} + +void DefaultComponentInstaller::ComponentReady( + scoped_ptr<base::DictionaryValue> manifest) { installer_traits_->ComponentReady( - current_version_, GetInstallDirectory(), manifest_copy.Pass()); + current_version_, GetInstallDirectory(), manifest.Pass()); } } // namespace component_updater
diff --git a/components/component_updater/default_component_installer.h b/components/component_updater/default_component_installer.h index 120d3a5..5815cd10 100644 --- a/components/component_updater/default_component_installer.h +++ b/components/component_updater/default_component_installer.h
@@ -98,16 +98,19 @@ const base::FilePath& unpack_path) override; bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; - - ~DefaultComponentInstaller() override; + bool Uninstall() override; private: + ~DefaultComponentInstaller() override; + base::FilePath GetInstallDirectory(); bool InstallHelper(const base::DictionaryValue& manifest, const base::FilePath& unpack_path, const base::FilePath& install_path); void StartRegistration(ComponentUpdateService* cus); void FinishRegistration(ComponentUpdateService* cus); + void ComponentReady(scoped_ptr<base::DictionaryValue> manifest); + void UninstallOnTaskRunner(); base::Version current_version_; std::string current_fingerprint_;
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 23261b15..64362f8 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -693,16 +693,13 @@ 'proximity_auth/wire_message_unittest.cc', ], 'dependencies': [ - # Dependencies for copresence. - 'components.gyp:copresence', - 'components.gyp:copresence_test_support', - - # Dependencies of proxmity_auth - 'components.gyp:proximity_auth', - 'components.gyp:cryptauth', '../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks', '../google_apis/google_apis.gyp:google_apis_test_support', '../third_party/protobuf/protobuf.gyp:protobuf_lite', + 'components.gyp:copresence', + 'components.gyp:copresence_test_support', + 'components.gyp:cryptauth', + 'components.gyp:proximity_auth', ], }], ['chromeos==1', { @@ -719,12 +716,10 @@ 'storage_monitor/storage_monitor_linux_unittest.cc', ], 'dependencies': [ - # Dependencies of wifi_sync - 'components.gyp:wifi_sync', - + '../chromeos/chromeos.gyp:chromeos_test_support', 'components.gyp:pairing', 'components.gyp:user_manager_test_support', - '../chromeos/chromeos.gyp:chromeos_test_support', + 'components.gyp:wifi_sync', ], }], ['OS=="linux"', { @@ -938,11 +933,6 @@ 'type': '<(gtest_target_type)', 'defines!': ['CONTENT_IMPLEMENTATION'], 'dependencies': [ - 'components.gyp:autofill_content_browser', - 'components.gyp:autofill_content_renderer', - 'components.gyp:password_manager_content_renderer', - 'components.gyp:pref_registry_test_support', - 'components_resources.gyp:components_resources', '../content/content.gyp:content_common', '../content/content.gyp:content_gpu', '../content/content.gyp:content_plugin', @@ -954,10 +944,13 @@ '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', - - # Dependencies of dom_distiller + 'components.gyp:autofill_content_browser', + 'components.gyp:autofill_content_renderer', 'components.gyp:dom_distiller_content', 'components.gyp:dom_distiller_core', + 'components.gyp:password_manager_content_renderer', + 'components.gyp:pref_registry_test_support', + 'components_resources.gyp:components_resources', 'components_strings.gyp:components_strings', ], 'include_dirs': [ @@ -1044,6 +1037,14 @@ '../content/content_shell_and_tests.gyp:content_shell', # Needed for Content Shell.app's Helper. ], }], + ['enable_basic_printing==1 or enable_print_preview==1', { + 'dependencies': [ + 'components.gyp:printing_test_support', + ], + 'sources' : [ + 'printing/test/print_web_view_helper_browsertest.cc', + ], + }] ], }, ],
diff --git a/components/copresence.gypi b/components/copresence.gypi index 12355e0d..8f77639 100644 --- a/components/copresence.gypi +++ b/components/copresence.gypi
@@ -13,6 +13,7 @@ '../media/media.gyp:media', '../media/media.gyp:shared_memory_support', '../net/net.gyp:net', + '../third_party/webrtc/common_audio/common_audio.gyp:common_audio', 'copresence_proto', ], 'include_dirs': [
diff --git a/components/copresence/BUILD.gn b/components/copresence/BUILD.gn index 74dd876..b518c79 100644 --- a/components/copresence/BUILD.gn +++ b/components/copresence/BUILD.gn
@@ -53,5 +53,6 @@ "//content", "//media", "//net", + "//third_party/webrtc/common_audio", ] }
diff --git a/components/copresence/DEPS b/components/copresence/DEPS index 959832a..96285fc 100644 --- a/components/copresence/DEPS +++ b/components/copresence/DEPS
@@ -6,5 +6,6 @@ "+google_apis", "+media", "+net", + "+third_party/webrtc/common_audio", "+url", ]
diff --git a/components/copresence/copresence_switches.cc b/components/copresence/copresence_switches.cc index f7a3bc7..96b0c00 100644 --- a/components/copresence/copresence_switches.cc +++ b/components/copresence/copresence_switches.cc
@@ -4,8 +4,23 @@ #include "components/copresence/copresence_switches.h" +// TODO(ckehoe): Move these flags to the chrome://copresence page. + namespace switches { +// Directory to dump encoded tokens to, for debugging. +// If empty (the default), tokens are not dumped. +// If invalid (not a writable directory), Chrome will crash! +const char kCopresenceDumpTokensToDir[] = "copresence-dump-tokens-to-dir"; + +// Allow broadcast of audible audio tokens. Defaults to true. +const char kCopresenceEnableAudibleBroadcast[] = + "copresence-enable-audible-broadcast"; + +// Allow broadcast of inaudible audio tokens. Defaults to true. +const char kCopresenceEnableInaudibleBroadcast[] = + "copresence-enable-inaudible-broadcast"; + // Address for calls to the Copresence server (via Apiary). // Defaults to https://www.googleapis.com/copresence/v2/copresence. const char kCopresenceServer[] = "copresence-server";
diff --git a/components/copresence/copresence_switches.h b/components/copresence/copresence_switches.h index d60a589f..0934f20 100644 --- a/components/copresence/copresence_switches.h +++ b/components/copresence/copresence_switches.h
@@ -9,6 +9,9 @@ // All switches in alphabetical order. The switches should be documented // alongside the definition of their values in the .cc file. +extern const char kCopresenceDumpTokensToDir[]; +extern const char kCopresenceEnableAudibleBroadcast[]; +extern const char kCopresenceEnableInaudibleBroadcast[]; extern const char kCopresenceServer[]; extern const char kCopresenceTracingToken[];
diff --git a/components/copresence/mediums/audio/audio_manager_impl.cc b/components/copresence/mediums/audio/audio_manager_impl.cc index 387eb54..d1cd7d9 100644 --- a/components/copresence/mediums/audio/audio_manager_impl.cc +++ b/components/copresence/mediums/audio/audio_manager_impl.cc
@@ -5,14 +5,19 @@ #include "components/copresence/mediums/audio/audio_manager_impl.h" #include <algorithm> +#include <limits> #include <vector> #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/logging.h" #include "base/run_loop.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/strings/sys_string_conversions.h" #include "base/time/time.h" +#include "components/copresence/copresence_switches.h" #include "components/copresence/mediums/audio/audio_player_impl.h" #include "components/copresence/mediums/audio/audio_recorder_impl.h" #include "components/copresence/public/copresence_constants.h" @@ -21,27 +26,59 @@ #include "media/audio/audio_manager.h" #include "media/audio/audio_manager_base.h" #include "media/base/audio_bus.h" +#include "third_party/webrtc/common_audio/wav_file.h" namespace copresence { namespace { +const int kSampleExpiryTimeMs = 60 * 60 * 1000; // 60 minutes. +const int kMaxSamples = 10000; +const int kTokenTimeoutMs = 2000; +const int kMonoChannelCount = 1; + // UrlSafe is defined as: // '/' represented by a '_' and '+' represented by a '-' -// TODO(rkc): Move this processing to the whispernet wrapper. +// TODO(ckehoe): Move this to a central place. std::string FromUrlSafe(std::string token) { base::ReplaceChars(token, "-", "+", &token); base::ReplaceChars(token, "_", "/", &token); return token; } +std::string ToUrlSafe(std::string token) { + base::ReplaceChars(token, "+", "-", &token); + base::ReplaceChars(token, "/", "_", &token); + return token; +} -const int kSampleExpiryTimeMs = 60 * 60 * 1000; // 60 minutes. -const int kMaxSamples = 10000; -const int kTokenTimeoutMs = 2000; +// TODO(ckehoe): Move this to a central place. +std::string AudioTypeToString(AudioType audio_type) { + if (audio_type == AUDIBLE) + return "audible"; + if (audio_type == INAUDIBLE) + return "inaudible"; + + NOTREACHED() << "Got unexpected token type " << audio_type; + return std::string(); +} + +bool ReadBooleanFlag(const std::string& flag, bool default_value) { + const std::string flag_value = base::StringToLowerASCII( + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(flag)); + if (flag_value == "true" || flag_value == "1") + return true; + if (flag_value == "false" || flag_value == "0") + return false; + LOG_IF(ERROR, !flag_value.empty()) + << "Unrecognized value \"" << flag_value << " for flag " + << flag << ". Defaulting to " << default_value; + return default_value; +} } // namespace -// Public methods. + +// Public functions. AudioManagerImpl::AudioManagerImpl() : whispernet_client_(nullptr), recorder_(nullptr) { @@ -51,6 +88,10 @@ should_be_recording_[AUDIBLE] = false; should_be_recording_[INAUDIBLE] = false; + player_enabled_[AUDIBLE] = ReadBooleanFlag( + switches::kCopresenceEnableAudibleBroadcast, true); + player_enabled_[INAUDIBLE] = ReadBooleanFlag( + switches::kCopresenceEnableInaudibleBroadcast, true); player_[AUDIBLE] = nullptr; player_[INAUDIBLE] = nullptr; token_length_[0] = 0; @@ -88,6 +129,9 @@ if (!recorder_) recorder_ = new AudioRecorderImpl(); recorder_->Initialize(decode_cancelable_cb_.callback()); + + dump_tokens_dir_ = base::FilePath(base::CommandLine::ForCurrentProcess() + ->GetSwitchValueNative(switches::kCopresenceDumpTokensToDir)); } AudioManagerImpl::~AudioManagerImpl() { @@ -113,10 +157,16 @@ // will call this code again (if we're still supposed to be playing). if (samples_cache_[type]->HasKey(playing_token_[type])) { DCHECK(!playing_token_[type].empty()); - started_playing_[type] = base::Time::Now(); - player_[type]->Play(samples_cache_[type]->GetValue(playing_token_[type])); - // If we're playing, we always record to hear what we are playing. - recorder_->Record(); + if (player_enabled_[type]) { + started_playing_[type] = base::Time::Now(); + player_[type]->Play(samples_cache_[type]->GetValue(playing_token_[type])); + + // If we're playing, we always record to hear what we are playing. + recorder_->Record(); + } else { + DVLOG(3) << "Skipping playback for disabled " << AudioTypeToString(type) + << " player."; + } } } @@ -173,13 +223,15 @@ token_length_[type] = token_length; } -// Private methods. + +// Private functions. void AudioManagerImpl::OnTokenEncoded( AudioType type, const std::string& token, const scoped_refptr<media::AudioBusRefCounted>& samples) { samples_cache_[type]->Add(token, samples); + DumpToken(type, token, samples.get()); UpdateToken(type, token); } @@ -222,11 +274,8 @@ // in the cache. DCHECK(samples_cache_[type]->HasKey(playing_token_[type])); - started_playing_[type] = base::Time::Now(); player_[type]->Stop(); - player_[type]->Play(samples_cache_[type]->GetValue(playing_token_[type])); - // If we're playing, we always record to hear what we are playing. - recorder_->Record(); + StartPlaying(type); } void AudioManagerImpl::DecodeSamplesConnector(const std::string& samples) { @@ -250,4 +299,37 @@ } } +void AudioManagerImpl::DumpToken(AudioType audio_type, + const std::string& token, + const media::AudioBus* samples) { + if (dump_tokens_dir_.empty()) + return; + + // Convert the samples to 16-bit integers. + std::vector<int16_t> int_samples; + int_samples.reserve(samples->frames()); + for (int i = 0; i < samples->frames(); i++) { + int_samples.push_back(round( + samples->channel(0)[i] * std::numeric_limits<int16_t>::max())); + } + DCHECK_EQ(static_cast<int>(int_samples.size()), samples->frames()); + DCHECK_EQ(kMonoChannelCount, samples->channels()); + + const std::string filename = base::StringPrintf("%s %s.wav", + AudioTypeToString(audio_type).c_str(), ToUrlSafe(token).c_str()); + DVLOG(3) << "Dumping token " << filename; + + std::string file_str; +#if defined(OS_WIN) + base::FilePath file_path = dump_tokens_dir_.Append( + base::SysNativeMBToWide(filename)); + file_str = base::SysWideToNativeMB(file_path.value()); +#else + file_str = dump_tokens_dir_.Append(filename).value(); +#endif + + webrtc::WavWriter writer(file_str, kDefaultSampleRate, kMonoChannelCount); + writer.WriteSamples(int_samples.data(), int_samples.size()); +} + } // namespace copresence
diff --git a/components/copresence/mediums/audio/audio_manager_impl.h b/components/copresence/mediums/audio/audio_manager_impl.h index 8148de6a..b660a7a9 100644 --- a/components/copresence/mediums/audio/audio_manager_impl.h +++ b/components/copresence/mediums/audio/audio_manager_impl.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/cancelable_callback.h" +#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" @@ -21,6 +22,10 @@ class Time; } +namespace media { +class AudioBus; +} + namespace copresence { class AudioPlayer; @@ -76,6 +81,10 @@ void DecodeSamplesConnector(const std::string& samples); + void DumpToken(AudioType audio_type, + const std::string& token, + const media::AudioBus* samples); + WhispernetClient* whispernet_client_; // Callbacks to send tokens back to the CopresenceManager. @@ -91,6 +100,7 @@ static_assert(INAUDIBLE == 1, "AudioType::INAUDIBLE should be 1."); // Indexed using enum AudioType. + bool player_enabled_[2]; bool should_be_playing_[2]; bool should_be_recording_[2]; @@ -102,6 +112,7 @@ // Indexed using enum AudioType. std::string playing_token_[2]; + size_t token_length_[2]; base::Time started_playing_[2]; base::Time heard_own_token_[2]; @@ -110,7 +121,7 @@ // Indexed using enum AudioType. ScopedVector<SamplesMap> samples_cache_; - size_t token_length_[2]; + base::FilePath dump_tokens_dir_; DISALLOW_COPY_AND_ASSIGN(AudioManagerImpl); };
diff --git a/components/copresence/mediums/audio/audio_manager_unittest.cc b/components/copresence/mediums/audio/audio_manager_unittest.cc index b30a1f5..1e541be0 100644 --- a/components/copresence/mediums/audio/audio_manager_unittest.cc +++ b/components/copresence/mediums/audio/audio_manager_unittest.cc
@@ -4,11 +4,14 @@ #include "components/copresence/mediums/audio/audio_manager.h" +#include <vector> + #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "components/copresence/mediums/audio/audio_manager_impl.h" #include "components/copresence/mediums/audio/audio_player.h" #include "components/copresence/mediums/audio/audio_recorder.h" +#include "components/copresence/test/audio_test_support.h" #include "components/copresence/test/stub_whispernet_client.h" #include "media/base/audio_bus.h" #include "testing/gtest/include/gtest/gtest.h" @@ -63,12 +66,17 @@ class AudioManagerTest : public testing::Test { public: AudioManagerTest() - : whispernet_client_(new StubWhispernetClient), - audio_manager_(new AudioManagerImpl()), + : audio_manager_(new AudioManagerImpl()), audible_player_(new AudioPlayerStub), inaudible_player_(new AudioPlayerStub), recorder_(new AudioRecorderStub), last_received_decode_type_(AUDIO_TYPE_UNKNOWN) { + std::vector<AudioToken> tokens; + tokens.push_back(AudioToken("abcdef", true)); + tokens.push_back(AudioToken("123456", false)); + whispernet_client_.reset(new StubWhispernetClient( + CreateRandomAudioRefCounted(0x123, 1, 0x321), tokens)); + audio_manager_->set_player_for_testing(AUDIBLE, audible_player_); audio_manager_->set_player_for_testing(INAUDIBLE, inaudible_player_); audio_manager_->set_recorder_for_testing(recorder_);
diff --git a/components/copresence/test/audio_test_support.cc b/components/copresence/test/audio_test_support.cc index b191311..5dd8966 100644 --- a/components/copresence/test/audio_test_support.cc +++ b/components/copresence/test/audio_test_support.cc
@@ -10,19 +10,15 @@ namespace copresence { -void PopulateSamples(int random_seed, size_t size, float* samples) { +void PopulateSamples(unsigned int random_seed, size_t size, float* samples) { +#if defined(OS_WIN) srand(random_seed); for (size_t i = 0; i < size; ++i) samples[i] = (2.0 * rand() / RAND_MAX) - 1; -} - -scoped_ptr<media::AudioBus> CreateRandomAudio(int random_seed, - int channels, - int samples) { - scoped_ptr<media::AudioBus> bus = media::AudioBus::Create(channels, samples); - for (int ch = 0; ch < channels; ++ch) - PopulateSamples(random_seed, samples, bus->channel(ch)); - return bus.Pass(); +#else + for (size_t i = 0; i < size; ++i) + samples[i] = (2.0 * rand_r(&random_seed) / RAND_MAX) - 1; +#endif } scoped_refptr<media::AudioBusRefCounted>
diff --git a/components/copresence/test/audio_test_support.h b/components/copresence/test/audio_test_support.h index 0c66dcf..baae22d 100644 --- a/components/copresence/test/audio_test_support.h +++ b/components/copresence/test/audio_test_support.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_ -#define COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_ +#ifndef COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_H_ +#define COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_H_ #include <cstddef> @@ -18,12 +18,7 @@ namespace copresence { // Populate random samples given a random seed into the samples array. -void PopulateSamples(int random_seed, size_t size, float* samples); - -// Create an audio bus populated with random samples. -scoped_ptr<media::AudioBus> CreateRandomAudio(int random_seed, - int channels, - int samples); +void PopulateSamples(unsigned int random_seed, size_t size, float* samples); // Create an ref counted audio bus populated with random samples. scoped_refptr<media::AudioBusRefCounted> @@ -31,4 +26,4 @@ } // namespace copresence -#endif // COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_ +#endif // COMPONENTS_COPRESENCE_TEST_AUDIO_TEST_SUPPORT_H_
diff --git a/components/copresence/test/stub_whispernet_client.cc b/components/copresence/test/stub_whispernet_client.cc index e82dd59..d0768a5 100644 --- a/components/copresence/test/stub_whispernet_client.cc +++ b/components/copresence/test/stub_whispernet_client.cc
@@ -4,26 +4,18 @@ #include "components/copresence/test/stub_whispernet_client.h" -#include "components/copresence/test/audio_test_support.h" -#include "media/base/audio_bus.h" - namespace copresence { -StubWhispernetClient::StubWhispernetClient(bool complete_initialization) - : complete_initialization_(complete_initialization) { - tokens_.push_back(AudioToken("abcdef", true)); - tokens_.push_back(AudioToken("123456", false)); - samples_ = CreateRandomAudioRefCounted(0x123, 1, 0x321); +StubWhispernetClient::StubWhispernetClient( + scoped_refptr<media::AudioBusRefCounted> samples, + const std::vector<AudioToken>& tokens) + : samples_(samples), + tokens_(tokens) { } -StubWhispernetClient::~StubWhispernetClient() { -} +StubWhispernetClient::~StubWhispernetClient() {} -void StubWhispernetClient::Initialize(const SuccessCallback& init_callback) { - // TODO(ckehoe): Consider updating tests to use this. - if (complete_initialization_) - init_callback.Run(true); -} +void StubWhispernetClient::Initialize(const SuccessCallback& init_callback) {} void StubWhispernetClient::EncodeToken(const std::string& token, AudioType type) {
diff --git a/components/copresence/test/stub_whispernet_client.h b/components/copresence/test/stub_whispernet_client.h index 33d4fc1..2356896 100644 --- a/components/copresence/test/stub_whispernet_client.h +++ b/components/copresence/test/stub_whispernet_client.h
@@ -10,16 +10,22 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "components/copresence/public/whispernet_client.h" +#include "components/copresence/tokens.h" +#include "media/base/audio_bus.h" namespace copresence { // A simple WhispernetClient for testing. class StubWhispernetClient final : public WhispernetClient { public: - // Constructor. The client can optionally be configured to respond - // as if Initialize() has completed. By default it does not. - explicit StubWhispernetClient(bool complete_initialization = false); + // Constructor. |samples| and |tokens|, if specified, + // will be returned for any encoding and decoding requests. + StubWhispernetClient( + scoped_refptr<media::AudioBusRefCounted> samples = + scoped_refptr<media::AudioBusRefCounted>(), + const std::vector<AudioToken>& tokens = std::vector<AudioToken>()); ~StubWhispernetClient() override; @@ -43,11 +49,10 @@ SuccessCallback GetInitializedCallback() override; private: - bool complete_initialization_; TokensCallback tokens_cb_; SamplesCallback samples_cb_; - std::vector<AudioToken> tokens_; scoped_refptr<media::AudioBusRefCounted> samples_; + std::vector<AudioToken> tokens_; DISALLOW_COPY_AND_ASSIGN(StubWhispernetClient); };
diff --git a/components/crash/browser/crash_dump_manager_android.h b/components/crash/browser/crash_dump_manager_android.h index 7476f81e..d7ae5c8 100644 --- a/components/crash/browser/crash_dump_manager_android.h +++ b/components/crash/browser/crash_dump_manager_android.h
@@ -39,7 +39,7 @@ // Should be created on the UI thread. explicit CrashDumpManager(const base::FilePath& crash_dump_dir); - virtual ~CrashDumpManager(); + ~CrashDumpManager() override; // Returns a file that should be used to generate a minidump for the process // |child_process_id|. @@ -52,15 +52,15 @@ base::ProcessHandle pid); // content::BrowserChildProcessObserver implementation: - virtual void BrowserChildProcessHostDisconnected( + void BrowserChildProcessHostDisconnected( const content::ChildProcessData& data) override; - virtual void BrowserChildProcessCrashed( + void BrowserChildProcessCrashed( const content::ChildProcessData& data) override; // NotificationObserver implementation: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; // Called on child process exit (including crash). void OnChildExit(int child_process_id, base::ProcessHandle pid);
diff --git a/components/cronet.gypi b/components/cronet.gypi index 07a521b..dc29726 100644 --- a/components/cronet.gypi +++ b/components/cronet.gypi
@@ -11,11 +11,11 @@ 'target_name': 'cronet_jni_headers', 'type': 'none', 'sources': [ + 'cronet/android/java/src/org/chromium/net/CronetHistogramManager.java', 'cronet/android/java/src/org/chromium/net/CronetUrlRequest.java', 'cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java', 'cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java', 'cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java', - 'cronet/android/java/src/org/chromium/net/HistogramManager.java', ], 'variables': { 'jni_gen_package': 'cronet', @@ -122,6 +122,8 @@ 'cronet/android/chromium_url_request_priority_list.h', 'cronet/android/chromium_url_request_context.cc', 'cronet/android/chromium_url_request_context.h', + 'cronet/android/cronet_histogram_manager.cc', + 'cronet/android/cronet_histogram_manager.h', 'cronet/android/cronet_loader.cc', 'cronet/android/cronet_loader.h', 'cronet/android/cronet_url_request.cc', @@ -132,8 +134,6 @@ 'cronet/android/cronet_url_request_context.h', 'cronet/android/cronet_url_request_context_adapter.cc', 'cronet/android/cronet_url_request_context_adapter.h', - 'cronet/android/histogram_manager.cc', - 'cronet/android/histogram_manager.h', 'cronet/android/url_request_adapter.cc', 'cronet/android/url_request_adapter.h', 'cronet/android/url_request_context_adapter.cc', @@ -194,6 +194,7 @@ 'javac_includes': [ '**/ChunkedWritableByteChannel.java', '**/ExtendedResponseInfo.java', + '**/HistogramManager.java', '**/HttpUrlConnection*.java', '**/HttpUrlRequest*.java', '**/ResponseInfo.java', @@ -230,11 +231,11 @@ '**/ChromiumUrlRequestError.java', '**/ChromiumUrlRequestFactory.java', '**/ChromiumUrlRequestPriority.java', + '**/CronetHistogramManager.java', '**/CronetResponseInfo.java', '**/CronetUrlRequest.java', '**/CronetUrlRequestContext.java', '**/CronetUrlRequestFactory.java', - '**/HistogramManager.java', '**/RequestPriority.java', '**/urlconnection/CronetInputStream.java', '**/urlconnection/CronetHttpURLConnection.java', @@ -316,8 +317,8 @@ 'cronet/android/test/cronet_test_jni.cc', 'cronet/android/test/mock_url_request_job_factory.cc', 'cronet/android/test/mock_url_request_job_factory.h', - 'cronet/android/test/upload_test_server.cc', - 'cronet/android/test/upload_test_server.h', + 'cronet/android/test/native_test_server.cc', + 'cronet/android/test/native_test_server.h', 'cronet/android/test/network_change_notifier_util.cc', 'cronet/android/test/network_change_notifier_util.h', ],
diff --git a/components/cronet/android/histogram_manager.cc b/components/cronet/android/cronet_histogram_manager.cc similarity index 83% rename from components/cronet/android/histogram_manager.cc rename to components/cronet/android/cronet_histogram_manager.cc index 4db69601..8c30bbb 100644 --- a/components/cronet/android/histogram_manager.cc +++ b/components/cronet/android/cronet_histogram_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/cronet/android/histogram_manager.h" +#include "components/cronet/android/cronet_histogram_manager.h" #include <string> #include <vector> @@ -11,12 +11,12 @@ #include "base/metrics/statistics_recorder.h" #include "components/metrics/histogram_manager.h" -#include "jni/HistogramManager_jni.h" +#include "jni/CronetHistogramManager_jni.h" namespace cronet { // Explicitly register static JNI functions. -bool HistogramManagerRegisterJni(JNIEnv* env) { +bool CronetHistogramManagerRegisterJni(JNIEnv* env) { return RegisterNativesImpl(env); }
diff --git a/components/cronet/android/histogram_manager.h b/components/cronet/android/cronet_histogram_manager.h similarity index 75% rename from components/cronet/android/histogram_manager.h rename to components/cronet/android/cronet_histogram_manager.h index 94001a48..1d298e1 100644 --- a/components/cronet/android/histogram_manager.h +++ b/components/cronet/android/cronet_histogram_manager.h
@@ -1,4 +1,4 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,7 +9,7 @@ namespace cronet { -bool HistogramManagerRegisterJni(JNIEnv* env); +bool CronetHistogramManagerRegisterJni(JNIEnv* env); } // namespace cronet
diff --git a/components/cronet/android/cronet_loader.cc b/components/cronet/android/cronet_loader.cc index 3929b6cb..ac68005 100644 --- a/components/cronet/android/cronet_loader.cc +++ b/components/cronet/android/cronet_loader.cc
@@ -8,9 +8,9 @@ #include "base/at_exit.h" #include "components/cronet/android/chromium_url_request.h" #include "components/cronet/android/chromium_url_request_context.h" +#include "components/cronet/android/cronet_histogram_manager.h" #include "components/cronet/android/cronet_url_request.h" #include "components/cronet/android/cronet_url_request_context.h" -#include "components/cronet/android/histogram_manager.h" #include "net/android/net_jni_registrar.h" #include "url/android/url_jni_registrar.h" #include "url/url_util.h" @@ -24,11 +24,11 @@ const base::android::RegistrationMethod kCronetRegisteredMethods[] = { {"BaseAndroid", base::android::RegisterJni}, - {"ChromiumUrlRequest", cronet::ChromiumUrlRequestRegisterJni}, - {"ChromiumUrlRequestContext", cronet::ChromiumUrlRequestContextRegisterJni}, - {"CronetUrlRequest", cronet::CronetUrlRequestRegisterJni}, - {"CronetUrlRequestContext", cronet::CronetUrlRequestContextRegisterJni}, - {"HistogramManager", cronet::HistogramManagerRegisterJni}, + {"ChromiumUrlRequest", ChromiumUrlRequestRegisterJni}, + {"ChromiumUrlRequestContext", ChromiumUrlRequestContextRegisterJni}, + {"CronetHistogramManager", CronetHistogramManagerRegisterJni}, + {"CronetUrlRequest", CronetUrlRequestRegisterJni}, + {"CronetUrlRequestContext", CronetUrlRequestContextRegisterJni}, {"NetAndroid", net::android::RegisterJni}, {"UrlAndroid", url::android::RegisterJni}, };
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc index 1e02bc0..c5b8686 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.cc +++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -30,7 +30,7 @@ class BasicNetworkDelegate : public net::NetworkDelegateImpl { public: BasicNetworkDelegate() {} - virtual ~BasicNetworkDelegate() {} + ~BasicNetworkDelegate() override {} private: // net::NetworkDelegate implementation.
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetHistogramManager.java b/components/cronet/android/java/src/org/chromium/net/CronetHistogramManager.java new file mode 100644 index 0000000..cb2d8d4 --- /dev/null +++ b/components/cronet/android/java/src/org/chromium/net/CronetHistogramManager.java
@@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.net; + +import org.chromium.base.JNINamespace; + +/** + * Controls UMA histograms. + */ +@JNINamespace("cronet") +public final class CronetHistogramManager extends HistogramManager { + public CronetHistogramManager() { + nativeEnsureInitialized(); + } + + /** + * Get histogram deltas serialized as protobuf. + */ + public byte[] getHistogramDeltas() { + return nativeGetHistogramDeltas(); + } + + private native byte[] nativeGetHistogramDeltas(); + + private native void nativeEnsureInitialized(); +}
diff --git a/components/cronet/android/java/src/org/chromium/net/HistogramManager.java b/components/cronet/android/java/src/org/chromium/net/HistogramManager.java index 4983920..e2b1840 100644 --- a/components/cronet/android/java/src/org/chromium/net/HistogramManager.java +++ b/components/cronet/android/java/src/org/chromium/net/HistogramManager.java
@@ -4,25 +4,41 @@ package org.chromium.net; -import org.chromium.base.JNINamespace; +import java.lang.reflect.Constructor; + /** - * Controls UMA histograms. + * Controls UMA histograms in native library. */ -@JNINamespace("cronet") -public final class HistogramManager { - public HistogramManager() { - nativeEnsureInitialized(); - } +public abstract class HistogramManager { + private static final String CRONET_HISTOGRAM_MANAGER = + "org.chromium.net.CronetHistogramManager"; /** * Get histogram deltas serialized as protobuf. */ - public byte[] getHistogramDeltas() { - return nativeGetHistogramDeltas(); + public abstract byte[] getHistogramDeltas(); + + /** + * Creates Histogram Manager if native library is loaded, returns null if not. + */ + public static HistogramManager createHistogramManager() { + HistogramManager histogramManager = null; + try { + Class<? extends HistogramManager> histogramManagerClass = + HistogramManager.class.getClassLoader() + .loadClass(CRONET_HISTOGRAM_MANAGER) + .asSubclass(HistogramManager.class); + Constructor<? extends HistogramManager> constructor = + histogramManagerClass.getConstructor(); + histogramManager = constructor.newInstance(); + } catch (ClassNotFoundException e) { + // Leave as null. + } catch (Exception e) { + throw new IllegalStateException( + "Cannot instantiate: " + CRONET_HISTOGRAM_MANAGER, + e); + } + return histogramManager; } - - private native byte[] nativeGetHistogramDeltas(); - - private native void nativeEnsureInitialized(); }
diff --git a/components/cronet/android/sample/README b/components/cronet/android/sample/README new file mode 100644 index 0000000..97bee9d --- /dev/null +++ b/components/cronet/android/sample/README
@@ -0,0 +1,180 @@ + +How to set up and run the sample app as an Android Studio project. + +Linux (Android Studio version 0.8.11 beta) +===== +(1) Launch Android Studio. + +(2) Choose "Import project". + - Navigate to the location of the sample soure code. + You should be looking at a directory named "sample" + containing a file named "AndroidManifest.xml". + - Pick a new destination for it. + +(3) Copy in the '.jar' files. + (a) Directly under the "app" directory of your project, + create a "libs" directory. Use a shell command if you like, + or use "File|New|Directory" from the menu. But note that + you only get "Directory" as an option if you are in + "Project" view, not "Android" view. "Project" models + the local machine's filesystem, but Android is a virtual + layout of files corresponding to the deployed hierarchy. + That is to say, do step (b) before step (a) if you're inclined. + (b) Toggle the view from "Android" to "Project" + in the selection list above the file hierarchy. + Otherwise you won't see "libs". + (c) Copy 'cronet.jar' and 'cronet_stub.jar' to "libs". + + [Also note that it is possible to leave the '.jar' files + in their original locations, though this seems to be + somewhat discouraged by convention] + +(4) Inform the IDE about the '.jar' files. + (a) Select both files at once. + (b) Bring up the context menu and choose "Add as Library". + (d) Confirm "OK" at the "Add to module" dialog. + [Note: the keyboard shortcut and/or main menu selection + for these steps seems to be missing from Android Studio. + If you prefer, the advice under problem #2 + in "Troubleshooting" below will perform the same thing + without reliance on menu selections] + +(5) Copy in the '.so' file. + (a) Under "app/src/main" create a directory named "jniLibs" + (b) Copy armeabi and ameabi-v7a into jniLibs, which should + contain only subdirectories, not directly a '.so' file + (c) The IDE will automatically know about these. + +(6) Click "Run". + +Troubleshooting: + +(I) If the project doesn't build, there are two typical problems: +#1 - make sure that you have the correct 'cronet.jar'. +There is one that is part of the Chromium build which +does not include org.chromium.base (and so will be missing PathUtil, +at least) and one that is part of the cronet build. + +#2 - If you have vast swaths of red text (errors) in the edit window +for CronetSampleActivity, you should confirm that the requisite +jar files are present in 'build.gradle'. There are at least 2 +files which are named 'build.gradle'. Check them both. +You should observe the following lines [see footnote 1] + +dependencies { + compile file('libs/cronet.jar') + compile file('libs/cornet_stub.jar') +} + +If absent, the lines may be added by hand to the gradle file +which corresponds to the module named "app", and not the project +s a whole. You might have to press a "Sync" button in the IDE +which tells it to re-scan the 'build.gradle' files. + +(II) If the project builds but doesn't run, verify that the '.so' files +are present in your Android package (which is just a jar file in disguise): +% jar tf build/outputs/apk/app-debug.apk +AndroidManifest.xml +res/layout/cronet_sample_activity.xml +resource.arsc +classes.dex +lib/armeabi/libcronet.so +lib/armeabi-v7/libcronet.so +META-INF +etc + +If the '.so' files are not present, it is likely that Android Studio +misinterpreted the containing folder as "ordinary" source code, +which, due to lack of any special directive pertaining to it, failed +to be copied to the apk. One thing to check for is the spelling +of "jniLibs" - it must literally be that, with a capital "L" or +it won't work. This is a bit of magic that allows users without +the NDK (Native Development Kit) to deploy '.so' files. +[With the NDK, things are different because in that case you have to +produce the '.so' files, and create build rules to do so, +so the setup is naturally more flexible to begin with.] +As a visual cue that the folder has been recognized as special, +its icon should match that of the "res" (resources) folder +which resembles a tabbed manila folder with some extra cross-hatches +on the front, and not the icon of the "java" folder. +The marking on the icon signifies that its contents land on the +the target device. But to keep things interesting, the icon is +distinct visually only in "Android" view, not "Project" view. + +MacOS (Android Studio version 1.0.1) +===== +(0) You might or might not have to set a magic environment + variable as follows [see footnote 3]: + export STUDIO_JDK=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk + +(1) Launch Android Studio, which can be achieved from the command + line with + % open '/Applications/Android Studio.app' + +(2) Choose "Import Non-Android Studio Project" + (a) Navigate to the path containing "sample" + (b) Pick a place to put it, and choose "Finish" + +(3) If you are comfortable using shell commands to create directories, + you may proceed to step (3) for Linux above. + Otherwise, if you prefer to create directories from the UI, + proceed with the following steps. + +(4) Choose "File -> New -> Folder -> Assets Folder". + Check "Change Folder Location" and delete the entire + pathname that was there. Change it to 'libs' + which is conventional for pre-built jar files. + +(5) Copy and paste the two pre-built '.jar' files into 'assets'. + When you do this, it will say that the destination is + "app/libs". This is right. If you prefer to see + the file hierarchy as it really exists, you can change + the dropdown above the tree view from "android view" + to "project view". Or just keep in mind that assets = libs + at this level of the hierarchy. + +(6) Select both jar files that you added (Shift+click). + and pull up the menu for them (Ctrl+click). + Select "Add as library" + +(7) Choose "File -> New -> Folder -> JNI Folder". + Choose "Change Folder Location" + and change the name to "src/main/jniLibs" [see footnote 2] + +---- + +Footnotes: +[1] "compile file" as used in a dependency line means to package the + named jars into the apk, and not to make those files. + The opposite of this is "provided file" which assumes that the + jars exist on the device already (in whatever the standard + location is for systemwide jar files), and not that a file + has been externally provided to Android Studio. + +[2] The menu option to add JNI files assumes that you have the + NDK (Native Development Kit) installed and want to produce + files into the named directory. This is triggered by an + automatic rule that tries to look for C++ source code + and the NDK based on the existence of "src/main/jni". + Changing this directory to "src/main/jniLibs" is magical + in a different way: it informs Android Studio that you will + place precompiled binaries into that directory. + +[3] This has to do with differences between the JDK that the studio + runs in as distinct from the JDK that the studio understands + to be present on the target machine. + There is discussion of the issue in + https://code.google.com/p/android/issues/detail?id=82378 + +Additional notes: + +Ideally the two .jar files and one .so file could be delivered as one .aar +(Android Archive) file, but Android Studio will try to pull aar files from +a Maven repository without some workarounds that are about as much trouble +as adding in three separate files. +See https://code.google.com/p/android/issues/detail?id=55863 + +Additionally, it is unclear how to automate the creation of a '.aar' file +outside of Android Studio and Gradle. If the entire workflow were controlled +by Gradle, it would be one thing; but presently the cronet jars are +produced as artifacts of the Chromium build which uses Ninja.
diff --git a/components/cronet/android/test/cronet_test_jni.cc b/components/cronet/android/test/cronet_test_jni.cc index fc24f152..1b1b558 100644 --- a/components/cronet/android/test/cronet_test_jni.cc +++ b/components/cronet/android/test/cronet_test_jni.cc
@@ -9,8 +9,8 @@ #include "base/android/jni_registrar.h" #include "components/cronet/android/cronet_loader.h" #include "mock_url_request_job_factory.h" +#include "native_test_server.h" #include "network_change_notifier_util.h" -#include "upload_test_server.h" namespace {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java index 243f32c8..8ef1ed0 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java
@@ -544,6 +544,7 @@ connection.setInstanceFollowRedirects(false); assertEquals(302, connection.getResponseCode()); assertEquals("Found", connection.getResponseMessage()); + assertEquals("/success.txt", connection.getHeaderField("Location")); assertEquals(NativeTestServer.getFileURL("/redirect.html"), connection.getURL().toString()); connection.disconnect(); @@ -559,6 +560,7 @@ (HttpURLConnection) url.openConnection(); assertEquals(302, connection.getResponseCode()); assertEquals("Found", connection.getResponseMessage()); + assertEquals("/success.txt", connection.getHeaderField("Location")); assertEquals(NativeTestServer.getFileURL("/redirect.html"), connection.getURL().toString()); connection.disconnect();
diff --git a/components/cronet/android/test/upload_test_server.cc b/components/cronet/android/test/native_test_server.cc similarity index 99% rename from components/cronet/android/test/upload_test_server.cc rename to components/cronet/android/test/native_test_server.cc index a6dee60..97261645 100644 --- a/components/cronet/android/test/upload_test_server.cc +++ b/components/cronet/android/test/native_test_server.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "upload_test_server.h" +#include "native_test_server.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h"
diff --git a/components/cronet/android/test/upload_test_server.h b/components/cronet/android/test/native_test_server.h similarity index 70% rename from components/cronet/android/test/upload_test_server.h rename to components/cronet/android/test/native_test_server.h index 9ae6fbb1..629f067 100644 --- a/components/cronet/android/test/upload_test_server.h +++ b/components/cronet/android/test/native_test_server.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CRONET_UPLOAD_TEST_SERVER_H_ -#define CRONET_UPLOAD_TEST_SERVER_H_ +#ifndef CRONET_NATIVE_TEST_SERVER_H_ +#define CRONET_NATIVE_TEST_SERVER_H_ #include <jni.h> @@ -13,4 +13,4 @@ } // namespace cronet -#endif // CRONET_UPLOAD_TEST_SERVER_H_ +#endif // CRONET_NATIVE_TEST_SERVER_H_
diff --git a/components/cronet/android/test/src/org/chromium/cronet_test_apk/CronetTestActivity.java b/components/cronet/android/test/src/org/chromium/cronet_test_apk/CronetTestActivity.java index 863d7639..34ce1450b 100644 --- a/components/cronet/android/test/src/org/chromium/cronet_test_apk/CronetTestActivity.java +++ b/components/cronet/android/test/src/org/chromium/cronet_test_apk/CronetTestActivity.java
@@ -74,8 +74,6 @@ return; } - mHistogramManager = new HistogramManager(); - String skipInitString = getCommandLineArg(SKIP_FACTORY_INIT_KEY); if (skipInitString != null) { return; @@ -121,6 +119,8 @@ mUrlRequestContext = UrlRequestContext.createContext( getApplicationContext(), config); + mHistogramManager = HistogramManager.createHistogramManager(); + return HttpUrlRequestFactory.createFactory(getApplicationContext(), config); }
diff --git a/components/cronet/android/url_request_adapter.h b/components/cronet/android/url_request_adapter.h index 7a63e71..8704a00 100644 --- a/components/cronet/android/url_request_adapter.h +++ b/components/cronet/android/url_request_adapter.h
@@ -49,7 +49,7 @@ URLRequestAdapterDelegate* delegate, GURL url, net::RequestPriority priority); - virtual ~URLRequestAdapter(); + ~URLRequestAdapter() override; // Sets the request method GET, POST etc void SetMethod(const std::string& method);
diff --git a/components/cronet/android/url_request_context_adapter.cc b/components/cronet/android/url_request_context_adapter.cc index 6234aa9..cd8a3a9 100644 --- a/components/cronet/android/url_request_context_adapter.cc +++ b/components/cronet/android/url_request_context_adapter.cc
@@ -39,7 +39,7 @@ class BasicNetworkDelegate : public net::NetworkDelegateImpl { public: BasicNetworkDelegate() {} - virtual ~BasicNetworkDelegate() {} + ~BasicNetworkDelegate() override {} private: // net::NetworkDelegate implementation.
diff --git a/components/cronet/android/url_request_context_adapter.h b/components/cronet/android/url_request_context_adapter.h index 6114087..c479621 100644 --- a/components/cronet/android/url_request_context_adapter.h +++ b/components/cronet/android/url_request_context_adapter.h
@@ -37,7 +37,7 @@ public: NetLogObserver() {} - virtual ~NetLogObserver() {} + ~NetLogObserver() override {} void OnAddEntry(const net::NetLog::Entry& entry) override;
diff --git a/components/cronet/android/wrapped_channel_upload_element_reader.h b/components/cronet/android/wrapped_channel_upload_element_reader.h index 6731e535..4d62d491b 100644 --- a/components/cronet/android/wrapped_channel_upload_element_reader.h +++ b/components/cronet/android/wrapped_channel_upload_element_reader.h
@@ -26,16 +26,16 @@ WrappedChannelElementReader( scoped_refptr<URLRequestAdapter::URLRequestAdapterDelegate> delegate, uint64 length); - virtual ~WrappedChannelElementReader(); + ~WrappedChannelElementReader() override; // UploadElementReader overrides: - virtual int Init(const net::CompletionCallback& callback) override; - virtual uint64 GetContentLength() const override; - virtual uint64 BytesRemaining() const override; - virtual bool IsInMemory() const override; - virtual int Read(net::IOBuffer* buf, - int buf_length, - const net::CompletionCallback& callback) override; + int Init(const net::CompletionCallback& callback) override; + uint64 GetContentLength() const override; + uint64 BytesRemaining() const override; + bool IsInMemory() const override; + int Read(net::IOBuffer* buf, + int buf_length, + const net::CompletionCallback& callback) override; private: const uint64 length_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.cc index b4bad4f..768db668 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.cc
@@ -20,7 +20,6 @@ #include "net/base/host_port_pair.h" #include "net/proxy/proxy_server.h" #include "net/url_request/url_request.h" -#include "url/gurl.h" #if !defined(OS_ANDROID) && !defined(OS_IOS) #include "google_apis/google_api_keys.h" @@ -241,9 +240,9 @@ return; if (data_reduction_proxy_params_ && data_reduction_proxy_params_->IsDataReductionProxy(proxy_server, NULL) && - net::HostPortPair::FromURL( - data_reduction_proxy_params_->ssl_origin()).Equals( - proxy_server) == expect_ssl) { + ((data_reduction_proxy_params_->ssl_origin().is_valid() && + data_reduction_proxy_params_->ssl_origin().host_port_pair().Equals( + proxy_server)) == expect_ssl)) { AddAuthorizationHeader(request_headers); } }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h index 4d270d3..4675ec4e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h
@@ -9,7 +9,6 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "base/time/time.h" -#include "url/gurl.h" namespace base { class SingleThreadTaskRunner;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler_unittest.cc index 68eedfe..647cac1d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler_unittest.cc
@@ -15,9 +15,9 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" #include "net/base/auth.h" #include "net/base/host_port_pair.h" +#include "net/proxy/proxy_server.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" namespace { const char kChromeProxyHeader[] = "chrome-proxy"; @@ -181,19 +181,16 @@ // Don't write headers with a valid data reduction ssl proxy. auth_handler.MaybeAddRequestHeader( NULL, - net::ProxyServer::FromURI( - net::HostPortPair::FromURL( - GURL(params->DefaultSSLOrigin())).ToString(), - net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(params->DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP), &headers); EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader)); // Write headers with a valid data reduction proxy. auth_handler.MaybeAddRequestHeader( NULL, - net::ProxyServer::FromURI( - net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(), - net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(params->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), &headers); EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); std::string header_value; @@ -203,7 +200,9 @@ // Write headers with a valid data reduction ssl proxy when one is expected. net::HttpRequestHeaders ssl_headers; auth_handler.MaybeAddProxyTunnelRequestHandler( - net::HostPortPair::FromURL(GURL(params->DefaultSSLOrigin())), + net::ProxyServer::FromURI( + params->DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), &ssl_headers); EXPECT_TRUE(ssl_headers.HasHeader(kChromeProxyHeader)); std::string ssl_header_value; @@ -216,9 +215,8 @@ // Write headers with a valid data reduction proxy. auth_handler.MaybeAddRequestHeader( NULL, - net::ProxyServer::FromURI( - net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(), - net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(params->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), &headers2); EXPECT_TRUE(headers2.HasHeader(kChromeProxyHeader)); std::string header_value2; @@ -231,9 +229,8 @@ // Write headers with a valid data reduction proxy. auth_handler.MaybeAddRequestHeader( NULL, - net::ProxyServer::FromURI( - net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(), - net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(params->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), &headers3); EXPECT_TRUE(headers3.HasHeader(kChromeProxyHeader)); std::string header_value3; @@ -304,7 +301,7 @@ auth_handler.MaybeAddRequestHeader( NULL, net::ProxyServer::FromURI( - net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(), + params->DefaultOrigin(), net::ProxyServer::SCHEME_HTTP), &headers); EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader));
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc index 81aeceae..66dcd9c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
@@ -24,18 +24,6 @@ namespace { -bool SetProxyServerFromGURL(const GURL& gurl, - net::ProxyServer* proxy_server) { - DCHECK(proxy_server); - if (!gurl.SchemeIsHTTPOrHTTPS()) - return false; - *proxy_server = net::ProxyServer(gurl.SchemeIs(url::kHttpScheme) ? - net::ProxyServer::SCHEME_HTTP : - net::ProxyServer::SCHEME_HTTPS, - net::HostPortPair::FromURL(gurl)); - return true; -} - // Adds non-empty entries in |data_reduction_proxies| to the retry map // maintained by the proxy service of the request. Adds // |data_reduction_proxies.second| to the retry list only if |bypass_all| is @@ -44,19 +32,21 @@ net::URLRequest* request, const base::TimeDelta& bypass_duration, bool bypass_all, - const std::pair<GURL, GURL>& data_reduction_proxies) { - DCHECK(!data_reduction_proxies.first.is_empty()); + const std::pair<net::ProxyServer, net::ProxyServer>& + data_reduction_proxies) { + DCHECK(data_reduction_proxies.first.is_valid()); + DCHECK(!data_reduction_proxies.first.host_port_pair().IsEmpty()); // Synthesize a suitable |ProxyInfo| to add the proxies to the // |ProxyRetryInfoMap| of the proxy service. net::ProxyList proxy_list; - net::ProxyServer primary; - SetProxyServerFromGURL(data_reduction_proxies.first, &primary); + net::ProxyServer primary = data_reduction_proxies.first; if (primary.is_valid()) proxy_list.AddProxyServer(primary); net::ProxyServer fallback; if (bypass_all) { - if (!data_reduction_proxies.second.is_empty()) - SetProxyServerFromGURL(data_reduction_proxies.second, &fallback); + if (data_reduction_proxies.second.is_valid() && + !data_reduction_proxies.second.host_port_pair().IsEmpty()) + fallback = data_reduction_proxies.second; if (fallback.is_valid()) proxy_list.AddProxyServer(fallback); proxy_list.AddProxyServer(net::ProxyServer::Direct()); @@ -112,13 +102,17 @@ if (data_reduction_proxy_type_info.is_ssl) return false; - if (data_reduction_proxy_type_info.proxy_servers.first.is_empty()) + const net::ProxyServer& first = + data_reduction_proxy_type_info.proxy_servers.first; + if (!first.is_valid() || first.host_port_pair().IsEmpty()) return false; // At this point, the response is expected to have the data reduction proxy // via header, so detect and report cases where the via header is missing. + const net::ProxyServer& second = + data_reduction_proxy_type_info.proxy_servers.second; DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode( - !data_reduction_proxy_type_info.proxy_servers.second.is_empty(), + second.is_valid() && !second.host_port_pair().IsEmpty(), response_headers); if (DataReductionProxyParams:: @@ -166,9 +160,8 @@ DCHECK(request->context()); DCHECK(request->context()->proxy_service()); - net::ProxyServer proxy_server; - SetProxyServerFromGURL( - data_reduction_proxy_type_info.proxy_servers.first, &proxy_server); + net::ProxyServer proxy_server = + data_reduction_proxy_type_info.proxy_servers.first; // Only record UMA if the proxy isn't already on the retry list. if (!params_->IsProxyBypassed( @@ -176,7 +169,7 @@ proxy_server, NULL)) { DataReductionProxyUsageStats::RecordDataReductionProxyBypassInfo( - !data_reduction_proxy_type_info.proxy_servers.second.is_empty(), + second.is_valid() && !second.host_port_pair().IsEmpty(), data_reduction_proxy_info.bypass_all, proxy_server, bypass_type);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h index 5315803..cbcd821 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h
@@ -15,8 +15,6 @@ class URLRequest; } -class GURL; - namespace data_reduction_proxy { class DataReductionProxyEventStore;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc index 406ece1ea..a27cc65 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
@@ -27,6 +27,7 @@ #include "net/base/network_delegate.h" #include "net/http/http_response_headers.h" #include "net/http/http_transaction_test_util.h" +#include "net/proxy/proxy_server.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" #include "net/url_request/static_http_user_agent_settings.h" @@ -287,11 +288,11 @@ // Returns the key to the |ProxyRetryInfoMap|. std::string GetProxyKey(std::string proxy) { - GURL gurl(proxy); - std::string host_port = HostPortPair::FromURL(GURL(proxy)).ToString(); - if (gurl.SchemeIs("https")) - return "https://" + host_port; - return host_port; + net::ProxyServer proxy_server = net::ProxyServer::FromURI( + proxy, net::ProxyServer::SCHEME_HTTP); + if (!proxy_server.is_valid()) + return HostPortPair::FromURL(GURL(std::string())).ToString(); + return proxy_server.host_port_pair().ToString(); } // Checks that |expected_num_bad_proxies| proxies are on the proxy retry list. @@ -773,9 +774,11 @@ std::string fallback = proxy_params_->DefaultFallbackOrigin(); for (size_t i = 0; i < arraysize(tests); ++i) { ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( - "PROXY " + - HostPortPair::FromURL(GURL(primary)).ToString() + "; PROXY " + - HostPortPair::FromURL(GURL(fallback)).ToString() + "; DIRECT")); + net::ProxyServer::FromURI( + primary, net::ProxyServer::SCHEME_HTTP).ToPacString() + "; " + + net::ProxyServer::FromURI( + fallback, + net::ProxyServer::SCHEME_HTTP).ToPacString() + "; DIRECT")); TestProxyFallback(tests[i].method, tests[i].first_response, tests[i].expected_retry, @@ -799,9 +802,12 @@ "DataReductionProxyRemoveMissingViaHeaderOtherBypass", "Relaxed"); ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( - "PROXY " + - HostPortPair::FromURL(GURL(primary)).ToString() + "; PROXY " + - HostPortPair::FromURL(GURL(fallback)).ToString() + "; DIRECT")); + net::ProxyServer::FromURI( + primary, net::ProxyServer::SCHEME_HTTP).ToPacString() + "; " + + net::ProxyServer::FromURI( + fallback, + net::ProxyServer::SCHEME_HTTP).ToPacString() + + "; DIRECT")); // This response with the DRP via header should be accepted without causing a // bypass.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 0fbd744..573a235 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -4,6 +4,8 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h" +#include <string> + #include "base/metrics/histogram.h" #include "base/metrics/sparse_histogram.h" #include "base/single_thread_task_runner.h" @@ -12,6 +14,7 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "net/base/load_flags.h" +#include "net/proxy/proxy_server.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" @@ -92,12 +95,12 @@ if (alternative_enabled) { configurator_->Enable(restricted, !params()->alternative_fallback_allowed(), - params()->alt_origin().spec(), std::string(), - params()->ssl_origin().spec()); + params()->alt_origin().ToURI(), std::string(), + params()->ssl_origin().ToURI()); } else { configurator_->Enable(restricted, !params()->fallback_allowed(), - params()->origin().spec(), - params()->fallback_origin().spec(), std::string()); + params()->origin().ToURI(), + params()->fallback_origin().ToURI(), std::string()); } } else { configurator_->Disable();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 024ebd04..61e2616 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -13,6 +13,7 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" #include "net/base/capturing_net_log.h" +#include "net/proxy/proxy_server.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_test_util.h" @@ -162,16 +163,14 @@ }; TEST_F(DataReductionProxyConfigTest, TestGetDataReductionProxyOrigin) { - std::string result = config()->params()->origin().spec(); - EXPECT_EQ(GURL(params()->DefaultOrigin()), GURL(result)); + EXPECT_EQ(params()->DefaultOrigin(), config()->params()->origin().ToURI()); } TEST_F(DataReductionProxyConfigTest, TestGetDataReductionProxyDevOrigin) { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kDataReductionProxyDev, params()->DefaultDevOrigin()); ResetSettings(true, true, false, true, false); - std::string result = config()->params()->origin().spec(); - EXPECT_EQ(GURL(params()->DefaultDevOrigin()), GURL(result)); + EXPECT_EQ(params()->DefaultDevOrigin(), config()->params()->origin().ToURI()); } TEST_F(DataReductionProxyConfigTest, TestGetDataReductionProxies) { @@ -181,14 +180,13 @@ unsigned int expected_proxy_size = 2u; EXPECT_EQ(expected_proxy_size, proxies.size()); - net::HostPortPair expected_origin = - net::HostPortPair::FromURL(GURL(params()->DefaultOrigin())); - net::HostPortPair expected_fallback_origin = - net::HostPortPair::FromURL(GURL(params()->DefaultFallbackOrigin())); - EXPECT_EQ(expected_origin.host(), proxies[0].host()); - EXPECT_EQ(expected_origin.port(), proxies[0].EffectiveIntPort()); - EXPECT_EQ(expected_fallback_origin.host(), proxies[1].host()); - EXPECT_EQ(expected_fallback_origin.port(), proxies[1].EffectiveIntPort()); + EXPECT_EQ(net::ProxyServer::FromURI(params()->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), + proxies[0]); + + EXPECT_EQ(net::ProxyServer::FromURI(params()->DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP), + proxies[1]); } TEST_F(DataReductionProxyConfigTest, TestSetProxyConfigs) { @@ -203,16 +201,21 @@ config()->SetProxyConfigs(true, true, false, false); EXPECT_TRUE(configurator()->enabled()); - EXPECT_TRUE( - net::HostPortPair::FromString(params()->DefaultAltOrigin()) - .Equals(net::HostPortPair::FromString(configurator()->origin()))); - EXPECT_TRUE( - net::HostPortPair::FromString(params()->DefaultAltFallbackOrigin()) - .Equals(net::HostPortPair::FromString( - configurator()->fallback_origin()))); - EXPECT_TRUE( - net::HostPortPair::FromString(params()->DefaultSSLOrigin()) - .Equals(net::HostPortPair::FromString(configurator()->ssl_origin()))); + + EXPECT_EQ( + net::ProxyServer::FromURI( + params()->DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(configurator()->origin(), + net::ProxyServer::SCHEME_HTTP)); + EXPECT_TRUE(net::ProxyServer::FromURI( + params()->DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).is_valid()); + EXPECT_TRUE(configurator()->fallback_origin().empty()); + EXPECT_EQ(net::ProxyServer::FromURI(params()->DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(configurator()->ssl_origin(), + net::ProxyServer::SCHEME_HTTP)); config()->SetProxyConfigs(true, false, false, false); EXPECT_TRUE(configurator()->enabled()); @@ -222,19 +225,19 @@ EXPECT_TRUE(net::HostPortPair::FromString(params()->DefaultFallbackOrigin()) .Equals(net::HostPortPair::FromString( configurator()->fallback_origin()))); - EXPECT_EQ("", configurator()->ssl_origin()); + EXPECT_TRUE(configurator()->ssl_origin().empty()); config()->SetProxyConfigs(false, true, false, false); EXPECT_FALSE(configurator()->enabled()); - EXPECT_EQ("", configurator()->origin()); - EXPECT_EQ("", configurator()->fallback_origin()); - EXPECT_EQ("", configurator()->ssl_origin()); + EXPECT_TRUE(configurator()->origin().empty()); + EXPECT_TRUE(configurator()->fallback_origin().empty()); + EXPECT_TRUE(configurator()->ssl_origin().empty()); config()->SetProxyConfigs(false, false, false, false); EXPECT_FALSE(configurator()->enabled()); - EXPECT_EQ("", configurator()->origin()); - EXPECT_EQ("", configurator()->fallback_origin()); - EXPECT_EQ("", configurator()->ssl_origin()); + EXPECT_TRUE(configurator()->origin().empty()); + EXPECT_TRUE(configurator()->fallback_origin().empty()); + EXPECT_TRUE(configurator()->ssl_origin().empty()); } TEST_F(DataReductionProxyConfigTest, TestSetProxyConfigsHoldback) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc index eaa4b63a..c8869ea 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
@@ -66,6 +66,18 @@ "", ""); } +TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedQuic) { + config_->Enable(false, + false, + "quic://www.foo.com:443/", + "http://www.bar.com:80/", + ""); + CheckProxyConfig( + net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "QUIC www.foo.com:443;PROXY www.bar.com:80;DIRECT", + "", ""); +} + TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedSSL) { config_->Enable(false, false, @@ -79,6 +91,19 @@ ""); } +TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedSSLQuic) { + config_->Enable(false, + false, + "quic://www.foo.com:443/", + "http://www.bar.com:80/", + "http://www.ssl.com:80/"); + CheckProxyConfig( + net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "QUIC www.foo.com:443;PROXY www.bar.com:80;DIRECT", + "PROXY www.ssl.com:80;DIRECT", + ""); +} + TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithBypassRule) { config_->AddHostPatternToBypass("<local>"); config_->AddHostPatternToBypass("*.goo.com"); @@ -93,12 +118,33 @@ "<local>;*.goo.com;"); } +TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithBypassRuleQuic) { + config_->AddHostPatternToBypass("<local>"); + config_->AddHostPatternToBypass("*.goo.com"); + config_->Enable(false, + false, + "quic://www.foo.com:443/", + "http://www.bar.com:80/", + ""); + CheckProxyConfig( + net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "QUIC www.foo.com:443;PROXY www.bar.com:80;DIRECT", "", + "<local>;*.goo.com;"); +} + TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithoutFallback) { config_->Enable(false, false, "https://www.foo.com:443/", "", ""); CheckProxyConfig(net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, "HTTPS www.foo.com:443;DIRECT", "", ""); } +TEST_F(DataReductionProxyConfiguratorTest, + TestUnrestrictedWithoutFallbackQuic) { + config_->Enable(false, false, "quic://www.foo.com:443/", "", ""); + CheckProxyConfig(net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "QUIC www.foo.com:443;DIRECT", "", ""); +} + TEST_F(DataReductionProxyConfiguratorTest, TestRestricted) { config_->Enable(true, false, @@ -109,6 +155,16 @@ "PROXY www.bar.com:80;DIRECT", "", ""); } +TEST_F(DataReductionProxyConfiguratorTest, TestRestrictedQuic) { + config_->Enable(true, + false, + "quic://www.foo.com:443/", + "http://www.bar.com:80/", + ""); + CheckProxyConfig(net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "PROXY www.bar.com:80;DIRECT", "", ""); +} + TEST_F(DataReductionProxyConfiguratorTest, TestFallbackRestricted) { config_->Enable(false, true, @@ -119,14 +175,24 @@ "HTTPS www.foo.com:443;DIRECT", "", ""); } +TEST_F(DataReductionProxyConfiguratorTest, TestFallbackRestrictedQuic) { + config_->Enable(false, + true, + "quic://www.foo.com:443/", + "http://www.bar.com:80/", + ""); + CheckProxyConfig(net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, + "QUIC www.foo.com:443;DIRECT", "", ""); +} + TEST_F(DataReductionProxyConfiguratorTest, TestDisable) { data_reduction_proxy::DataReductionProxyParams params( data_reduction_proxy::DataReductionProxyParams:: kAllowAllProxyConfigurations); config_->Enable(false, false, - params.origin().spec(), - params.fallback_origin().spec(), + params.origin().ToURI(), + params.fallback_origin().ToURI(), ""); config_->Disable(); CheckProxyConfig(net::ProxyConfig::ProxyRules::TYPE_NO_RULES, "", "", "");
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc index 26de12c..9bbca1b 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
@@ -4,6 +4,8 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h" +#include <string> + #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -18,6 +20,7 @@ #include "net/base/capturing_net_log.h" #include "net/base/request_priority.h" #include "net/http/http_response_headers.h" +#include "net/proxy/proxy_server.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_intercepting_job_factory.h" @@ -83,7 +86,7 @@ TestURLRequestContextWithDataReductionProxy(DataReductionProxyParams* params, net::NetworkDelegate* delegate) : net::TestURLRequestContext(true) { - std::string proxy = params->origin().spec(); + std::string proxy = params->origin().ToURI(); context_storage_.set_proxy_service(net::ProxyService::CreateFixed(proxy)); set_network_delegate(delegate); } @@ -187,9 +190,11 @@ TestDataReductionProxyParams::HAS_EVERYTHING & ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); - params->set_origin(proxy_.GetURL("/")); - std::string proxy_name = - net::HostPortPair::FromURL(GURL(params->origin())).ToString(); + std::string spec; + base::TrimString(proxy_.GetURL("/").spec(), "/", &spec); + params->set_origin(net::ProxyServer::FromURI( + spec, net::ProxyServer::SCHEME_HTTP)); + std::string proxy_name = params->origin().ToURI(); proxy_service_.reset( net::ProxyService::CreateFixedFromPacResult( "PROXY " + proxy_name + "; DIRECT"));
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index b679892..2eecb6a 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -85,6 +85,10 @@ return statistics_prefs_.get(); } + DataReductionProxyAuthRequestHandler* auth_request_handler() const { + return auth_request_handler_.get(); + } + net::ProxyDelegate* proxy_delegate() const { return proxy_delegate_.get(); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 50fc91a..46e235e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -26,6 +26,7 @@ #include "net/base/net_log.h" #include "net/http/http_response_headers.h" #include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_server.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_test_job.h" @@ -361,7 +362,9 @@ base::TrimString(test_params.DefaultOrigin(), "/", &data_reduction_proxy); data_reduction_proxy_info.UsePacString( "PROXY " + - net::HostPortPair::FromURL(GURL(test_params.DefaultOrigin())).ToString() + + net::ProxyServer::FromURI( + test_params.DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair().ToString() + "; DIRECT"); EXPECT_FALSE(data_reduction_proxy_info.is_empty());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc index 88aa317..26fad47 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -30,6 +30,7 @@ #include "net/base/net_util.h" #include "net/http/http_network_session.h" #include "net/http/http_response_headers.h" +#include "net/proxy/proxy_server.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_context_getter.h" @@ -437,14 +438,14 @@ if (alternative_enabled) { configurator_->Enable(restricted, !params()->alternative_fallback_allowed(), - params()->alt_origin().spec(), + params()->alt_origin().ToURI(), std::string(), - params()->ssl_origin().spec()); + params()->ssl_origin().ToURI()); } else { configurator_->Enable(restricted, !params()->fallback_allowed(), - params()->origin().spec(), - params()->fallback_origin().spec(), + params()->origin().ToURI(), + params()->fallback_origin().ToURI(), std::string()); } } else {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc index 8519ebbb..f8be374 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -18,7 +18,6 @@ #include "net/http/http_auth_cache.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" namespace { @@ -38,8 +37,8 @@ TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyOrigin) { // SetUp() adds the origin to the command line, which should be returned here. std::string result = - settings_->params()->origin().spec(); - EXPECT_EQ(GURL(expected_params_->DefaultOrigin()), GURL(result)); + settings_->params()->origin().ToURI(); + EXPECT_EQ(expected_params_->DefaultOrigin(), result); } TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyDevOrigin) { @@ -47,8 +46,8 @@ switches::kDataReductionProxyDev, expected_params_->DefaultDevOrigin()); ResetSettings(true, true, false, true, false); std::string result = - settings_->params()->origin().spec(); - EXPECT_EQ(GURL(expected_params_->DefaultDevOrigin()), GURL(result)); + settings_->params()->origin().ToURI(); + EXPECT_EQ(expected_params_->DefaultDevOrigin(), result); } @@ -59,15 +58,12 @@ unsigned int expected_proxy_size = 2u; EXPECT_EQ(expected_proxy_size, proxies.size()); - net::HostPortPair expected_origin = - net::HostPortPair::FromURL(GURL(expected_params_->DefaultOrigin())); - net::HostPortPair expected_fallback_origin = - net::HostPortPair::FromURL( - GURL(expected_params_->DefaultFallbackOrigin())); - EXPECT_EQ(expected_origin.host(), proxies[0].host()); - EXPECT_EQ(expected_origin.port() ,proxies[0].EffectiveIntPort()); - EXPECT_EQ(expected_fallback_origin.host(), proxies[1].host()); - EXPECT_EQ(expected_fallback_origin.port(), proxies[1].EffectiveIntPort()); + EXPECT_EQ(net::ProxyServer::FromURI(expected_params_->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), + proxies[0]); + EXPECT_EQ(net::ProxyServer::FromURI(expected_params_->DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP), + proxies[1]); } TEST_F(DataReductionProxySettingsTest, TestSetProxyConfigs) { @@ -92,36 +88,43 @@ settings_->SetProxyConfigs(true, true, false, false); EXPECT_TRUE(configurator->enabled()); - EXPECT_TRUE(net::HostPortPair::FromString( - expected_params_->DefaultAltOrigin()).Equals( - net::HostPortPair::FromString(configurator->origin()))); - EXPECT_TRUE(net::HostPortPair::FromString( - expected_params_->DefaultAltFallbackOrigin()).Equals( - net::HostPortPair::FromString(configurator->fallback_origin()))); - EXPECT_TRUE(net::HostPortPair::FromString( - expected_params_->DefaultSSLOrigin()).Equals( - net::HostPortPair::FromString(configurator->ssl_origin()))); + EXPECT_EQ(net::ProxyServer::FromURI(expected_params_->DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(configurator->origin(), + net::ProxyServer::SCHEME_HTTP)); + EXPECT_TRUE( + net::ProxyServer::FromURI(expected_params_->DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).is_valid()); + EXPECT_TRUE(configurator->fallback_origin().empty()); + EXPECT_EQ(net::ProxyServer::FromURI(expected_params_->DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(configurator->ssl_origin(), + net::ProxyServer::SCHEME_HTTP)); settings_->SetProxyConfigs(true, false, false, false); EXPECT_TRUE(configurator->enabled()); - EXPECT_TRUE(net::HostPortPair::FromString(drp_params.DefaultOrigin()).Equals( - net::HostPortPair::FromString(configurator->origin()))); - EXPECT_TRUE(net::HostPortPair::FromString( - drp_params.DefaultFallbackOrigin()).Equals( - net::HostPortPair::FromString(configurator->fallback_origin()))); - EXPECT_EQ("", configurator->ssl_origin()); + EXPECT_EQ(net::ProxyServer::FromURI(drp_params.DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI(configurator->origin(), + net::ProxyServer::SCHEME_HTTP)); + EXPECT_EQ(net::ProxyServer::FromURI(drp_params.DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP), + net::ProxyServer::FromURI( + configurator->fallback_origin(), + net::ProxyServer::SCHEME_HTTP)); + EXPECT_TRUE(configurator->ssl_origin().empty()); settings_->SetProxyConfigs(false, true, false, false); EXPECT_FALSE(configurator->enabled()); - EXPECT_EQ("", configurator->origin()); - EXPECT_EQ("", configurator->fallback_origin()); - EXPECT_EQ("", configurator->ssl_origin()); + EXPECT_TRUE(configurator->origin().empty()); + EXPECT_TRUE(configurator->fallback_origin().empty()); + EXPECT_TRUE(configurator->ssl_origin().empty()); settings_->SetProxyConfigs(false, false, false, false); EXPECT_FALSE(configurator->enabled()); - EXPECT_EQ("", configurator->origin()); - EXPECT_EQ("", configurator->fallback_origin()); - EXPECT_EQ("", configurator->ssl_origin()); + EXPECT_TRUE(configurator->origin().empty()); + EXPECT_TRUE(configurator->fallback_origin().empty()); + EXPECT_TRUE(configurator->ssl_origin().empty()); } TEST_F(DataReductionProxySettingsTest, TestSetProxyConfigsHoldback) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc index f603265..ef14fbd 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc
@@ -254,11 +254,12 @@ content_length); // If non-empty, |proxy_server.first| is the proxy that this request used. - if (!data_reduction_proxy_type_info.proxy_servers.first.is_empty()) { + const net::ProxyServer& first = + data_reduction_proxy_type_info.proxy_servers.first; + if (first.is_valid() && !first.host_port_pair().IsEmpty()) { DataReductionProxyTamperDetection::DetectAndReport( request.response_info().headers.get(), - data_reduction_proxy_type_info.proxy_servers.first.SchemeIsSecure(), - content_length); + first.is_https() || first.is_quic(), content_length); } return; } @@ -273,7 +274,7 @@ // Now that the data reduction proxy is a best effort proxy, if the effective // proxy configuration resolves to anything other than direct:// for a URL, // the data reduction proxy will not be used. - DCHECK(data_reduction_proxy_type_info.proxy_servers.first.is_empty()); + DCHECK(!data_reduction_proxy_type_info.proxy_servers.first.is_valid()); if (!request.proxy_server().IsEmpty()) { RecordBypassedBytes(last_bypass_type_, DataReductionProxyUsageStats::PROXY_OVERRIDDEN,
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc index 84dc2f5..d7fce59d 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
@@ -16,6 +16,7 @@ #include "base/values.h" #include "net/base/host_port_pair.h" #include "net/base/net_log.h" +#include "net/proxy/proxy_server.h" #include "url/gurl.h" namespace { @@ -58,18 +59,12 @@ // The following method creates a string resembling the output of // net::ProxyServer::ToURI(). std::string GetNormalizedProxyString(const std::string& proxy_origin) { - GURL proxy_url(proxy_origin); - if (proxy_url.is_valid()) { - net::HostPortPair proxy_host_port_pair = - net::HostPortPair::FromURL(proxy_url); - if (proxy_url.SchemeIs(url::kHttpScheme)) - return proxy_host_port_pair.ToString(); - - return std::string(proxy_url.scheme()) + url::kStandardSchemeSeparator + - proxy_host_port_pair.ToString(); - } else { + net::ProxyServer proxy_server = net::ProxyServer::FromURI( + proxy_origin, net::ProxyServer::SCHEME_HTTP); + if (proxy_server.is_valid()) + return proxy_origin; + else return std::string(); - } } // The following callbacks create a base::Value which contains information
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc index 80139f5..4f0ca9a0 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -4,6 +4,7 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" +#include <string> #include <vector> #include "base/command_line.h" @@ -29,16 +30,16 @@ namespace { const char kEnabled[] = "Enabled"; -const char kDefaultOrigin[] = "https://proxy.googlezip.net:443/"; -const char kDevOrigin[] = "https://proxy-dev.googlezip.net:443/"; -const char kDevFallbackOrigin[] = "http://proxy-dev.googlezip.net:80/"; -const char kDefaultFallbackOrigin[] = "http://compress.googlezip.net:80/"; +const char kDefaultOrigin[] = "https://proxy.googlezip.net:443"; +const char kDevOrigin[] = "https://proxy-dev.googlezip.net:443"; +const char kDevFallbackOrigin[] = "proxy-dev.googlezip.net:80"; +const char kDefaultFallbackOrigin[] = "compress.googlezip.net:80"; // This is for a proxy that supports HTTP CONNECT to tunnel SSL traffic. // The proxy listens on port 443, but uses the HTTP protocol to set up // the tunnel, not HTTPS. -const char kDefaultSslOrigin[] = "http://ssl.googlezip.net:443/"; -const char kDefaultAltOrigin[] = "http://ssl.googlezip.net:80/"; -const char kDefaultAltFallbackOrigin[] = "http://ssl.googlezip.net:80/"; +const char kDefaultSslOrigin[] = "ssl.googlezip.net:443"; +const char kDefaultAltOrigin[] = "ssl.googlezip.net:80"; +const char kDefaultAltFallbackOrigin[] = "ssl.googlezip.net:80"; const char kDefaultProbeUrl[] = "http://check.googlezip.net/connect"; const char kDefaultWarmupUrl[] = "http://www.gstatic.com/generate_204"; @@ -189,7 +190,7 @@ // Verify that all necessary params are set. if (allowed) { if (!origin_.is_valid()) { - DVLOG(1) << "Invalid data reduction proxy origin: " << origin_.spec(); + DVLOG(1) << "Invalid data reduction proxy origin: " << origin_.ToURI(); return false; } } @@ -197,7 +198,7 @@ if (allowed && fallback_allowed) { if (!fallback_origin_.is_valid()) { DVLOG(1) << "Invalid data reduction proxy fallback origin: " - << fallback_origin_.spec(); + << fallback_origin_.ToURI(); return false; } } @@ -209,11 +210,11 @@ return false; } if (!alt_origin_.is_valid()) { - DVLOG(1) << "Invalid alternative origin:" << alt_origin_.spec(); + DVLOG(1) << "Invalid alternative origin:" << alt_origin_.ToURI(); return false; } if (!ssl_origin_.is_valid()) { - DVLOG(1) << "Invalid ssl origin: " << ssl_origin_.spec(); + DVLOG(1) << "Invalid ssl origin: " << ssl_origin_.ToURI(); return false; } } @@ -221,7 +222,7 @@ if (alt_allowed && alt_fallback_allowed) { if (!alt_fallback_origin_.is_valid()) { DVLOG(1) << "Invalid alternative fallback origin:" - << alt_fallback_origin_.spec(); + << alt_fallback_origin_.ToURI(); return false; } } @@ -308,11 +309,16 @@ if (warmup_url.empty()) warmup_url = GetDefaultWarmupURL(); - origin_ = GURL(origin); - fallback_origin_ = GURL(fallback_origin); - ssl_origin_ = GURL(ssl_origin); - alt_origin_ = GURL(alt_origin); - alt_fallback_origin_ = GURL(alt_fallback_origin); + origin_ = net::ProxyServer::FromURI(origin, net::ProxyServer::SCHEME_HTTP); + fallback_origin_ = + net::ProxyServer::FromURI(fallback_origin, net::ProxyServer::SCHEME_HTTP); + ssl_origin_ = + net::ProxyServer::FromURI(ssl_origin, net::ProxyServer::SCHEME_HTTP); + alt_origin_ = + net::ProxyServer::FromURI(alt_origin, net::ProxyServer::SCHEME_HTTP); + alt_fallback_origin_ = + net::ProxyServer::FromURI(alt_fallback_origin, + net::ProxyServer::SCHEME_HTTP); probe_url_ = GURL(probe_url); warmup_url_ = GURL(warmup_url); @@ -328,8 +334,8 @@ bool DataReductionProxyParams::IsDataReductionProxy( const net::HostPortPair& host_port_pair, DataReductionProxyTypeInfo* proxy_info) const { - if (allowed() && - net::HostPortPair::FromURL(origin()).Equals(host_port_pair)) { + if (allowed() && origin().is_valid() && + origin().host_port_pair().Equals(host_port_pair)) { if (proxy_info) { proxy_info->proxy_servers.first = origin(); if (fallback_allowed()) @@ -338,17 +344,19 @@ return true; } - if (fallback_allowed() && - net::HostPortPair::FromURL(fallback_origin()).Equals(host_port_pair)) { + if (fallback_allowed() && fallback_origin().is_valid() && + fallback_origin().host_port_pair().Equals(host_port_pair)) { if (proxy_info) { proxy_info->proxy_servers.first = fallback_origin(); - proxy_info->proxy_servers.second = GURL(); + proxy_info->proxy_servers.second = + net::ProxyServer::FromURI(std::string(), + net::ProxyServer::SCHEME_HTTP); proxy_info->is_fallback = true; } return true; } - if (alternative_allowed() && - net::HostPortPair::FromURL(alt_origin()).Equals(host_port_pair)) { + if (alternative_allowed() && alt_origin().is_valid() && + alt_origin().host_port_pair().Equals(host_port_pair)) { if (proxy_info) { proxy_info->proxy_servers.first = alt_origin(); proxy_info->is_alternative = true; @@ -357,21 +365,26 @@ } return true; } - if (alternative_fallback_allowed() && - net::HostPortPair::FromURL(alt_fallback_origin()).Equals( + if (alternative_fallback_allowed() && alt_fallback_origin().is_valid() && + alt_fallback_origin().host_port_pair().Equals( host_port_pair)) { if (proxy_info) { proxy_info->proxy_servers.first = alt_fallback_origin(); - proxy_info->proxy_servers.second = GURL(); + proxy_info->proxy_servers.second = + net::ProxyServer::FromURI(std::string(), + net::ProxyServer::SCHEME_HTTP); proxy_info->is_fallback = true; proxy_info->is_alternative = true; } return true; } - if (net::HostPortPair::FromURL(ssl_origin()).Equals(host_port_pair)) { + if (ssl_origin().is_valid() && + ssl_origin().host_port_pair().Equals(host_port_pair)) { if (proxy_info) { proxy_info->proxy_servers.first = ssl_origin(); - proxy_info->proxy_servers.second = GURL(); + proxy_info->proxy_servers.second = + net::ProxyServer::FromURI(std::string(), + net::ProxyServer::SCHEME_HTTP); proxy_info->is_ssl = true; } return true; @@ -463,18 +476,17 @@ for (size_t i = 0; i < proxy_list->GetSize(); ++i) { proxy_list->GetString(i, &proxy); - host_port_pair = GURL(proxy).SchemeIs(url::kHttpsScheme) ? - net::HostPortPair::FromURL(GURL(proxy)) : - net::HostPortPair::FromString(proxy); + host_port_pair = net::HostPortPair::FromString(std::string()); + net::ProxyServer proxy_server = + net::ProxyServer::FromURI(proxy, net::ProxyServer::SCHEME_HTTP); + if (proxy_server.is_valid() && !proxy_server.is_direct()) + host_port_pair = proxy_server.host_port_pair(); if (IsDataReductionProxy(host_port_pair, NULL)) { if (!IsProxyBypassed( - retry_map, - net::ProxyServer(GURL(proxy).SchemeIs(url::kHttpsScheme) ? - net::ProxyServer::SCHEME_HTTPS : - net::ProxyServer::SCHEME_HTTP, - host_port_pair), - &delay)) + retry_map, + net::ProxyServer::FromURI(proxy, net::ProxyServer::SCHEME_HTTP), + &delay)) return false; if (delay < min_delay) min_delay = delay;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h index e4acf28..e8164d7a 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -13,6 +13,7 @@ #include "net/base/host_port_pair.h" #include "net/proxy/proxy_config.h" #include "net/proxy/proxy_retry_info.h" +#include "net/proxy/proxy_server.h" #include "url/gurl.h" namespace base { @@ -33,7 +34,7 @@ struct DataReductionProxyTypeInfo { DataReductionProxyTypeInfo(); ~DataReductionProxyTypeInfo(); - std::pair<GURL, GURL> proxy_servers; + std::pair<net::ProxyServer, net::ProxyServer> proxy_servers; bool is_fallback; bool is_alternative; bool is_ssl; @@ -58,7 +59,7 @@ static const unsigned int kPromoAllowed = (1 << 4); static const unsigned int kHoldback = (1 << 5); - typedef std::vector<GURL> DataReductionProxyList; + typedef std::vector<net::ProxyServer> DataReductionProxyList; // Returns true if this client is part of field trial to use an alternative // configuration for the data reduction proxy. @@ -180,28 +181,28 @@ base::TimeDelta* retry_delay) const; // Returns the data reduction proxy primary origin. - const GURL& origin() const { + const net::ProxyServer& origin() const { return origin_; } // Returns the data reduction proxy fallback origin. - const GURL& fallback_origin() const { + const net::ProxyServer& fallback_origin() const { return fallback_origin_; } // Returns the data reduction proxy ssl origin that is used with the // alternative proxy configuration. - const GURL& ssl_origin() const { + const net::ProxyServer& ssl_origin() const { return ssl_origin_; } // Returns the alternative data reduction proxy primary origin. - const GURL& alt_origin() const { + const net::ProxyServer& alt_origin() const { return alt_origin_; } // Returns the alternative data reduction proxy fallback origin. - const GURL& alt_fallback_origin() const { + const net::ProxyServer& alt_fallback_origin() const { return alt_fallback_origin_; } @@ -291,8 +292,8 @@ virtual std::string GetDefaultWarmupURL() const; protected: - GURL origin_; - GURL fallback_origin_; + net::ProxyServer origin_; + net::ProxyServer fallback_origin_; private: // Checks if the primary and fallback data reduction proxies are in the retry @@ -301,15 +302,16 @@ // NULL). If the fallback proxy is not valid, returns true if primary proxy // was bypassed and returns its bypass delay. bool ArePrimaryAndFallbackBypassed(const net::ProxyRetryInfoMap& retry_map, - const GURL& primary, - const GURL& fallback, + const net::ProxyServer& primary, + const net::ProxyServer& fallback, base::TimeDelta* min_retry_delay) const; + DataReductionProxyParams& operator=(const DataReductionProxyParams& params); - GURL ssl_origin_; - GURL alt_origin_; - GURL alt_fallback_origin_; + net::ProxyServer ssl_origin_; + net::ProxyServer alt_origin_; + net::ProxyServer alt_fallback_origin_; GURL probe_url_; GURL warmup_url_;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc index d6dd412..e0aa147a 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
@@ -6,20 +6,20 @@ namespace { // Test values to replace the values specified in preprocessor defines. -static const char kDefaultDevOrigin[] = "https://dev.net:443/"; -static const char kDefaultDevFallbackOrigin[] = "http://dev.net:80/"; -static const char kDefaultOrigin[] = "http://origin.net:80/"; -static const char kDefaultFallbackOrigin[] = "http://fallback.net:80/"; -static const char kDefaultSSLOrigin[] = "http://ssl.net:1080/"; -static const char kDefaultAltOrigin[] = "https://alt.net:443/"; -static const char kDefaultAltFallbackOrigin[] = "http://altfallback.net:80/"; +static const char kDefaultDevOrigin[] = "https://dev.net:443"; +static const char kDefaultDevFallbackOrigin[] = "dev.net:80"; +static const char kDefaultOrigin[] = "origin.net:80"; +static const char kDefaultFallbackOrigin[] = "fallback.net:80"; +static const char kDefaultSSLOrigin[] = "ssl.net:1080"; +static const char kDefaultAltOrigin[] = "https://alt.net:443"; +static const char kDefaultAltFallbackOrigin[] = "altfallback.net:80"; static const char kDefaultProbeURL[] = "http://probe.net/"; -static const char kFlagOrigin[] = "https://origin.org:443/"; -static const char kFlagFallbackOrigin[] = "http://fallback.org:80/"; -static const char kFlagSSLOrigin[] = "http://ssl.org:1080/"; -static const char kFlagAltOrigin[] = "https://alt.org:443/"; -static const char kFlagAltFallbackOrigin[] = "http://altfallback.org:80/"; +static const char kFlagOrigin[] = "https://origin.org:443"; +static const char kFlagFallbackOrigin[] = "fallback.org:80"; +static const char kFlagSSLOrigin[] = "ssl.org:1080"; +static const char kFlagAltOrigin[] = "https://alt.org:443"; +static const char kFlagAltFallbackOrigin[] = "altfallback.org:80"; static const char kFlagProbeURL[] = "http://probe.org/"; } @@ -96,12 +96,12 @@ return kFlagProbeURL; } -void TestDataReductionProxyParams::set_origin(const GURL& origin) { +void TestDataReductionProxyParams::set_origin(const net::ProxyServer& origin) { origin_ = origin; } void TestDataReductionProxyParams::set_fallback_origin( - const GURL& fallback_origin) { + const net::ProxyServer& fallback_origin) { fallback_origin_ = fallback_origin; }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h index 713cf3f..8357d24d 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h
@@ -7,6 +7,10 @@ #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" +namespace net { +class ProxyServer; +} + namespace data_reduction_proxy { class TestDataReductionProxyParams : public DataReductionProxyParams { @@ -46,8 +50,8 @@ static std::string FlagAltFallbackOrigin(); static std::string FlagProbeURL(); - void set_origin(const GURL& origin); - void set_fallback_origin(const GURL& fallback_origin); + void set_origin(const net::ProxyServer& origin); + void set_fallback_origin(const net::ProxyServer& fallback_origin); protected: std::string GetDefaultDevOrigin() const override;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc index 4c5db3d..590671f9 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -37,11 +37,12 @@ const std::string& expected_alt_origin, const std::string& expected_alt_fallback_origin, const std::string& expected_probe_url) { - EXPECT_EQ(GURL(expected_origin), params.origin()); - EXPECT_EQ(GURL(expected_fallback_origin), params.fallback_origin()); - EXPECT_EQ(GURL(expected_ssl_origin), params.ssl_origin()); - EXPECT_EQ(GURL(expected_alt_origin), params.alt_origin()); - EXPECT_EQ(GURL(expected_alt_fallback_origin), params.alt_fallback_origin()); + EXPECT_EQ(expected_origin, params.origin().ToURI()); + EXPECT_EQ(expected_fallback_origin, params.fallback_origin().ToURI()); + EXPECT_EQ(expected_ssl_origin, params.ssl_origin().ToURI()); + EXPECT_EQ(expected_alt_origin, params.alt_origin().ToURI()); + EXPECT_EQ(expected_alt_fallback_origin, + params.alt_fallback_origin().ToURI()); EXPECT_EQ(GURL(expected_probe_url), params.probe_url()); } }; @@ -543,51 +544,59 @@ bool expected_is_ssl; } tests[] = { { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultOrigin())), - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), net::HostPortPair::FromURL(GURL()), false, false, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), net::HostPortPair::FromURL(GURL()), true, false, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false, @@ -599,51 +608,59 @@ false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltOrigin())), - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, true, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), net::HostPortPair::FromURL(GURL()), false, true, false }, { - net::HostPortPair::FromURL( - GURL(TestDataReductionProxyParams::DefaultAltFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), net::HostPortPair::FromURL(GURL()), true, true, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultAltFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultAltFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false, @@ -655,37 +672,43 @@ false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultSSLOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, false, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultSSLOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultSSLOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), net::HostPortPair::FromURL(GURL()), false, false, true }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultDevOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultDevOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, true, true, - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultDevOrigin())), - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultDevFallbackOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultDevOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultDevFallbackOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), false, false, false }, { - net::HostPortPair::FromURL(GURL( - TestDataReductionProxyParams::DefaultOrigin())), + net::ProxyServer::FromURI( + TestDataReductionProxyParams::DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP).host_port_pair(), true, true, true, @@ -714,10 +737,23 @@ EXPECT_EQ(tests[i].expected_result, params.IsDataReductionProxy( tests[i].host_port_pair, &proxy_type_info)) << i; - EXPECT_TRUE(tests[i].expected_first.Equals( - net::HostPortPair::FromURL(proxy_type_info.proxy_servers.first))) << i; - EXPECT_TRUE(tests[i].expected_second.Equals( - net::HostPortPair::FromURL(proxy_type_info.proxy_servers.second))) << i; + EXPECT_EQ(net::ProxyServer::FromURI( + tests[i].expected_first.ToString(), + net::ProxyServer::SCHEME_HTTP).is_valid(), + proxy_type_info.proxy_servers.first.is_valid()) << i; + if (proxy_type_info.proxy_servers.first.is_valid()) { + EXPECT_TRUE(tests[i].expected_first.Equals( + proxy_type_info.proxy_servers.first.host_port_pair())) << i; + } + EXPECT_EQ(net::ProxyServer::FromURI( + tests[i].expected_second.ToString(), + net::ProxyServer::SCHEME_HTTP).is_valid(), + proxy_type_info.proxy_servers.second.is_valid()) << i; + if (proxy_type_info.proxy_servers.second.is_valid()) { + EXPECT_TRUE(tests[i].expected_second.Equals( + proxy_type_info.proxy_servers.second.host_port_pair())) << i; + } + EXPECT_EQ(tests[i].expected_is_fallback, proxy_type_info.is_fallback) << i; EXPECT_EQ(tests[i].expected_is_alternative, proxy_type_info.is_alternative) << i; @@ -727,9 +763,7 @@ std::string GetRetryMapKeyFromOrigin(std::string origin) { // The retry map has the scheme prefix for https but not for http - return net::ProxyServer(GURL(origin).SchemeIs(url::kHttpsScheme) ? - net::ProxyServer::SCHEME_HTTPS : net::ProxyServer::SCHEME_HTTP, - net::HostPortPair::FromURL(GURL(origin))).ToURI(); + return origin; } TEST_F(DataReductionProxyParamsTest, AreProxiesBypassed) {
diff --git a/components/devtools_bridge/android/session_dependency_factory_android.cc b/components/devtools_bridge/android/session_dependency_factory_android.cc index 7f3ea56..50c81c5 100644 --- a/components/devtools_bridge/android/session_dependency_factory_android.cc +++ b/components/devtools_bridge/android/session_dependency_factory_android.cc
@@ -39,15 +39,15 @@ connected_ = false; } - virtual void OnIceConnectionChange(bool connected) override { + void OnIceConnectionChange(bool connected) override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyIceConnectionChange( env, java_object_.obj(), connected); } - virtual void OnIceCandidate( - const std::string& sdp_mid, int sdp_mline_index, const std::string& sdp) - override { + void OnIceCandidate(const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp) override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyIceCandidate( env, java_object_.obj(), @@ -62,29 +62,27 @@ ConvertUTF8ToJavaString(env, description).obj()); } - virtual void OnLocalOfferCreatedAndSetSet(const std::string& description) - override { + void OnLocalOfferCreatedAndSetSet(const std::string& description) override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet( env, java_object_.obj(), ConvertUTF8ToJavaString(env, description).obj()); } - virtual void OnLocalAnswerCreatedAndSetSet(const std::string& description) - override { + void OnLocalAnswerCreatedAndSetSet(const std::string& description) override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyLocalAnswerCreatedAndSetSet( env, java_object_.obj(), ConvertUTF8ToJavaString(env, description).obj()); } - virtual void OnRemoteDescriptionSet() override { + void OnRemoteDescriptionSet() override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyRemoteDescriptionSet( env, java_object_.obj()); } - virtual void OnFailure(const std::string& description) override { + void OnFailure(const std::string& description) override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyConnectionFailure( env, java_object_.obj(), @@ -102,19 +100,19 @@ java_object_.Reset(env, java_object); } - virtual void OnOpen() override { + void OnOpen() override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyChannelOpen( env, java_object_.obj()); } - virtual void OnClose() override { + void OnClose() override { JNIEnv* env = AttachCurrentThread(); Java_SessionDependencyFactoryNative_notifyChannelClose( env, java_object_.obj()); } - virtual void OnMessage(const void* data, size_t length) override { + void OnMessage(const void* data, size_t length) override { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> byte_buffer(
diff --git a/components/devtools_bridge/android/session_dependency_factory_android.h b/components/devtools_bridge/android/session_dependency_factory_android.h index 384d3d9..24496de1 100644 --- a/components/devtools_bridge/android/session_dependency_factory_android.h +++ b/components/devtools_bridge/android/session_dependency_factory_android.h
@@ -14,17 +14,16 @@ class SessionDependencyFactoryAndroid : public SessionDependencyFactory { public: SessionDependencyFactoryAndroid(); - virtual ~SessionDependencyFactoryAndroid(); + ~SessionDependencyFactoryAndroid() override; static bool RegisterNatives(JNIEnv* env); - virtual scoped_ptr<AbstractPeerConnection> CreatePeerConnection( + scoped_ptr<AbstractPeerConnection> CreatePeerConnection( scoped_ptr<RTCConfiguration> config, scoped_ptr<AbstractPeerConnection::Delegate> delegate) override; - virtual scoped_refptr<base::TaskRunner> signaling_thread_task_runner() - override; - virtual scoped_refptr<base::TaskRunner> io_thread_task_runner() override; + scoped_refptr<base::TaskRunner> signaling_thread_task_runner() override; + scoped_refptr<base::TaskRunner> io_thread_task_runner() override; private: const scoped_ptr<SessionDependencyFactory> impl_;
diff --git a/components/devtools_bridge/session_dependency_factory.cc b/components/devtools_bridge/session_dependency_factory.cc index c7d4a98..567771f 100644 --- a/components/devtools_bridge/session_dependency_factory.cc +++ b/components/devtools_bridge/session_dependency_factory.cc
@@ -25,11 +25,9 @@ : public RTCConfiguration, public webrtc::PeerConnectionInterface::RTCConfiguration { public: - - virtual void AddIceServer( - const std::string& uri, - const std::string& username, - const std::string& credential) override { + void AddIceServer(const std::string& uri, + const std::string& username, + const std::string& credential) override { webrtc::PeerConnectionInterface::IceServer server; server.uri = uri; server.username = username; @@ -55,15 +53,11 @@ class MediaConstraints : public webrtc::MediaConstraintsInterface { public: - virtual ~MediaConstraints() {} + ~MediaConstraints() override {} - virtual const Constraints& GetMandatory() const override { - return mandatory_; - } + const Constraints& GetMandatory() const override { return mandatory_; } - virtual const Constraints& GetOptional() const override { - return optional_; - } + const Constraints& GetOptional() const override { return optional_; } void AddMandatory(const std::string& key, const std::string& value) { mandatory_.push_back(Constraint(key, value)); @@ -133,7 +127,7 @@ open_ = data_channel_->state() == webrtc::DataChannelInterface::kOpen; } - virtual void OnStateChange() override { + void OnStateChange() override { bool open = data_channel_->state() == webrtc::DataChannelInterface::kOpen; if (open == open_) return; @@ -146,7 +140,7 @@ } } - virtual void OnMessage(const webrtc::DataBuffer& buffer) override { + void OnMessage(const webrtc::DataBuffer& buffer) override { observer_->OnMessage(buffer.data.data(), buffer.size()); } @@ -173,7 +167,7 @@ data_channel_ = NULL; } - virtual void SendBinaryMessage(const void* data, size_t length) override { + void SendBinaryMessage(const void* data, size_t length) override { auto buffer = make_scoped_ptr(new webrtc::DataBuffer(rtc::Buffer(), true)); buffer->data.SetData(data, length); @@ -184,7 +178,7 @@ base::Passed(&buffer))); } - virtual void Close() override { + void Close() override { signaling_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&DataChannelProxyImpl::CloseOnSignalingThread, this)); @@ -221,30 +215,30 @@ impl_(impl) { } - ~DataChannelImpl() { + ~DataChannelImpl() override { if (proxy_.get()) { signaling_thread_->Invoke<void>(rtc::Bind( &DataChannelProxyImpl::StopOnSignalingThread, proxy_.get())); } } - virtual void RegisterObserver(scoped_ptr<Observer> observer) override { + void RegisterObserver(scoped_ptr<Observer> observer) override { observer_.reset(new DataChannelObserverImpl(impl_.get(), observer.Pass())); signaling_thread_->Invoke<void>(rtc::Bind( &DataChannelImpl::RegisterObserverOnSignalingThread, this)); } - virtual void UnregisterObserver() override { + void UnregisterObserver() override { DCHECK(observer_.get() != NULL); impl_->UnregisterObserver(); observer_.reset(); } - virtual void SendBinaryMessage(void* data, size_t length) override { + void SendBinaryMessage(void* data, size_t length) override { SendMessage(data, length, true); } - virtual void SendTextMessage(void* data, size_t length) override { + void SendTextMessage(void* data, size_t length) override { SendMessage(data, length, false); } @@ -285,20 +279,18 @@ connected_(false) { } - virtual void OnAddStream(webrtc::MediaStreamInterface* stream) override {} + void OnAddStream(webrtc::MediaStreamInterface* stream) override {} - virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) override {} + void OnRemoveStream(webrtc::MediaStreamInterface* stream) override {} - virtual void OnDataChannel(webrtc::DataChannelInterface* data_channel) - override {} + void OnDataChannel(webrtc::DataChannelInterface* data_channel) override {} - virtual void OnRenegotiationNeeded() override {} + void OnRenegotiationNeeded() override {} - virtual void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) override { - } + void OnSignalingChange( + webrtc::PeerConnectionInterface::SignalingState new_state) override {} - virtual void OnIceConnectionChange( + void OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) override { bool connected = new_state == webrtc::PeerConnectionInterface::kIceConnectionConnected || @@ -310,8 +302,7 @@ } } - virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) - override { + void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { std::string sdp; candidate->ToString(&sdp); @@ -341,9 +332,7 @@ disposed_(false) { } - virtual ~PeerConnectionHolder() { - DCHECK(disposed_); - } + ~PeerConnectionHolder() override { DCHECK(disposed_); } void Dispose() { DCHECK(!IsDisposed()); @@ -381,7 +370,7 @@ : holder_(holder) { } - virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { + void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { if (holder_->IsDisposed()) return; type_ = desc->type(); @@ -392,7 +381,7 @@ } } - virtual void OnSuccess() override { + void OnSuccess() override { if (holder_->IsDisposed()) return; if (type_ == webrtc::SessionDescriptionInterface::kOffer) { @@ -404,7 +393,7 @@ } } - virtual void OnFailure(const std::string& error) override { + void OnFailure(const std::string& error) override { if (holder_->IsDisposed()) return; holder_->delegate()->OnFailure(error); @@ -424,13 +413,13 @@ : holder_(holder) { } - virtual void OnSuccess() override { + void OnSuccess() override { if (holder_->IsDisposed()) return; holder_->delegate()->OnRemoteDescriptionSet(); } - virtual void OnFailure(const std::string& error) override { + void OnFailure(const std::string& error) override { if (holder_->IsDisposed()) return; holder_->delegate()->OnFailure(error); @@ -457,25 +446,25 @@ delegate_(delegate.Pass()) { } - virtual ~PeerConnectionImpl() { + ~PeerConnectionImpl() override { signaling_thread_->Invoke<void>(rtc::Bind( &PeerConnectionImpl::DisposeOnSignalingThread, this)); } - virtual void CreateAndSetLocalOffer() override { + void CreateAndSetLocalOffer() override { connection_->CreateOffer(MakeCreateAndSetHandler(), NULL); } - virtual void CreateAndSetLocalAnswer() override { + void CreateAndSetLocalAnswer() override { connection_->CreateAnswer(MakeCreateAndSetHandler(), NULL); } - virtual void SetRemoteOffer(const std::string& description) override { + void SetRemoteOffer(const std::string& description) override { SetRemoteDescription( webrtc::SessionDescriptionInterface::kOffer, description); } - virtual void SetRemoteAnswer(const std::string& description) override { + void SetRemoteAnswer(const std::string& description) override { SetRemoteDescription( webrtc::SessionDescriptionInterface::kAnswer, description); } @@ -495,10 +484,9 @@ value.release()); } - virtual void AddIceCandidate( - const std::string& sdp_mid, - int sdp_mline_index, - const std::string& sdp) override { + void AddIceCandidate(const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp) override { webrtc::SdpParseError error; auto candidate = webrtc::CreateIceCandidate( sdp_mid, sdp_mline_index, sdp, &error); @@ -511,8 +499,7 @@ delete candidate; } - virtual scoped_ptr<AbstractDataChannel> CreateDataChannel( - int channelId) override { + scoped_ptr<AbstractDataChannel> CreateDataChannel(int channelId) override { webrtc::DataChannelInit init; init.ordered = true; init.negotiated = true; @@ -562,7 +549,7 @@ &worker_thread_, &signaling_thread_, NULL, NULL, NULL); } - virtual ~SessionDependencyFactoryImpl() { + ~SessionDependencyFactoryImpl() override { if (signaling_thread_task_runner_.get()) signaling_thread_task_runner_->Stop(); @@ -570,7 +557,7 @@ &SessionDependencyFactoryImpl::DisposeOnSignalingThread, this)); } - virtual scoped_ptr<AbstractPeerConnection> CreatePeerConnection( + scoped_ptr<AbstractPeerConnection> CreatePeerConnection( scoped_ptr<RTCConfiguration> config, scoped_ptr<AbstractPeerConnection::Delegate> delegate) override { auto observer = make_scoped_ptr(
diff --git a/components/devtools_bridge/socket_tunnel_server.cc b/components/devtools_bridge/socket_tunnel_server.cc index 1297916..afa07a2 100644 --- a/components/devtools_bridge/socket_tunnel_server.cc +++ b/components/devtools_bridge/socket_tunnel_server.cc
@@ -56,7 +56,7 @@ ReadNextChunk(); } - virtual void OnReadError(int error) override { + void OnReadError(int error) override { socket()->Disconnect(); SendControlPacket(SERVER_CLOSE); delegate_->RemoveConnection(index_);
diff --git a/components/dom_distiller/core/distilled_page_prefs_android.h b/components/dom_distiller/core/distilled_page_prefs_android.h index bcb96c2..de3928e 100644 --- a/components/dom_distiller/core/distilled_page_prefs_android.h +++ b/components/dom_distiller/core/distilled_page_prefs_android.h
@@ -40,9 +40,9 @@ virtual ~DistilledPagePrefsObserverAndroid(); // DistilledPagePrefs::Observer implementation. - virtual void OnChangeFontFamily( + void OnChangeFontFamily( DistilledPagePrefs::FontFamily new_font_family) override; - virtual void OnChangeTheme(DistilledPagePrefs::Theme new_theme) override; + void OnChangeTheme(DistilledPagePrefs::Theme new_theme) override; virtual void DestroyObserverAndroid(JNIEnv* env, jobject obj);
diff --git a/components/enhanced_bookmarks.gypi b/components/enhanced_bookmarks.gypi index 2048493..8b913fa8 100644 --- a/components/enhanced_bookmarks.gypi +++ b/components/enhanced_bookmarks.gypi
@@ -92,4 +92,20 @@ 'includes': [ '../build/protoc.gypi' ], }, ], + 'conditions' : [ + ['OS=="android"', { + 'targets': [ + { + # GN: //components/enhanced_bookmarks:enhanced_bookmarks_launch_location_srcjar + 'target_name': 'enhanced_bookmarks_launch_location_srcjar', + 'type': 'none', + 'variables': { + 'source_file': 'enhanced_bookmarks/enhanced_bookmark_utils.h', + }, + 'includes': [ '../build/android/java_cpp_enum.gypi' ], + }, + ], + }, + ], + ], }
diff --git a/components/enhanced_bookmarks/BUILD.gn b/components/enhanced_bookmarks/BUILD.gn index 7ce7ed5..11462c4 100644 --- a/components/enhanced_bookmarks/BUILD.gn +++ b/components/enhanced_bookmarks/BUILD.gn
@@ -2,6 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +if (is_android) { + import("//build/config/android/config.gni") + import("//build/config/android/rules.gni") +} + # GYP: //components/enhanced_bookmarks.gypi:enhanced_bookmarks source_set("enhanced_bookmarks") { sources = [ @@ -49,6 +54,18 @@ } } +if (is_android) { + # GYP: //components/enhanced_bookmarks.gypi:enhanced_bookmarks_launch_location_srcjar + java_cpp_enum("enhanced_bookmarks_launch_location_srcjar") { + sources = [ + "enhanced_bookmark_utils.h", + ] + outputs = [ + "org/chromium/chrome/browser/enhancedbookmark/LaunchLocation.java", + ] + } +} + # GYP: //components/enhanced_bookmarks.gypi:enhanced_bookmarks_test_support source_set("test_support") { testonly = true
diff --git a/components/enhanced_bookmarks/bookmark_image_service.cc b/components/enhanced_bookmarks/bookmark_image_service.cc index c2c019e..683ae6e 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.cc +++ b/components/enhanced_bookmarks/bookmark_image_service.cc
@@ -16,6 +16,7 @@ #include "components/enhanced_bookmarks/persistent_image_store.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace { @@ -165,7 +166,7 @@ } void BookmarkImageService::SalientImageForUrl(const GURL& page_url, - bool fetch_from_bookmark, + bool fetch_from_web, ImageCallback callback) { DCHECK(CalledOnValidThread()); @@ -176,7 +177,7 @@ return; } - if (!fetch_from_bookmark) { + if (!fetch_from_web) { RetrieveImageFromStore(page_url, callback); } else { RetrieveImageFromStore(page_url,
diff --git a/components/enhanced_bookmarks/bookmark_image_service.h b/components/enhanced_bookmarks/bookmark_image_service.h index 5bf2637..8ec1fa8 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.h +++ b/components/enhanced_bookmarks/bookmark_image_service.h
@@ -17,7 +17,10 @@ namespace base { class SingleThreadTaskRunner; } + +namespace bookmarks { class BookmarkNode; +} namespace enhanced_bookmarks { @@ -51,28 +54,29 @@ // bookmarks::BookmarkModelObserver: void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override; void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, + const bookmarks::BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, + const bookmarks::BookmarkNode* new_parent, int new_index) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void OnWillChangeBookmarkNode(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void BookmarkNodeChildrenReordered( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; @@ -80,8 +84,8 @@ // Returns true if the image for the page_url is currently being fetched. bool IsPageUrlInProgress(const GURL& page_url); - // Once an image has been retrieved, store the image and notify all the - // consumers that were waiting on it. + // Stores the image to local storage. If update_bookmarks is true, relates the + // corresponding bookmark to image_url. void ProcessNewImage(const GURL& page_url, bool update_bookmarks, const gfx::Image& image, @@ -109,10 +113,10 @@ EnhancedBookmarkModel* enhanced_bookmark_model_; private: - // Same as SalientImageForUrl(const GURL&, ImageCallback) but can - // prevent the network request if fetch_from_bookmark is false. + // If fetch_from_web is true, retrieves the salient image via a network + // request; else only gets the image from local storage. void SalientImageForUrl(const GURL& page_url, - bool fetch_from_bookmark, + bool fetch_from_web, ImageCallback stack_callback); // Processes the requests that have been waiting on an image. @@ -178,3 +182,4 @@ } // namespace enhanced_bookmarks #endif // COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_IMAGE_SERVICE_H_ +
diff --git a/components/enhanced_bookmarks/bookmark_server_cluster_service.cc b/components/enhanced_bookmarks/bookmark_server_cluster_service.cc index 2eeb45ed..e433717 100644 --- a/components/enhanced_bookmarks/bookmark_server_cluster_service.cc +++ b/components/enhanced_bookmarks/bookmark_server_cluster_service.cc
@@ -20,6 +20,8 @@ #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" +using bookmarks::BookmarkNode; + namespace { const char kClusterUrl[] = "https://www.google.com/stars/cluster"; const int kPrefServiceVersion = 1;
diff --git a/components/enhanced_bookmarks/bookmark_server_cluster_service.h b/components/enhanced_bookmarks/bookmark_server_cluster_service.h index cc3ae513..6c2a678 100644 --- a/components/enhanced_bookmarks/bookmark_server_cluster_service.h +++ b/components/enhanced_bookmarks/bookmark_server_cluster_service.h
@@ -43,12 +43,12 @@ // Retrieves all the bookmarks associated with a cluster. The returned // BookmarkNodes are owned by the bookmark model, and one must listen to the // model observer notification to clear them. - const std::vector<const BookmarkNode*> BookmarksForClusterNamed( + const std::vector<const bookmarks::BookmarkNode*> BookmarksForClusterNamed( const std::string& cluster_name) const; // Returns the clusters in which the passed bookmark is in, if any. const std::vector<std::string> ClustersForBookmark( - const BookmarkNode* bookmark) const; + const bookmarks::BookmarkNode* bookmark) const; // Dynamically generates a vector of all clusters names. const std::vector<std::string> GetClusters() const; @@ -65,11 +65,12 @@ // EnhancedBookmarkModelObserver methods. void EnhancedBookmarkModelLoaded() override; - void EnhancedBookmarkAdded(const BookmarkNode* node) override; - void EnhancedBookmarkRemoved(const BookmarkNode* node) override; - void EnhancedBookmarkNodeChanged(const BookmarkNode* node) override; + void EnhancedBookmarkAdded(const bookmarks::BookmarkNode* node) override; + void EnhancedBookmarkRemoved(const bookmarks::BookmarkNode* node) override; + void EnhancedBookmarkNodeChanged( + const bookmarks::BookmarkNode* node) override; void EnhancedBookmarkAllUserNodesRemoved() override; - void EnhancedBookmarkRemoteIdChanged(const BookmarkNode* node, + void EnhancedBookmarkRemoteIdChanged(const bookmarks::BookmarkNode* node, const std::string& old_remote_id, const std::string& remote_id) override;
diff --git a/components/enhanced_bookmarks/bookmark_server_search_service.cc b/components/enhanced_bookmarks/bookmark_server_search_service.cc index e1ab78e..063fa388 100644 --- a/components/enhanced_bookmarks/bookmark_server_search_service.cc +++ b/components/enhanced_bookmarks/bookmark_server_search_service.cc
@@ -10,6 +10,8 @@ #include "net/base/url_util.h" #include "net/url_request/url_fetcher.h" +using bookmarks::BookmarkNode; + namespace { const char kSearchUrl[] = "https://www.google.com/stars/search"; const int kSearchCacheMaxSize = 50;
diff --git a/components/enhanced_bookmarks/bookmark_server_search_service.h b/components/enhanced_bookmarks/bookmark_server_search_service.h index f178447..5b4c619 100644 --- a/components/enhanced_bookmarks/bookmark_server_search_service.h +++ b/components/enhanced_bookmarks/bookmark_server_search_service.h
@@ -40,7 +40,7 @@ // loading and no results have come to the client. Previously cancelled // queries will not trigger onChange(), and this method will also return null // for queries that have never been passed to Search() before. - scoped_ptr<std::vector<const BookmarkNode*>> ResultForQuery( + scoped_ptr<std::vector<const bookmarks::BookmarkNode*>> ResultForQuery( const std::string& query); protected: @@ -53,11 +53,12 @@ // EnhancedBookmarkModelObserver methods. void EnhancedBookmarkModelLoaded() override{}; - void EnhancedBookmarkAdded(const BookmarkNode* node) override; - void EnhancedBookmarkRemoved(const BookmarkNode* node) override{}; - void EnhancedBookmarkNodeChanged(const BookmarkNode* node) override{}; + void EnhancedBookmarkAdded(const bookmarks::BookmarkNode* node) override; + void EnhancedBookmarkRemoved(const bookmarks::BookmarkNode* node) override {} + void EnhancedBookmarkNodeChanged( + const bookmarks::BookmarkNode* node) override {} void EnhancedBookmarkAllUserNodesRemoved() override; - void EnhancedBookmarkRemoteIdChanged(const BookmarkNode* node, + void EnhancedBookmarkRemoteIdChanged(const bookmarks::BookmarkNode* node, const std::string& old_remote_id, const std::string& remote_id) override; @@ -70,6 +71,7 @@ std::string current_query_; DISALLOW_COPY_AND_ASSIGN(BookmarkServerSearchService); }; + } // namespace enhanced_bookmarks #endif // COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_SERVER_SEARCH_SERVICE_H_
diff --git a/components/enhanced_bookmarks/bookmark_server_service.cc b/components/enhanced_bookmarks/bookmark_server_service.cc index 73cd8f8..23c85b1 100644 --- a/components/enhanced_bookmarks/bookmark_server_service.cc +++ b/components/enhanced_bookmarks/bookmark_server_service.cc
@@ -13,6 +13,8 @@ #include "net/url_request/url_request_context_getter.h" #include "ui/base/models/tree_node_iterator.h" +using bookmarks::BookmarkNode; + namespace enhanced_bookmarks { BookmarkServerService::BookmarkServerService(
diff --git a/components/enhanced_bookmarks/bookmark_server_service.h b/components/enhanced_bookmarks/bookmark_server_service.h index 9f2fd52e..45190332 100644 --- a/components/enhanced_bookmarks/bookmark_server_service.h +++ b/components/enhanced_bookmarks/bookmark_server_service.h
@@ -17,7 +17,10 @@ class ProfileOAuth2TokenService; class SigninManagerBase; + +namespace bookmarks { class BookmarkNode; +} namespace enhanced_bookmarks { @@ -53,9 +56,10 @@ protected: // Retrieves a bookmark by using its remote id. Returns null if nothing // matches. - virtual const BookmarkNode* BookmarkForRemoteId( + virtual const bookmarks::BookmarkNode* BookmarkForRemoteId( const std::string& remote_id) const; - const std::string RemoteIDForBookmark(const BookmarkNode* bookmark) const; + const std::string RemoteIDForBookmark( + const bookmarks::BookmarkNode* bookmark) const; // Cancels the ongoing request, if any. void Cancel(); @@ -123,3 +127,4 @@ } // namespace enhanced_bookmarks #endif // COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_SERVER_SERVICE_H_ +
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.cc b/components/enhanced_bookmarks/enhanced_bookmark_model.cc index f114c5a..42bb5ce 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model.cc +++ b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
@@ -20,11 +20,11 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace { const char* kBookmarkBarId = "f_bookmarks_bar"; -const char* kFlagsKey = "stars.flags"; const char* kIdKey = "stars.id"; const char* kImageDataKey = "stars.imageData"; const char* kNoteKey = "stars.note"; @@ -34,11 +34,6 @@ const char* kBookmarkPrefix = "ebc_"; -enum Flags { - // When set the server will attempt to fill in image and snippet information. - NEEDS_OFFLINE_PROCESSING = 0x1, -}; - // Helper method for working with bookmark metainfo. std::string DataForMetaInfoField(const BookmarkNode* node, const std::string& field) { @@ -311,14 +306,6 @@ if (node->GetMetaInfo(kIdKey, &remote_id)) { AddToIdMap(node); ScheduleResetDuplicateRemoteIds(); - } else if (node->is_url()) { - set_needs_offline_processing_tasks_[node] = - make_linked_ptr(new base::CancelableClosure( - base::Bind(&EnhancedBookmarkModel::SetNeedsOfflineProcessing, - weak_ptr_factory_.GetWeakPtr(), - base::Unretained(node)))); - base::MessageLoopProxy::current()->PostTask( - FROM_HERE, set_needs_offline_processing_tasks_[node]->callback()); } FOR_EACH_OBSERVER( EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkAdded(node)); @@ -407,7 +394,6 @@ std::string remote_id = GetRemoteId(node); id_map_.erase(remote_id); nodes_to_reset_.erase(node); - set_needs_offline_processing_tasks_.erase(node); } void EnhancedBookmarkModel::ScheduleResetDuplicateRemoteIds() { @@ -431,19 +417,6 @@ nodes_to_reset_.clear(); } -void EnhancedBookmarkModel::SetNeedsOfflineProcessing( - const BookmarkNode* node) { - set_needs_offline_processing_tasks_.erase(node); - int flags = 0; - std::string flags_str; - if (node->GetMetaInfo(kFlagsKey, &flags_str)) { - if (!base::StringToInt(flags_str, &flags)) - flags = 0; - } - flags |= NEEDS_OFFLINE_PROCESSING; - SetMetaInfo(node, kFlagsKey, base::IntToString(flags)); -} - void EnhancedBookmarkModel::SetMetaInfo(const BookmarkNode* node, const std::string& field, const std::string& value) {
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.h b/components/enhanced_bookmarks/enhanced_bookmark_model.h index 1660237..9bc5e89 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model.h +++ b/components/enhanced_bookmarks/enhanced_bookmark_model.h
@@ -17,7 +17,6 @@ #include "components/bookmarks/browser/bookmark_node.h" #include "components/keyed_service/core/keyed_service.h" -class BookmarkNode; class GURL; namespace base { @@ -26,6 +25,7 @@ namespace bookmarks { class BookmarkModel; +class BookmarkNode; } FORWARD_DECLARE_TEST(EnhancedBookmarkModelTest, SetMultipleMetaInfo); @@ -49,51 +49,54 @@ void RemoveObserver(EnhancedBookmarkModelObserver* observer); // Moves |node| to |new_parent| and inserts it at the given |index|. - void Move(const BookmarkNode* node, - const BookmarkNode* new_parent, + void Move(const bookmarks::BookmarkNode* node, + const bookmarks::BookmarkNode* new_parent, int index); // Adds a new folder node at the specified position. - const BookmarkNode* AddFolder(const BookmarkNode* parent, - int index, - const base::string16& title); + const bookmarks::BookmarkNode* AddFolder( + const bookmarks::BookmarkNode* parent, + int index, + const base::string16& title); // Adds a url at the specified position. - const BookmarkNode* AddURL(const BookmarkNode* parent, - int index, - const base::string16& title, - const GURL& url, - const base::Time& creation_time); + const bookmarks::BookmarkNode* AddURL(const bookmarks::BookmarkNode* parent, + int index, + const base::string16& title, + const GURL& url, + const base::Time& creation_time); // Returns the remote id for a bookmark |node|. - std::string GetRemoteId(const BookmarkNode* node); + std::string GetRemoteId(const bookmarks::BookmarkNode* node); // Returns the bookmark node corresponding to the given |remote_id|, or NULL // if there is no node with the id. - const BookmarkNode* BookmarkForRemoteId(const std::string& remote_id); + const bookmarks::BookmarkNode* BookmarkForRemoteId( + const std::string& remote_id); // Sets the description of a bookmark |node|. - void SetDescription(const BookmarkNode* node, const std::string& description); + void SetDescription(const bookmarks::BookmarkNode* node, + const std::string& description); // Returns the description of a bookmark |node|. - std::string GetDescription(const BookmarkNode* node); + std::string GetDescription(const bookmarks::BookmarkNode* node); // Sets the URL of an image representative of a bookmark |node|. // Expects the URL to be valid and not empty. // Returns true if the metainfo is successfully populated. - bool SetOriginalImage(const BookmarkNode* node, + bool SetOriginalImage(const bookmarks::BookmarkNode* node, const GURL& url, int width, int height); // Removes all image data for the node and sets the user_removed_image flag // so the server won't try to fetch a new image for the node. - void RemoveImageData(const BookmarkNode* node); + void RemoveImageData(const bookmarks::BookmarkNode* node); // Returns the url and dimensions of the original scraped image of a // bookmark |node|. // Returns true if the out variables are populated, false otherwise. - bool GetOriginalImage(const BookmarkNode* node, + bool GetOriginalImage(const bookmarks::BookmarkNode* node, GURL* url, int* width, int* height); @@ -101,14 +104,14 @@ // Returns the url and dimensions of the server provided thumbnail image for // a given bookmark |node|. // Returns true if the out variables are populated, false otherwise. - bool GetThumbnailImage(const BookmarkNode* node, + bool GetThumbnailImage(const bookmarks::BookmarkNode* node, GURL* url, int* width, int* height); // Returns a brief server provided synopsis of the bookmarked page. // Returns the empty string if the snippet could not be extracted. - std::string GetSnippet(const BookmarkNode* node); + std::string GetSnippet(const bookmarks::BookmarkNode* node); // Sets a custom suffix to be added to the version field when writing meta // info fields. @@ -121,7 +124,7 @@ // Expects valid or empty urls. Returns true if the metainfo is successfully // populated. // TODO(rfevang): Move this to a testing only utility file. - bool SetAllImages(const BookmarkNode* node, + bool SetAllImages(const bookmarks::BookmarkNode* node, const GURL& image_url, int image_width, int image_height, @@ -142,27 +145,28 @@ private: FRIEND_TEST_ALL_PREFIXES(::EnhancedBookmarkModelTest, SetMultipleMetaInfo); - typedef std::map<std::string, const BookmarkNode*> IdToNodeMap; - typedef std::map<const BookmarkNode*, std::string> NodeToIdMap; + typedef std::map<std::string, const bookmarks::BookmarkNode*> IdToNodeMap; + typedef std::map<const bookmarks::BookmarkNode*, std::string> NodeToIdMap; // bookmarks::BaseBookmarkModelObserver: void BookmarkModelChanged() override; void BookmarkModelLoaded(bookmarks::BookmarkModel* model, bool ids_reassigned) override; void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int index) override; void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, + const bookmarks::BookmarkNode* parent, int old_index, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::set<GURL>& removed_urls) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - void OnWillChangeBookmarkMetaInfo(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; + void OnWillChangeBookmarkMetaInfo( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override; void BookmarkMetaInfoChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + const bookmarks::BookmarkNode* node) override; void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; @@ -171,10 +175,10 @@ // Adds a node to the id map if it has a (unique) remote id. Must be followed // by a (Schedule)ResetDuplicateRemoteIds call when done adding nodes. - void AddToIdMap(const BookmarkNode* node); + void AddToIdMap(const bookmarks::BookmarkNode* node); // Recursively removes a node and all its children from the various maps. - void RemoveNodeFromMaps(const BookmarkNode* node); + void RemoveNodeFromMaps(const bookmarks::BookmarkNode* node); // If there are nodes that needs to reset their remote ids, schedules // ResetDuplicateRemoteIds to be run asynchronously. @@ -183,20 +187,17 @@ // Clears out any duplicate remote ids detected by AddToIdMap calls. void ResetDuplicateRemoteIds(); - // Sets the NEEDS_OFFLINE_PROCESSING flag on the given node. - void SetNeedsOfflineProcessing(const BookmarkNode* node); - // Helper method for setting a meta info field on a node. Also updates the // version field. - void SetMetaInfo(const BookmarkNode* node, + void SetMetaInfo(const bookmarks::BookmarkNode* node, const std::string& field, const std::string& value); // Helper method for setting multiple meta info fields at once. All the fields // in |meta_info| will be set, but the method will not delete fields not // present. - void SetMultipleMetaInfo(const BookmarkNode* node, - BookmarkNode::MetaInfoMap meta_info); + void SetMultipleMetaInfo(const bookmarks::BookmarkNode* node, + bookmarks::BookmarkNode::MetaInfoMap meta_info); bookmarks::BookmarkModel* bookmark_model_; bool loaded_; @@ -206,11 +207,6 @@ IdToNodeMap id_map_; NodeToIdMap nodes_to_reset_; - // Pending SetNeedsOfflineProcessing calls are stored here, as they may need - // to be cancelled if the node is removed. - std::map<const BookmarkNode*, linked_ptr<base::CancelableClosure>> - set_needs_offline_processing_tasks_; - // Caches the remote id of a node before its meta info changes. std::string prev_remote_id_;
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model_observer.h b/components/enhanced_bookmarks/enhanced_bookmark_model_observer.h index eb83b57..45714fb 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model_observer.h +++ b/components/enhanced_bookmarks/enhanced_bookmark_model_observer.h
@@ -7,7 +7,9 @@ #include <string> +namespace bookmarks { class BookmarkNode; +} namespace enhanced_bookmarks { @@ -20,13 +22,14 @@ virtual void EnhancedBookmarkModelShuttingDown() = 0; // Called when a node is added to the model. - virtual void EnhancedBookmarkAdded(const BookmarkNode* node) = 0; + virtual void EnhancedBookmarkAdded(const bookmarks::BookmarkNode* node) = 0; // Called when a node is removed from the model. - virtual void EnhancedBookmarkRemoved(const BookmarkNode* node) = 0; + virtual void EnhancedBookmarkRemoved(const bookmarks::BookmarkNode* node) = 0; // Called when a node has changed. - virtual void EnhancedBookmarkNodeChanged(const BookmarkNode* node) = 0; + virtual void EnhancedBookmarkNodeChanged( + const bookmarks::BookmarkNode* node) = 0; // Called when all user editable nodes are removed from the model. virtual void EnhancedBookmarkAllUserNodesRemoved() = 0; @@ -34,13 +37,15 @@ // Called when the remote id of a node changes. If |remote_id| is empty, the // remote id has been cleared. This could happen if multiple nodes with the // same remote id has been detected. - virtual void EnhancedBookmarkRemoteIdChanged(const BookmarkNode* node, - const std::string& old_remote_id, - const std::string& remote_id) {}; + virtual void EnhancedBookmarkRemoteIdChanged( + const bookmarks::BookmarkNode* node, + const std::string& old_remote_id, + const std::string& remote_id) {} protected: virtual ~EnhancedBookmarkModelObserver() {} }; } // namespace enhanced_bookmarks + #endif // COMPONENTS_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARK_MODEL_OBSERVER_H_
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc index f760d0c..4b53abdf 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc +++ b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc
@@ -21,6 +21,7 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; using enhanced_bookmarks::EnhancedBookmarkModel; namespace { @@ -678,85 +679,6 @@ base::RunLoop().RunUntilIdle(); } -// Verifies that the NEEDS_OFFLINE_PROCESSING flag is set for nodes added -// with no remote id. -TEST_F(EnhancedBookmarkModelTest, BookmarkAddedSetsOfflineProcessingFlag) { - const BookmarkNode* node = - bookmark_model_->AddURL(bookmark_model_->other_node(), - 0, - base::ASCIIToUTF16("Some title"), - GURL(BOOKMARK_URL)); - std::string flags_str; - EXPECT_FALSE(node->GetMetaInfo("stars.flags", &flags_str)); - base::RunLoop().RunUntilIdle(); - ASSERT_TRUE(node->GetMetaInfo("stars.flags", &flags_str)); - int flags; - ASSERT_TRUE(base::StringToInt(flags_str, &flags)); - EXPECT_EQ(1, (flags & 1)); -} - -// Verifies that the NEEDS_OFFLINE_PROCESSING_FLAG is not set for added folders. -TEST_F(EnhancedBookmarkModelTest, FolderAddedDoesNotSetOfflineProcessingFlag) { - const BookmarkNode* node = AddFolder(); - base::RunLoop().RunUntilIdle(); - - std::string flags_str; - if (node->GetMetaInfo("stars.flags", &flags_str)) { - int flags; - ASSERT_TRUE(base::StringToInt(flags_str, &flags)); - EXPECT_EQ(0, (flags & 1)); - } -} - -// Verifies that when a bookmark is added that has a remote id, the status of -// the NEEDS_OFFLINE_PROCESSING flag doesn't change. -TEST_F(EnhancedBookmarkModelTest, - BookmarkAddedWithIdKeepsOfflineProcessingFlag) { - BookmarkNode::MetaInfoMap meta_info; - meta_info["stars.id"] = "some_id"; - meta_info["stars.flags"] = "1"; - - const BookmarkNode* node1 = - bookmark_model_->AddURLWithCreationTimeAndMetaInfo( - bookmark_model_->other_node(), - 0, - base::ASCIIToUTF16("Some title"), - GURL(BOOKMARK_URL), - base::Time::Now(), - &meta_info); - base::RunLoop().RunUntilIdle(); - std::string flags_str; - ASSERT_TRUE(node1->GetMetaInfo("stars.flags", &flags_str)); - int flags; - ASSERT_TRUE(base::StringToInt(flags_str, &flags)); - EXPECT_EQ(1, (flags & 1)); - - meta_info["stars.flags"] = "0"; - const BookmarkNode* node2 = - bookmark_model_->AddURLWithCreationTimeAndMetaInfo( - bookmark_model_->other_node(), - 0, - base::ASCIIToUTF16("Some title"), - GURL(BOOKMARK_URL), - base::Time::Now(), - &meta_info); - base::RunLoop().RunUntilIdle(); - ASSERT_TRUE(node2->GetMetaInfo("stars.flags", &flags_str)); - ASSERT_TRUE(base::StringToInt(flags_str, &flags)); - EXPECT_EQ(0, (flags & 1)); -} - -TEST_F(EnhancedBookmarkModelTest, - NodeRemovedWhileSetNeedsOfflineProcessingIsScheduled) { - const BookmarkNode* node = - bookmark_model_->AddURL(bookmark_model_->other_node(), - 0, - base::ASCIIToUTF16("Some title"), - GURL(BOOKMARK_URL)); - bookmark_model_->Remove(node->parent(), node->parent()->GetIndexOf(node)); - base::RunLoop().RunUntilIdle(); -} - TEST_F(EnhancedBookmarkModelTest, RemoveParentShouldRemoveChildrenFromMaps) { const BookmarkNode* parent = AddFolder();
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_utils.cc b/components/enhanced_bookmarks/enhanced_bookmark_utils.cc index 337fb94..08d810e 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_utils.cc +++ b/components/enhanced_bookmarks/enhanced_bookmark_utils.cc
@@ -8,6 +8,7 @@ #include "components/bookmarks/browser/bookmark_model.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace enhanced_bookmarks {
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_utils.h b/components/enhanced_bookmarks/enhanced_bookmark_utils.h index dc9cf3c..f2ce4dc 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_utils.h +++ b/components/enhanced_bookmarks/enhanced_bookmark_utils.h
@@ -9,40 +9,58 @@ #include <string> #include <vector> -class BookmarkNode; - namespace bookmarks { class BookmarkModel; +class BookmarkNode; } namespace enhanced_bookmarks { +static const char kLaunchLocationUMA[] = "Stars.LaunchLocation"; + +// Possible locations where a bookmark can be opened from. +// Please sync with the corresponding histograms.xml. +// +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.enhancedbookmark +enum LaunchLocation { + ALL_ITEMS = 0, + UNCATEGORIZED = 1, // Deprecated. + FOLDER = 2, + FILTER = 3, + SEARCH = 4, + BOOKMARK_EDITOR = 5, + COUNT = 6, +}; + // The vector is sorted in place. // All of the bookmarks in |nodes| must be urls. -void SortBookmarksByName(std::vector<const BookmarkNode*>& nodes); +void SortBookmarksByName(std::vector<const bookmarks::BookmarkNode*>& nodes); // Returns the permanent nodes whose url children are considered uncategorized // and whose folder children should be shown in the bookmark menu. // |model| must be loaded. -std::vector<const BookmarkNode*> PrimaryPermanentNodes( +std::vector<const bookmarks::BookmarkNode*> PrimaryPermanentNodes( bookmarks::BookmarkModel* model); // Returns an unsorted vector of folders that are considered to be at the "root" // level of the bookmark hierarchy. Functionally, this means all direct // descendants of PrimaryPermanentNodes. -std::vector<const BookmarkNode*> RootLevelFolders( +std::vector<const bookmarks::BookmarkNode*> RootLevelFolders( bookmarks::BookmarkModel* model); // Returns whether |node| is a primary permanent node in the sense of // |PrimaryPermanentNodes|. -bool IsPrimaryPermanentNode(const BookmarkNode* node, +bool IsPrimaryPermanentNode(const bookmarks::BookmarkNode* node, bookmarks::BookmarkModel* model); // Returns the root level folder in which this node is directly, or indirectly // via subfolders, located. -const BookmarkNode* RootLevelFolderForNode(const BookmarkNode* node, - bookmarks::BookmarkModel* model); +const bookmarks::BookmarkNode* RootLevelFolderForNode( + const bookmarks::BookmarkNode* node, + bookmarks::BookmarkModel* model); } // namespace enhanced_bookmarks #endif // COMPONENTS_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARK_UTILS_H_ +
diff --git a/components/enhanced_bookmarks/metadata_accessor.cc b/components/enhanced_bookmarks/metadata_accessor.cc index d259832..40c5de9e 100644 --- a/components/enhanced_bookmarks/metadata_accessor.cc +++ b/components/enhanced_bookmarks/metadata_accessor.cc
@@ -14,6 +14,7 @@ using namespace image::collections; using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; namespace {
diff --git a/components/enhanced_bookmarks/metadata_accessor.h b/components/enhanced_bookmarks/metadata_accessor.h index 884a0e72..dea97b20 100644 --- a/components/enhanced_bookmarks/metadata_accessor.h +++ b/components/enhanced_bookmarks/metadata_accessor.h
@@ -9,11 +9,11 @@ #include <string> #include <vector> -class BookmarkNode; class GURL; namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // TODO(rfevang): Remove this file once the remaining caller @@ -24,8 +24,8 @@ // images and descriptions related to the url. namespace enhanced_bookmarks { -typedef std::vector<const BookmarkNode*> NodeVector; -typedef std::set<const BookmarkNode*> NodeSet; +typedef std::vector<const bookmarks::BookmarkNode*> NodeVector; +typedef std::set<const bookmarks::BookmarkNode*> NodeSet; // The keys used to store the data in the bookmarks metadata dictionary. extern const char* kPageDataKey; @@ -36,49 +36,49 @@ // Returns the remoteId for a bookmark. If the bookmark doesn't have one already // this function will create and set one. std::string RemoteIdFromBookmark(bookmarks::BookmarkModel* bookmark_model, - const BookmarkNode* node); + const bookmarks::BookmarkNode* node); // Sets the description of a bookmark. void SetDescriptionForBookmark(bookmarks::BookmarkModel* bookmark_model, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const std::string& description); // Returns the description of a bookmark. -std::string DescriptionFromBookmark(const BookmarkNode* node); +std::string DescriptionFromBookmark(const bookmarks::BookmarkNode* node); // Sets the URL of an image representative of the page. // Expects the URL to be valid and not empty. // Returns true if the metainfo is successfully populated. bool SetOriginalImageForBookmark(bookmarks::BookmarkModel* bookmark_model, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const GURL& url, int width, int height); // Returns the url and dimensions of the original scraped image. // Returns true if the out variables are populated, false otherwise. -bool OriginalImageFromBookmark(const BookmarkNode* node, +bool OriginalImageFromBookmark(const bookmarks::BookmarkNode* node, GURL* url, int* width, int* height); // Returns the url and dimensions of the server provided thumbnail image. // Returns true if the out variables are populated, false otherwise. -bool ThumbnailImageFromBookmark(const BookmarkNode* node, +bool ThumbnailImageFromBookmark(const bookmarks::BookmarkNode* node, GURL* url, int* width, int* height); // Returns a brief server provided synopsis of the bookmarked page. // Returns the empty string if the snippet could not be extracted. -std::string SnippetFromBookmark(const BookmarkNode* node); +std::string SnippetFromBookmark(const bookmarks::BookmarkNode* node); // Used for testing, simulates the process that creates the thumnails. Will // remove existing entries for empty urls or set them if the url is not empty. // expects valid or empty urls. Returns true if the metainfo is successfully // populated. bool SetAllImagesForBookmark(bookmarks::BookmarkModel* bookmark_model, - const BookmarkNode* node, + const bookmarks::BookmarkNode* node, const GURL& image_url, int image_width, int image_height,
diff --git a/components/feedback/feedback_data.cc b/components/feedback/feedback_data.cc index 3abe1cfc..6b2fc49 100644 --- a/components/feedback/feedback_data.cc +++ b/components/feedback/feedback_data.cc
@@ -20,7 +20,7 @@ namespace feedback { namespace { -const char kTraceFilename[] = "tracing.zip\n"; +const char kTraceFilename[] = "tracing.zip"; const char kPerformanceCategoryTag[] = "Performance"; const base::FilePath::CharType kHistogramsFilename[] =
diff --git a/components/gcm_driver/gcm_channel_status_syncer.cc b/components/gcm_driver/gcm_channel_status_syncer.cc index a83ac63..852922d 100644 --- a/components/gcm_driver/gcm_channel_status_syncer.cc +++ b/components/gcm_driver/gcm_channel_status_syncer.cc
@@ -21,15 +21,6 @@ namespace { -// The GCM channel's enabled state. -const char kGCMChannelStatus[] = "gcm.channel_status"; - -// The GCM channel's polling interval (in seconds). -const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; - -// Last time when checking with the GCM channel status server is done. -const char kGCMChannelLastCheckTime[] = "gcm.check_time"; - // A small delay to avoid sending request at browser startup time for first-time // request. const int kFirstTimeDelaySeconds = 1 * 60; // 1 minute. @@ -45,6 +36,19 @@ } // namespace +namespace prefs { + +// The GCM channel's enabled state. +const char kGCMChannelStatus[] = "gcm.channel_status"; + +// The GCM channel's polling interval (in seconds). +const char kGCMChannelPollIntervalSeconds[] = "gcm.poll_interval"; + +// Last time when checking with the GCM channel status server is done. +const char kGCMChannelLastCheckTime[] = "gcm.check_time"; + +} // namepsace prefs + namespace switches { // Override the default poll interval for testing purpose. @@ -54,26 +58,26 @@ // static void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(kGCMChannelStatus, true); + registry->RegisterBooleanPref(prefs::kGCMChannelStatus, true); registry->RegisterIntegerPref( - kGCMChannelPollIntervalSeconds, + prefs::kGCMChannelPollIntervalSeconds, GCMChannelStatusRequest::default_poll_interval_seconds()); - registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0); + registry->RegisterInt64Pref(prefs::kGCMChannelLastCheckTime, 0); } // static void GCMChannelStatusSyncer::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref( - kGCMChannelStatus, + prefs::kGCMChannelStatus, true, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterIntegerPref( - kGCMChannelPollIntervalSeconds, + prefs::kGCMChannelPollIntervalSeconds, GCMChannelStatusRequest::default_poll_interval_seconds(), user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterInt64Pref( - kGCMChannelLastCheckTime, + prefs::kGCMChannelLastCheckTime, 0, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); } @@ -101,8 +105,9 @@ custom_poll_interval_use_count_(0), delay_removed_for_testing_(false), weak_ptr_factory_(this) { - gcm_enabled_ = prefs_->GetBoolean(kGCMChannelStatus); - poll_interval_seconds_ = prefs_->GetInteger(kGCMChannelPollIntervalSeconds); + gcm_enabled_ = prefs_->GetBoolean(prefs::kGCMChannelStatus); + poll_interval_seconds_ = prefs_->GetInteger( + prefs::kGCMChannelPollIntervalSeconds); if (poll_interval_seconds_ < GCMChannelStatusRequest::min_poll_interval_seconds()) { poll_interval_seconds_ = @@ -123,7 +128,7 @@ } } last_check_time_ = base::Time::FromInternalValue( - prefs_->GetInt64(kGCMChannelLastCheckTime)); + prefs_->GetInt64(prefs::kGCMChannelLastCheckTime)); } GCMChannelStatusSyncer::~GCMChannelStatusSyncer() { @@ -152,13 +157,13 @@ // Persist the current time as the last request complete time. last_check_time_ = base::Time::Now(); - prefs_->SetInt64(kGCMChannelLastCheckTime, + prefs_->SetInt64(prefs::kGCMChannelLastCheckTime, last_check_time_.ToInternalValue()); if (update_received) { if (gcm_enabled_ != enabled) { gcm_enabled_ = enabled; - prefs_->SetBoolean(kGCMChannelStatus, enabled); + prefs_->SetBoolean(prefs::kGCMChannelStatus, enabled); if (gcm_enabled_) driver_->Enable(); else @@ -171,7 +176,7 @@ GCMChannelStatusRequest::min_poll_interval_seconds()); if (poll_interval_seconds_ != poll_interval_seconds) { poll_interval_seconds_ = poll_interval_seconds; - prefs_->SetInteger(kGCMChannelPollIntervalSeconds, + prefs_->SetInteger(prefs::kGCMChannelPollIntervalSeconds, poll_interval_seconds_); } }
diff --git a/components/gcm_driver/gcm_channel_status_syncer.h b/components/gcm_driver/gcm_channel_status_syncer.h index 0b7ba3f..e9fd7e3 100644 --- a/components/gcm_driver/gcm_channel_status_syncer.h +++ b/components/gcm_driver/gcm_channel_status_syncer.h
@@ -28,6 +28,11 @@ class GCMChannelStatusRequest; class GCMDriver; +namespace prefs { +// The GCM channel's enabled state. +extern const char kGCMChannelStatus[]; +} // namepsace prefs + // Syncing with the server for GCM channel status that controls if GCM // functionality should be enabled or disabled. class GCMChannelStatusSyncer {
diff --git a/components/gcm_driver/gcm_driver_android.h b/components/gcm_driver/gcm_driver_android.h index 566c91c..d26ed677 100644 --- a/components/gcm_driver/gcm_driver_android.h +++ b/components/gcm_driver/gcm_driver_android.h
@@ -18,7 +18,7 @@ class GCMDriverAndroid : public GCMDriver { public: GCMDriverAndroid(); - virtual ~GCMDriverAndroid(); + ~GCMDriverAndroid() override; // Methods called from Java via JNI: void OnRegisterFinished(JNIEnv* env, @@ -44,40 +44,36 @@ static bool RegisterBindings(JNIEnv* env); // GCMDriver implementation: - virtual void OnSignedIn() override; - virtual void OnSignedOut() override; - virtual void Enable() override; - virtual void AddConnectionObserver(GCMConnectionObserver* observer) override; - virtual void RemoveConnectionObserver( - GCMConnectionObserver* observer) override; - virtual void Disable() override; - virtual GCMClient* GetGCMClientForTesting() const override; - virtual bool IsStarted() const override; - virtual bool IsConnected() const override; - virtual void GetGCMStatistics(const GetGCMStatisticsCallback& callback, - bool clear_logs) override; - virtual void SetGCMRecording(const GetGCMStatisticsCallback& callback, - bool recording) override; - virtual void SetAccountTokens( + void OnSignedIn() override; + void OnSignedOut() override; + void Enable() override; + void AddConnectionObserver(GCMConnectionObserver* observer) override; + void RemoveConnectionObserver(GCMConnectionObserver* observer) override; + void Disable() override; + GCMClient* GetGCMClientForTesting() const override; + bool IsStarted() const override; + bool IsConnected() const override; + void GetGCMStatistics(const GetGCMStatisticsCallback& callback, + bool clear_logs) override; + void SetGCMRecording(const GetGCMStatisticsCallback& callback, + bool recording) override; + void SetAccountTokens( const std::vector<GCMClient::AccountTokenInfo>& account_tokens) override; - virtual void UpdateAccountMapping( - const AccountMapping& account_mapping) override; - virtual void RemoveAccountMapping(const std::string& account_id) override; - virtual base::Time GetLastTokenFetchTime() override; - virtual void SetLastTokenFetchTime(const base::Time& time) override; - virtual void WakeFromSuspendForHeartbeat(bool wake) override; + void UpdateAccountMapping(const AccountMapping& account_mapping) override; + void RemoveAccountMapping(const std::string& account_id) override; + base::Time GetLastTokenFetchTime() override; + void SetLastTokenFetchTime(const base::Time& time) override; + void WakeFromSuspendForHeartbeat(bool wake) override; protected: // GCMDriver implementation: - virtual GCMClient::Result EnsureStarted( - GCMClient::StartMode start_mode) override; - virtual void RegisterImpl( - const std::string& app_id, - const std::vector<std::string>& sender_ids) override; - virtual void UnregisterImpl(const std::string& app_id) override; - virtual void SendImpl(const std::string& app_id, - const std::string& receiver_id, - const GCMClient::OutgoingMessage& message) override; + GCMClient::Result EnsureStarted(GCMClient::StartMode start_mode) override; + void RegisterImpl(const std::string& app_id, + const std::vector<std::string>& sender_ids) override; + void UnregisterImpl(const std::string& app_id) override; + void SendImpl(const std::string& app_id, + const std::string& receiver_id, + const GCMClient::OutgoingMessage& message) override; private: base::android::ScopedJavaGlobalRef<jobject> java_ref_;
diff --git a/components/gcm_driver/gcm_driver_desktop.h b/components/gcm_driver/gcm_driver_desktop.h index 6ea70d6..422f0f51 100644 --- a/components/gcm_driver/gcm_driver_desktop.h +++ b/components/gcm_driver/gcm_driver_desktop.h
@@ -134,14 +134,12 @@ scoped_ptr<GCMChannelStatusSyncer> gcm_channel_status_syncer_; // Flag to indicate whether the user is signed in to a GAIA account. - // TODO(jianli): To be removed when sign-in enforcement is dropped. bool signed_in_; // Flag to indicate if GCM is started. bool gcm_started_; // Flag to indicate if GCM is enabled. - // TODO(jianli): Removed when we switch completely to support all users. bool gcm_enabled_; // Flag to indicate the last known state of the GCM client. Because this
diff --git a/components/google/core/browser/google_url_tracker.cc b/components/google/core/browser/google_url_tracker.cc index 44488341..dd72e35 100644 --- a/components/google/core/browser/google_url_tracker.cc +++ b/components/google/core/browser/google_url_tracker.cc
@@ -17,9 +17,9 @@ const char GoogleURLTracker::kDefaultGoogleHomepage[] = - "http://www.google.com/"; + "https://www.google.com/"; const char GoogleURLTracker::kSearchDomainCheckURL[] = - "https://www.google.com/searchdomaincheck?format=url&type=chrome"; + "https://www.google.com/searchdomaincheck?format=domain&type=chrome"; GoogleURLTracker::GoogleURLTracker(scoped_ptr<GoogleURLTrackerClient> client, Mode mode) @@ -81,16 +81,16 @@ return; } - // See if the response data was valid. It should be - // "<scheme>://[www.]google.<TLD>/". + // See if the response data was valid. It should be ".google.<TLD>". std::string url_str; source->GetResponseAsString(&url_str); base::TrimWhitespace(url_str, base::TRIM_ALL, &url_str); - GURL url(url_str); + if (!StartsWithASCII(url_str, ".google.", false)) + return; + GURL url("https://www" + url_str); if (!url.is_valid() || (url.path().length() > 1) || url.has_query() || url.has_ref() || - !google_util::IsGoogleDomainUrl(url, - google_util::DISALLOW_SUBDOMAIN, + !google_util::IsGoogleDomainUrl(url, google_util::DISALLOW_SUBDOMAIN, google_util::DISALLOW_NON_STANDARD_PORTS)) return;
diff --git a/components/google/core/browser/google_url_tracker_unittest.cc b/components/google/core/browser/google_url_tracker_unittest.cc index a89dded..1946e76 100644 --- a/components/google/core/browser/google_url_tracker_unittest.cc +++ b/components/google/core/browser/google_url_tracker_unittest.cc
@@ -207,7 +207,7 @@ FinishSleep(); // No one called RequestServerCheck() so nothing should have happened. EXPECT_FALSE(GetFetcher()); - MockSearchDomainCheckResponse("http://www.google.co.uk/"); + MockSearchDomainCheckResponse(".google.co.uk"); EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), google_url()); EXPECT_FALSE(listener_notified()); } @@ -219,13 +219,13 @@ EXPECT_FALSE(listener_notified()); FinishSleep(); - MockSearchDomainCheckResponse("http://www.google.co.uk/"); - EXPECT_EQ(GURL("http://www.google.co.uk/"), google_url()); + MockSearchDomainCheckResponse(".google.co.uk"); + EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url()); EXPECT_TRUE(listener_notified()); } TEST_F(GoogleURLTrackerTest, DontUpdateWhenUnchanged) { - GURL original_google_url("http://www.google.co.uk/"); + GURL original_google_url("https://www.google.co.uk/"); set_google_url(original_google_url); RequestServerCheck(); @@ -234,14 +234,14 @@ EXPECT_FALSE(listener_notified()); FinishSleep(); - MockSearchDomainCheckResponse(original_google_url.spec()); + MockSearchDomainCheckResponse(".google.co.uk"); EXPECT_EQ(original_google_url, google_url()); // No one should be notified, because the new URL matches the old. EXPECT_FALSE(listener_notified()); } -TEST_F(GoogleURLTrackerTest, DontPromptOnBadReplies) { - GURL original_google_url("http://www.google.co.uk/"); +TEST_F(GoogleURLTrackerTest, DontUpdateOnBadReplies) { + GURL original_google_url("https://www.google.co.uk/"); set_google_url(original_google_url); RequestServerCheck(); @@ -249,33 +249,39 @@ EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); - // Old-style domain string. + // Old-style URL string. FinishSleep(); - MockSearchDomainCheckResponse(".google.co.in"); + MockSearchDomainCheckResponse("https://www.google.com/"); EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); - // Bad subdomain. + // Not a Google domain. + FinishSleep(); + MockSearchDomainCheckResponse(".google.evil.com"); + EXPECT_EQ(original_google_url, google_url()); + EXPECT_FALSE(listener_notified()); + + // Doesn't start with .google. NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://mail.google.com/"); + MockSearchDomainCheckResponse(".mail.google.com"); EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); // Non-empty path. NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.com/search"); + MockSearchDomainCheckResponse(".google.com/search"); EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); // Non-empty query. NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.com/?q=foo"); + MockSearchDomainCheckResponse(".google.com/?q=foo"); EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); // Non-empty ref. NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.com/#anchor"); + MockSearchDomainCheckResponse(".google.com/#anchor"); EXPECT_EQ(original_google_url, google_url()); EXPECT_FALSE(listener_notified()); @@ -289,14 +295,14 @@ TEST_F(GoogleURLTrackerTest, RefetchOnNetworkChange) { RequestServerCheck(); FinishSleep(); - MockSearchDomainCheckResponse("http://www.google.co.uk/"); - EXPECT_EQ(GURL("http://www.google.co.uk/"), google_url()); + MockSearchDomainCheckResponse(".google.co.uk"); + EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url()); EXPECT_TRUE(listener_notified()); clear_listener_notified(); NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.co.in/"); - EXPECT_EQ(GURL("http://www.google.co.in/"), google_url()); + MockSearchDomainCheckResponse(".google.co.in"); + EXPECT_EQ(GURL("https://www.google.co.in/"), google_url()); EXPECT_TRUE(listener_notified()); } @@ -305,7 +311,7 @@ NotifyNetworkChanged(); // No one called RequestServerCheck() so nothing should have happened. EXPECT_FALSE(GetFetcher()); - MockSearchDomainCheckResponse("http://www.google.co.uk/"); + MockSearchDomainCheckResponse(".google.co.uk"); EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), google_url()); EXPECT_FALSE(listener_notified()); } @@ -313,33 +319,33 @@ TEST_F(GoogleURLTrackerTest, FetchOnLateRequest) { FinishSleep(); NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.co.jp/"); + MockSearchDomainCheckResponse(".google.co.jp"); RequestServerCheck(); // The first request for a check should trigger a fetch if it hasn't happened // already. - MockSearchDomainCheckResponse("http://www.google.co.uk/"); - EXPECT_EQ(GURL("http://www.google.co.uk/"), google_url()); + MockSearchDomainCheckResponse(".google.co.uk"); + EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url()); EXPECT_TRUE(listener_notified()); } TEST_F(GoogleURLTrackerTest, DontFetchTwiceOnLateRequests) { FinishSleep(); NotifyNetworkChanged(); - MockSearchDomainCheckResponse("http://www.google.co.jp/"); + MockSearchDomainCheckResponse(".google.co.jp"); RequestServerCheck(); // The first request for a check should trigger a fetch if it hasn't happened // already. - MockSearchDomainCheckResponse("http://www.google.co.uk/"); - EXPECT_EQ(GURL("http://www.google.co.uk/"), google_url()); + MockSearchDomainCheckResponse(".google.co.uk"); + EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url()); EXPECT_TRUE(listener_notified()); clear_listener_notified(); RequestServerCheck(); // The second request should be ignored. EXPECT_FALSE(GetFetcher()); - MockSearchDomainCheckResponse("http://www.google.co.in/"); - EXPECT_EQ(GURL("http://www.google.co.uk/"), google_url()); + MockSearchDomainCheckResponse(".google.co.in"); + EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url()); EXPECT_FALSE(listener_notified()); }
diff --git a/components/google/core/browser/google_util.cc b/components/google/core/browser/google_util.cc index 307cebb3..58d2d21d 100644 --- a/components/google/core/browser/google_util.cc +++ b/components/google/core/browser/google_util.cc
@@ -132,11 +132,9 @@ GURL GetGoogleSearchURL(GURL google_homepage_url) { // To transform the homepage URL into the corresponding search URL, add the // "search" and the "q=" query string. - std::string search_path = "search"; - std::string query_string = "q="; GURL::Replacements replacements; - replacements.SetPathStr(search_path); - replacements.SetQueryStr(query_string); + replacements.SetPathStr("search"); + replacements.SetQueryStr("q="); return google_homepage_url.ReplaceComponents(replacements); }
diff --git a/components/history/core/browser/android/android_urls_sql_handler.h b/components/history/core/browser/android/android_urls_sql_handler.h index 806f2cd..2c5f7b5 100644 --- a/components/history/core/browser/android/android_urls_sql_handler.h +++ b/components/history/core/browser/android/android_urls_sql_handler.h
@@ -15,14 +15,14 @@ class AndroidURLsSQLHandler : public SQLHandler { public: explicit AndroidURLsSQLHandler(AndroidURLsDatabase* android_urls_db); - virtual ~AndroidURLsSQLHandler(); + ~AndroidURLsSQLHandler() override; - virtual bool Update(const HistoryAndBookmarkRow& row, - const TableIDRows& ids_set) override; + bool Update(const HistoryAndBookmarkRow& row, + const TableIDRows& ids_set) override; - virtual bool Insert(HistoryAndBookmarkRow* row) override; + bool Insert(HistoryAndBookmarkRow* row) override; - virtual bool Delete(const TableIDRows& ids_set) override; + bool Delete(const TableIDRows& ids_set) override; private: AndroidURLsDatabase* android_urls_db_;
diff --git a/components/history/core/browser/android/favicon_sql_handler.h b/components/history/core/browser/android/favicon_sql_handler.h index fbcd66d6..86a628c 100644 --- a/components/history/core/browser/android/favicon_sql_handler.h +++ b/components/history/core/browser/android/favicon_sql_handler.h
@@ -15,13 +15,13 @@ class FaviconSQLHandler : public SQLHandler { public: explicit FaviconSQLHandler(ThumbnailDatabase* thumbnail_db); - virtual ~FaviconSQLHandler(); + ~FaviconSQLHandler() override; // SQLHandler overrides: - virtual bool Update(const HistoryAndBookmarkRow& row, - const TableIDRows& ids_set) override; - virtual bool Delete(const TableIDRows& ids_set) override; - virtual bool Insert(HistoryAndBookmarkRow* row) override; + bool Update(const HistoryAndBookmarkRow& row, + const TableIDRows& ids_set) override; + bool Delete(const TableIDRows& ids_set) override; + bool Insert(HistoryAndBookmarkRow* row) override; private: // Deletes the given favicons if they are not used by any pages. Returns
diff --git a/components/history/core/browser/android/urls_sql_handler.h b/components/history/core/browser/android/urls_sql_handler.h index b7fb2fa..aab5c96 100644 --- a/components/history/core/browser/android/urls_sql_handler.h +++ b/components/history/core/browser/android/urls_sql_handler.h
@@ -15,13 +15,13 @@ class UrlsSQLHandler : public SQLHandler { public: explicit UrlsSQLHandler(URLDatabase* url_db); - virtual ~UrlsSQLHandler(); + ~UrlsSQLHandler() override; // Overriden from SQLHandler. - virtual bool Insert(HistoryAndBookmarkRow* row) override; - virtual bool Update(const HistoryAndBookmarkRow& row, - const TableIDRows& ids_set) override; - virtual bool Delete(const TableIDRows& ids_set) override; + bool Insert(HistoryAndBookmarkRow* row) override; + bool Update(const HistoryAndBookmarkRow& row, + const TableIDRows& ids_set) override; + bool Delete(const TableIDRows& ids_set) override; private: URLDatabase* url_db_;
diff --git a/components/history/core/browser/android/visit_sql_handler.h b/components/history/core/browser/android/visit_sql_handler.h index 0f59a0a0..6c4a6db 100644 --- a/components/history/core/browser/android/visit_sql_handler.h +++ b/components/history/core/browser/android/visit_sql_handler.h
@@ -20,13 +20,13 @@ class VisitSQLHandler : public SQLHandler { public: VisitSQLHandler(URLDatabase* url_db, VisitDatabase* visit_db); - virtual ~VisitSQLHandler(); + ~VisitSQLHandler() override; // Overriden from SQLHandler. - virtual bool Update(const HistoryAndBookmarkRow& row, - const TableIDRows& ids_set) override; - virtual bool Insert(HistoryAndBookmarkRow* row) override; - virtual bool Delete(const TableIDRows& ids_set) override; + bool Update(const HistoryAndBookmarkRow& row, + const TableIDRows& ids_set) override; + bool Insert(HistoryAndBookmarkRow* row) override; + bool Delete(const TableIDRows& ids_set) override; private: // Add a row in visit table with the given |url_id| and |visit_time|.
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc index 72949b3..60d424e3 100644 --- a/components/history/core/browser/history_types.cc +++ b/components/history/core/browser/history_types.cc
@@ -245,31 +245,30 @@ nullptr, 0, GURL(), - history::RedirectList(), + RedirectList(), ui::PAGE_TRANSITION_LINK, SOURCE_BROWSED, false) { } -HistoryAddPageArgs::HistoryAddPageArgs( - const GURL& url, - base::Time time, - ContextID context_id, - int nav_entry_id, - const GURL& referrer, - const history::RedirectList& redirects, - ui::PageTransition transition, - VisitSource source, - bool did_replace_entry) - : url(url), - time(time), - context_id(context_id), - nav_entry_id(nav_entry_id), - referrer(referrer), - redirects(redirects), - transition(transition), - visit_source(source), - did_replace_entry(did_replace_entry) { +HistoryAddPageArgs::HistoryAddPageArgs(const GURL& url, + base::Time time, + ContextID context_id, + int nav_entry_id, + const GURL& referrer, + const RedirectList& redirects, + ui::PageTransition transition, + VisitSource source, + bool did_replace_entry) + : url(url), + time(time), + context_id(context_id), + nav_entry_id(nav_entry_id), + referrer(referrer), + redirects(redirects), + transition(transition), + visit_source(source), + did_replace_entry(did_replace_entry) { } HistoryAddPageArgs::~HistoryAddPageArgs() {}
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h index 45ebdd5..cbcf26b 100644 --- a/components/history/core/browser/history_types.h +++ b/components/history/core/browser/history_types.h
@@ -25,12 +25,11 @@ #include "ui/gfx/geometry/size.h" #include "url/gurl.h" -class PageUsageData; - namespace history { // Forward declaration for friend statements. class HistoryBackend; +class PageUsageData; class URLDatabase; // Container for a list of URLs. @@ -363,7 +362,7 @@ // // HistoryAddPageArgs( // GURL(), base::Time(), NULL, 0, GURL(), - // history::RedirectList(), ui::PAGE_TRANSITION_LINK, + // RedirectList(), ui::PAGE_TRANSITION_LINK, // SOURCE_BROWSED, false) HistoryAddPageArgs(); HistoryAddPageArgs(const GURL& url, @@ -371,7 +370,7 @@ ContextID context_id, int nav_entry_id, const GURL& referrer, - const history::RedirectList& redirects, + const RedirectList& redirects, ui::PageTransition transition, VisitSource source, bool did_replace_entry); @@ -382,7 +381,7 @@ ContextID context_id; int nav_entry_id; GURL referrer; - history::RedirectList redirects; + RedirectList redirects; ui::PageTransition transition; VisitSource visit_source; bool did_replace_entry;
diff --git a/components/history/core/browser/in_memory_url_index_types.h b/components/history/core/browser/in_memory_url_index_types.h index 9390c26..fbb511a5 100644 --- a/components/history/core/browser/in_memory_url_index_types.h +++ b/components/history/core/browser/in_memory_url_index_types.h
@@ -135,7 +135,7 @@ typedef std::map<base::char16, WordIDSet> CharWordIDMap; // A map from word (by word_id) to history items containing that word. -typedef history::URLID HistoryID; +typedef URLID HistoryID; typedef std::set<HistoryID> HistoryIDSet; typedef std::vector<HistoryID> HistoryIDVector; typedef std::map<WordID, HistoryIDSet> WordIDHistoryMap;
diff --git a/components/history/core/browser/in_memory_url_index_types_unittest.cc b/components/history/core/browser/in_memory_url_index_types_unittest.cc index b140491..c10f1c0 100644 --- a/components/history/core/browser/in_memory_url_index_types_unittest.cc +++ b/components/history/core/browser/in_memory_url_index_types_unittest.cc
@@ -126,12 +126,12 @@ TEST_F(InMemoryURLIndexTypesTest, OffsetsAndTermMatches) { // Test OffsetsFromTermMatches - history::TermMatches matches_a; - matches_a.push_back(history::TermMatch(1, 1, 2)); - matches_a.push_back(history::TermMatch(2, 4, 3)); - matches_a.push_back(history::TermMatch(3, 9, 1)); - matches_a.push_back(history::TermMatch(3, 10, 1)); - matches_a.push_back(history::TermMatch(4, 14, 5)); + TermMatches matches_a; + matches_a.push_back(TermMatch(1, 1, 2)); + matches_a.push_back(TermMatch(2, 4, 3)); + matches_a.push_back(TermMatch(3, 9, 1)); + matches_a.push_back(TermMatch(3, 10, 1)); + matches_a.push_back(TermMatch(4, 14, 5)); std::vector<size_t> offsets = OffsetsFromTermMatches(matches_a); const size_t expected_offsets_a[] = {1, 3, 4, 7, 9, 10, 10, 11, 14, 19}; ASSERT_EQ(offsets.size(), arraysize(expected_offsets_a)); @@ -140,8 +140,7 @@ // Test ReplaceOffsetsInTermMatches offsets[4] = base::string16::npos; // offset of third term - history::TermMatches matches_b = - ReplaceOffsetsInTermMatches(matches_a, offsets); + TermMatches matches_b = ReplaceOffsetsInTermMatches(matches_a, offsets); const size_t expected_offsets_b[] = {1, 4, 10, 14}; ASSERT_EQ(arraysize(expected_offsets_b), matches_b.size()); for (size_t i = 0; i < matches_b.size(); ++i)
diff --git a/components/history/core/browser/page_usage_data.cc b/components/history/core/browser/page_usage_data.cc index e240ff9..73ba3d4 100644 --- a/components/history/core/browser/page_usage_data.cc +++ b/components/history/core/browser/page_usage_data.cc
@@ -6,9 +6,9 @@ #include <algorithm> -PageUsageData::PageUsageData(history::SegmentID id) - : id_(id), - score_(0.0) { +namespace history { + +PageUsageData::PageUsageData(SegmentID id) : id_(id), score_(0.0) { } PageUsageData::~PageUsageData() { @@ -19,3 +19,5 @@ const PageUsageData* rhs) { return lhs->GetScore() > rhs->GetScore(); } + +} // namespace history
diff --git a/components/history/core/browser/page_usage_data.h b/components/history/core/browser/page_usage_data.h index 284b196..3a8fcc1 100644 --- a/components/history/core/browser/page_usage_data.h +++ b/components/history/core/browser/page_usage_data.h
@@ -11,6 +11,8 @@ class SkBitmap; +namespace history { + ///////////////////////////////////////////////////////////////////////////// // // PageUsageData @@ -18,19 +20,17 @@ // A per domain usage data structure to compute and manage most visited // pages. // -// See History::QueryPageUsageSince() +// See QueryPageUsageSince() // ///////////////////////////////////////////////////////////////////////////// class PageUsageData { public: - explicit PageUsageData(history::SegmentID id); + explicit PageUsageData(SegmentID id); virtual ~PageUsageData(); // Return the url ID - history::SegmentID GetID() const { - return id_; - } + SegmentID GetID() const { return id_; } void SetURL(const GURL& url) { url_ = url; @@ -60,11 +60,13 @@ static bool Predicate(const PageUsageData* dud1, const PageUsageData* dud2); private: - history::SegmentID id_; + SegmentID id_; GURL url_; base::string16 title_; double score_; }; +} // namespace history + #endif // COMPONENTS_HISTORY_CORE_BROWSER_PAGE_USAGE_DATA_H__
diff --git a/components/history/core/browser/thumbnail_database.cc b/components/history/core/browser/thumbnail_database.cc index 551af768..b7ad4c2d 100644 --- a/components/history/core/browser/thumbnail_database.cc +++ b/components/history/core/browser/thumbnail_database.cc
@@ -29,6 +29,8 @@ #include "base/mac/mac_util.h" #endif +namespace history { + // Description of database tables: // // icon_mapping @@ -568,8 +570,6 @@ } // namespace -namespace history { - ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { }
diff --git a/components/history/core/browser/top_sites_database.cc b/components/history/core/browser/top_sites_database.cc index 7b1cd48..ac5f71bc 100644 --- a/components/history/core/browser/top_sites_database.cc +++ b/components/history/core/browser/top_sites_database.cc
@@ -18,6 +18,8 @@ #include "sql/transaction.h" #include "third_party/sqlite/sqlite3.h" +namespace history { + // Description of database table: // // thumbnails @@ -79,7 +81,7 @@ } // Encodes redirects into a string. -std::string GetRedirects(const history::MostVisitedURL& url) { +std::string GetRedirects(const MostVisitedURL& url) { std::vector<std::string> redirects; for (size_t i = 0; i < url.redirects.size(); i++) redirects.push_back(url.redirects[i].spec()); @@ -87,7 +89,7 @@ } // Decodes redirects from a string and sets them for the url. -void SetRedirects(const std::string& redirects, history::MostVisitedURL* url) { +void SetRedirects(const std::string& redirects, MostVisitedURL* url) { std::vector<std::string> redirects_vector; base::SplitStringAlongWhitespace(redirects, &redirects_vector); for (size_t i = 0; i < redirects_vector.size(); ++i) { @@ -346,8 +348,6 @@ } // namespace -namespace history { - // static const int TopSitesDatabase::kRankOfForcedURL = -1;
diff --git a/components/history/core/browser/top_sites_observer.h b/components/history/core/browser/top_sites_observer.h index 28008de..443b33f 100644 --- a/components/history/core/browser/top_sites_observer.h +++ b/components/history/core/browser/top_sites_observer.h
@@ -8,6 +8,7 @@ #include "base/macros.h" namespace history { + class TopSites; // Interface for observing notifications from TopSites. @@ -17,11 +18,11 @@ virtual ~TopSitesObserver() {} // Is called when TopSites finishes loading. - virtual void TopSitesLoaded(history::TopSites* top_sites) = 0; + virtual void TopSitesLoaded(TopSites* top_sites) = 0; // Is called when either one of the most visited urls // changed, or one of the images changes. - virtual void TopSitesChanged(history::TopSites* top_sites) = 0; + virtual void TopSitesChanged(TopSites* top_sites) = 0; private: DISALLOW_COPY_AND_ASSIGN(TopSitesObserver);
diff --git a/components/history/core/browser/url_database.cc b/components/history/core/browser/url_database.cc index fc3bb94..65ac67e 100644 --- a/components/history/core/browser/url_database.cc +++ b/components/history/core/browser/url_database.cc
@@ -58,9 +58,9 @@ return (gurl.ReplaceComponents(replacements)).spec(); } -// Convenience to fill a history::URLRow. Must be in sync with the fields in +// Convenience to fill a URLRow. Must be in sync with the fields in // kURLRowFields. -void URLDatabase::FillURLRow(sql::Statement& s, history::URLRow* i) { +void URLDatabase::FillURLRow(sql::Statement& s, URLRow* i) { DCHECK(i); i->id_ = s.ColumnInt64(0); i->url_ = GURL(s.ColumnString(1)); @@ -99,7 +99,7 @@ return true; } -URLID URLDatabase::GetRowForURL(const GURL& url, history::URLRow* info) { +URLID URLDatabase::GetRowForURL(const GURL& url, URLRow* info) { sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE url=?")); std::string url_string = GURLToDatabaseURL(url); @@ -113,8 +113,7 @@ return statement.ColumnInt64(0); } -bool URLDatabase::UpdateURLRow(URLID url_id, - const history::URLRow& info) { +bool URLDatabase::UpdateURLRow(URLID url_id, const URLRow& info) { sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, "UPDATE urls SET title=?,visit_count=?,typed_count=?,last_visit_time=?," "hidden=?" @@ -129,8 +128,7 @@ return statement.Run() && GetDB().GetLastChangeCount() > 0; } -URLID URLDatabase::AddURLInternal(const history::URLRow& info, - bool is_temporary) { +URLID URLDatabase::AddURLInternal(const URLRow& info, bool is_temporary) { // This function is used to insert into two different tables, so we have to // do some shuffling. Unfortinately, we can't use the macro // HISTORY_URL_ROW_FIELDS because that specifies the table name which is @@ -167,7 +165,7 @@ return GetDB().GetLastInsertRowId(); } -bool URLDatabase::InsertOrUpdateURLRowByID(const history::URLRow& info) { +bool URLDatabase::InsertOrUpdateURLRowByID(const URLRow& info) { // SQLite does not support INSERT OR UPDATE, however, it does have INSERT OR // REPLACE, which is feasible to use, because of the following. // * Before INSERTing, REPLACE will delete all pre-existing rows that cause @@ -297,7 +295,7 @@ statement.BindInt(2, static_cast<int>(max_results)); while (statement.Step()) { - history::URLRow info; + URLRow info; FillURLRow(statement, &info); if (info.url().is_valid()) results->push_back(info); @@ -327,7 +325,7 @@ int min_visits, int min_typed, bool allow_base, - history::URLRow* info) { + URLRow* info) { // Select URLs that start with |base| and are prefixes of |url|. All parts // of this query except the substr() call can be done using the index. We // could do this query with a couple of LIKE or GLOB statements as well, but @@ -382,7 +380,7 @@ query_parser_.ExtractQueryWords(title, &query_words); if (query_parser_.DoesQueryMatch(query_words, query_nodes.get())) { - history::URLResult info; + URLResult info; FillURLRow(statement, &info); if (info.url().is_valid()) results->push_back(info);
diff --git a/components/history/core/browser/url_database.h b/components/history/core/browser/url_database.h index f69105a..fb3d2f0 100644 --- a/components/history/core/browser/url_database.h +++ b/components/history/core/browser/url_database.h
@@ -138,7 +138,7 @@ URLEnumerator(); // Retreives the next url. Returns false if no more urls are available - bool GetNextURL(history::URLRow* r); + bool GetNextURL(URLRow* r); private: DISALLOW_COPY_AND_ASSIGN(URLEnumerator); @@ -181,7 +181,7 @@ int min_visits, int min_typed, bool allow_base, - history::URLRow* info); + URLRow* info); // History search ------------------------------------------------------------ @@ -276,7 +276,7 @@ // be used in between CreateTemporaryURLTable() and CommitTemporaryURLTable(). URLID AddURLInternal(const URLRow& info, bool is_temporary); - // Convenience to fill a history::URLRow. Must be in sync with the fields in + // Convenience to fill a URLRow. Must be in sync with the fields in // kHistoryURLRowFields. static void FillURLRow(sql::Statement& s, URLRow* i);
diff --git a/components/history/core/browser/visit_database.cc b/components/history/core/browser/visit_database.cc index 2a9234b..eab9d9d 100644 --- a/components/history/core/browser/visit_database.cc +++ b/components/history/core/browser/visit_database.cc
@@ -100,7 +100,7 @@ return false; while (statement.Step()) { - history::VisitRow visit; + VisitRow visit; FillVisitRow(statement, &visit); visits->push_back(visit); }
diff --git a/components/history/core/browser/visit_tracker_unittest.cc b/components/history/core/browser/visit_tracker_unittest.cc index 4f37768..eee8b9c 100644 --- a/components/history/core/browser/visit_tracker_unittest.cc +++ b/components/history/core/browser/visit_tracker_unittest.cc
@@ -7,9 +7,7 @@ #include "base/basictypes.h" #include "testing/gtest/include/gtest/gtest.h" -using history::ContextID; -using history::VisitTracker; - +namespace history { namespace { struct VisitToTest { @@ -19,13 +17,13 @@ // Used when adding this to the tracker const char* url; - const history::VisitID visit_id; + const VisitID visit_id; // Used when finding the referrer const char* referrer; // the correct referring visit ID to compare to the computed one - history::VisitID referring_visit_id; + VisitID referring_visit_id; }; void RunTest(VisitTracker* tracker, VisitToTest* test, int test_count) { @@ -35,8 +33,8 @@ ContextID context_id = reinterpret_cast<ContextID>(test[i].context_id_int); // Check the referrer for this visit. - history::VisitID ref_visit = tracker->GetLastVisit( - context_id, test[i].nav_entry_id, GURL(test[i].referrer)); + VisitID ref_visit = tracker->GetLastVisit(context_id, test[i].nav_entry_id, + GURL(test[i].referrer)); EXPECT_EQ(test[i].referring_visit_id, ref_visit); // Now add this visit. @@ -128,3 +126,5 @@ }; RunTest(&tracker, part2, arraysize(part2)); } + +} // namespace history
diff --git a/components/history/core/browser/visitsegment_database.h b/components/history/core/browser/visitsegment_database.h index a2aa156d8b..1bac890f 100644 --- a/components/history/core/browser/visitsegment_database.h +++ b/components/history/core/browser/visitsegment_database.h
@@ -8,14 +8,14 @@ #include "base/basictypes.h" #include "components/history/core/browser/history_types.h" -class PageUsageData; - namespace sql { class Connection; } namespace history { +class PageUsageData; + // Tracks pages used for the most visited view. class VisitSegmentDatabase { public:
diff --git a/components/invalidation/gcm_invalidation_bridge.cc b/components/invalidation/gcm_invalidation_bridge.cc index 23cb09e..ef09594 100644 --- a/components/invalidation/gcm_invalidation_bridge.cc +++ b/components/invalidation/gcm_invalidation_bridge.cc
@@ -280,6 +280,23 @@ result)); } +void GCMInvalidationBridge::Unregister() { + DCHECK(CalledOnValidThread()); + // No-op if GCMClient is disabled. + if (gcm_driver_ == NULL) + return; + + gcm_driver_->Unregister( + kInvalidationsAppId, + base::Bind(&GCMInvalidationBridge::UnregisterFinishedNoOp)); +} + +// static +void GCMInvalidationBridge::UnregisterFinishedNoOp( + gcm::GCMClient::Result result) { + // No-op. +} + void GCMInvalidationBridge::SubscribeForIncomingMessages() { // No-op if GCMClient is disabled. if (gcm_driver_ == NULL) @@ -357,5 +374,4 @@ false)); } - } // namespace invalidation
diff --git a/components/invalidation/gcm_invalidation_bridge.h b/components/invalidation/gcm_invalidation_bridge.h index 4f3e735..9f9fe42 100644 --- a/components/invalidation/gcm_invalidation_bridge.h +++ b/components/invalidation/gcm_invalidation_bridge.h
@@ -86,6 +86,10 @@ const std::string& registration_id, gcm::GCMClient::Result result); + void Unregister(); + + static void UnregisterFinishedNoOp(gcm::GCMClient::Result result); + private: gcm::GCMDriver* const gcm_driver_; IdentityProvider* const identity_provider_;
diff --git a/components/invalidation/invalidation_service_android.h b/components/invalidation/invalidation_service_android.h index 4a9e77a..c8e0a51 100644 --- a/components/invalidation/invalidation_service_android.h +++ b/components/invalidation/invalidation_service_android.h
@@ -30,27 +30,25 @@ public InvalidationService { public: InvalidationServiceAndroid(jobject context); - virtual ~InvalidationServiceAndroid(); + ~InvalidationServiceAndroid() override; // InvalidationService implementation. // // Note that this implementation does not properly support Ack-tracking, // fetching the invalidator state, or querying the client's ID. Support for // exposing the client ID should be available soon; see crbug.com/172391. - virtual void RegisterInvalidationHandler( + void RegisterInvalidationHandler( syncer::InvalidationHandler* handler) override; - virtual void UpdateRegisteredInvalidationIds( - syncer::InvalidationHandler* handler, - const syncer::ObjectIdSet& ids) override; - virtual void UnregisterInvalidationHandler( + void UpdateRegisteredInvalidationIds(syncer::InvalidationHandler* handler, + const syncer::ObjectIdSet& ids) override; + void UnregisterInvalidationHandler( syncer::InvalidationHandler* handler) override; - virtual syncer::InvalidatorState GetInvalidatorState() const override; - virtual std::string GetInvalidatorClientId() const override; - virtual InvalidationLogger* GetInvalidationLogger() override; - virtual void RequestDetailedStatus( - base::Callback<void(const base::DictionaryValue&)> caller) const - override; - virtual IdentityProvider* GetIdentityProvider() override; + syncer::InvalidatorState GetInvalidatorState() const override; + std::string GetInvalidatorClientId() const override; + InvalidationLogger* GetInvalidationLogger() override; + void RequestDetailedStatus( + base::Callback<void(const base::DictionaryValue&)> caller) const override; + IdentityProvider* GetIdentityProvider() override; void RequestSync(JNIEnv* env, jobject obj,
diff --git a/components/invalidation/invalidation_service_android_unittest.cc b/components/invalidation/invalidation_service_android_unittest.cc index a03a973..ed295bb 100644 --- a/components/invalidation/invalidation_service_android_unittest.cc +++ b/components/invalidation/invalidation_service_android_unittest.cc
@@ -17,7 +17,7 @@ public: InvalidationServiceAndroidTest() : invalidation_service_(base::android::GetApplicationContext()) {} - virtual ~InvalidationServiceAndroidTest() {} + ~InvalidationServiceAndroidTest() override {} InvalidationService& invalidation_service() { return invalidation_service_;
diff --git a/components/invalidation/ticl_invalidation_service.cc b/components/invalidation/ticl_invalidation_service.cc index c606c28..e60902c 100644 --- a/components/invalidation/ticl_invalidation_service.cc +++ b/components/invalidation/ticl_invalidation_service.cc
@@ -262,6 +262,9 @@ access_token_request_.reset(); request_access_token_retry_timer_.Stop(); + if (gcm_invalidation_bridge_) + gcm_invalidation_bridge_->Unregister(); + if (IsStarted()) { StopInvalidator(); }
diff --git a/components/json_schema/json_schema_validator_unittest_base.h b/components/json_schema/json_schema_validator_unittest_base.h index 4edb9943..ff661ac 100644 --- a/components/json_schema/json_schema_validator_unittest_base.h +++ b/components/json_schema/json_schema_validator_unittest_base.h
@@ -16,7 +16,7 @@ // Base class for unit tests for JSONSchemaValidator. There is currently only // one implementation, JSONSchemaValidatorCPPTest. // -// TODO(aa): Refactor chrome/test/data/json_schema_test.js into +// TODO(aa): Refactor extensions/test/data/json_schema_test.js into // JSONSchemaValidatorJSTest that inherits from this. class JSONSchemaValidatorTestBase : public testing::Test { public:
diff --git a/components/keyed_service.gypi b/components/keyed_service.gypi index 6fb6c958..e363ef8 100644 --- a/components/keyed_service.gypi +++ b/components/keyed_service.gypi
@@ -32,6 +32,8 @@ 'keyed_service/core/keyed_service_export.h', 'keyed_service/core/keyed_service_factory.cc', 'keyed_service/core/keyed_service_factory.h', + 'keyed_service/core/keyed_service_shutdown_notifier.cc', + 'keyed_service/core/keyed_service_shutdown_notifier.h', 'keyed_service/core/refcounted_keyed_service.cc', 'keyed_service/core/refcounted_keyed_service.h', 'keyed_service/core/refcounted_keyed_service_factory.cc', @@ -70,6 +72,8 @@ 'keyed_service/content/browser_context_keyed_base_factory.cc', 'keyed_service/content/browser_context_keyed_service_factory.cc', 'keyed_service/content/browser_context_keyed_service_factory.h', + 'keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc', + 'keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h', 'keyed_service/content/refcounted_browser_context_keyed_service_factory.cc', 'keyed_service/content/refcounted_browser_context_keyed_service_factory.h', ],
diff --git a/components/keyed_service/content/BUILD.gn b/components/keyed_service/content/BUILD.gn index 80f204e..e5f7cb9 100644 --- a/components/keyed_service/content/BUILD.gn +++ b/components/keyed_service/content/BUILD.gn
@@ -13,6 +13,8 @@ "browser_context_keyed_base_factory.cc", "browser_context_keyed_service_factory.cc", "browser_context_keyed_service_factory.h", + "browser_context_keyed_service_shutdown_notifier_factory.cc", + "browser_context_keyed_service_shutdown_notifier_factory.h", "refcounted_browser_context_keyed_service_factory.cc", "refcounted_browser_context_keyed_service_factory.h", ]
diff --git a/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc b/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc new file mode 100644 index 0000000..5a75b5a --- /dev/null +++ b/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc
@@ -0,0 +1,37 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" + +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/core/keyed_service_shutdown_notifier.h" + +BrowserContextKeyedServiceShutdownNotifierFactory:: + BrowserContextKeyedServiceShutdownNotifierFactory(const char* name) + : BrowserContextKeyedServiceFactory( + name, + BrowserContextDependencyManager::GetInstance()) { +} +BrowserContextKeyedServiceShutdownNotifierFactory:: + ~BrowserContextKeyedServiceShutdownNotifierFactory() { +} + +KeyedServiceShutdownNotifier* +BrowserContextKeyedServiceShutdownNotifierFactory::Get( + content::BrowserContext* context) { + return static_cast<KeyedServiceShutdownNotifier*>( + GetServiceForBrowserContext(context, true)); +} + +KeyedService* +BrowserContextKeyedServiceShutdownNotifierFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new KeyedServiceShutdownNotifier; +} + +content::BrowserContext* +BrowserContextKeyedServiceShutdownNotifierFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return context; +}
diff --git a/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h b/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h new file mode 100644 index 0000000..dee6302 --- /dev/null +++ b/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h
@@ -0,0 +1,35 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_ +#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/keyed_service/core/keyed_service_export.h" + +class KeyedServiceShutdownNotifier; + +// A base class for factories for KeyedServiceShutdownNotifier objects that are +// keyed on a BrowserContext. +// To use this class, create a singleton subclass and declare its dependencies +// in the constructor. +class KEYED_SERVICE_EXPORT BrowserContextKeyedServiceShutdownNotifierFactory + : public BrowserContextKeyedServiceFactory { + public: + KeyedServiceShutdownNotifier* Get(content::BrowserContext* context); + + protected: + explicit BrowserContextKeyedServiceShutdownNotifierFactory(const char* name); + ~BrowserContextKeyedServiceShutdownNotifierFactory() override; + + private: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(BrowserContextKeyedServiceShutdownNotifierFactory); +}; + +#endif // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_
diff --git a/components/keyed_service/core/BUILD.gn b/components/keyed_service/core/BUILD.gn index bc8d3b02..2d8670e 100644 --- a/components/keyed_service/core/BUILD.gn +++ b/components/keyed_service/core/BUILD.gn
@@ -17,6 +17,8 @@ "keyed_service_export.h", "keyed_service_factory.cc", "keyed_service_factory.h", + "keyed_service_shutdown_notifier.cc", + "keyed_service_shutdown_notifier.h", "refcounted_keyed_service.cc", "refcounted_keyed_service.h", "refcounted_keyed_service_factory.cc",
diff --git a/components/keyed_service/core/keyed_service_shutdown_notifier.cc b/components/keyed_service/core/keyed_service_shutdown_notifier.cc new file mode 100644 index 0000000..cb0b27c4 --- /dev/null +++ b/components/keyed_service/core/keyed_service_shutdown_notifier.cc
@@ -0,0 +1,20 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/keyed_service/core/keyed_service_export.h" +#include "components/keyed_service/core/keyed_service_shutdown_notifier.h" + +KeyedServiceShutdownNotifier::KeyedServiceShutdownNotifier() { +} +KeyedServiceShutdownNotifier::~KeyedServiceShutdownNotifier() { +} + +scoped_ptr<base::CallbackList<void()>::Subscription> +KeyedServiceShutdownNotifier::Subscribe(const base::Closure& callback) { + return callback_list_.Add(callback); +} + +void KeyedServiceShutdownNotifier::Shutdown() { + callback_list_.Notify(); +}
diff --git a/components/keyed_service/core/keyed_service_shutdown_notifier.h b/components/keyed_service/core/keyed_service_shutdown_notifier.h new file mode 100644 index 0000000..2f2ca294 --- /dev/null +++ b/components/keyed_service/core/keyed_service_shutdown_notifier.h
@@ -0,0 +1,39 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_ +#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_ + +#include "base/callback_list.h" +#include "components/keyed_service/core/keyed_service.h" + +// This is a helper class for objects that depend on one or more keyed services, +// but which cannot be keyed services themselves, for example because they don't +// correspond 1:1 to a context, or because they have a different lifetime. +// +// To use this class, add a factory class and declare the dependencies there. +// This class (being a KeyedService itself) will be shut down before its +// dependencies and notify its observers. +class KEYED_SERVICE_EXPORT KeyedServiceShutdownNotifier : public KeyedService { + public: + using Subscription = base::CallbackList<void()>::Subscription; + + KeyedServiceShutdownNotifier(); + ~KeyedServiceShutdownNotifier() override; + + // Subscribe for a notification when the keyed services this object depends on + // (as defined by its factory) are shut down. The subscription object can be + // destroyed to unsubscribe. + scoped_ptr<Subscription> Subscribe(const base::Closure& callback); + + private: + // KeyedService implementation: + void Shutdown() override; + + base::CallbackList<void()> callback_list_; + + DISALLOW_COPY_AND_ASSIGN(KeyedServiceShutdownNotifier); +}; + +#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_
diff --git a/components/nacl.gyp b/components/nacl.gyp index 9d543d8..8524e92e 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp
@@ -147,6 +147,7 @@ 'dependencies': [ # Required by nacl_fork_delegate_linux.cc. '../sandbox/sandbox.gyp:suid_sandbox_client', + '../sandbox/sandbox.gyp:sandbox_services', ] }], ],
diff --git a/components/nacl/loader/DEPS b/components/nacl/loader/DEPS index 5d73078..7a02f23 100644 --- a/components/nacl/loader/DEPS +++ b/components/nacl/loader/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/nacl", "+content/public/app/startup_helper_win.h", + "+content/public/common", "+crypto", "+sandbox/linux/bpf_dsl", "+sandbox/linux/seccomp-bpf", @@ -13,11 +14,9 @@ "+native_client/src/include", "+native_client/src/public", "+native_client/src/shared/platform/nacl_host_desc.h", - "+native_client/src/shared/srpc/nacl_srpc.h", "+native_client/src/trusted/desc", "+native_client/src/trusted/service_runtime/include", "+native_client/src/trusted/service_runtime/nacl_error_code.h", - "+native_client/src/trusted/validator/rich_file_info.h", "+native_client/src/trusted/validator/validation_cache.h", "+native_client/src/untrusted/irt/irt.h",
diff --git a/components/nacl/loader/nacl_ipc_adapter.cc b/components/nacl/loader/nacl_ipc_adapter.cc index 6cf2cc3..5df92fbe 100644 --- a/components/nacl/loader/nacl_ipc_adapter.cc +++ b/components/nacl/loader/nacl_ipc_adapter.cc
@@ -16,6 +16,7 @@ #include "build/build_config.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_platform_file.h" +#include "native_client/src/public/nacl_desc.h" #include "native_client/src/trusted/desc/nacl_desc_base.h" #include "native_client/src/trusted/desc/nacl_desc_custom.h" #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h" @@ -23,9 +24,7 @@ #include "native_client/src/trusted/desc/nacl_desc_quota.h" #include "native_client/src/trusted/desc/nacl_desc_quota_interface.h" #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h" -#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" -#include "native_client/src/trusted/validator/rich_file_info.h" #include "ppapi/c/ppb_file_io.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_handle.h" @@ -665,33 +664,15 @@ std::string file_path_str = file_path.AsUTF8Unsafe(); base::PlatformFile handle = IPC::PlatformFileForTransitToPlatformFile(ipc_fd); - // The file token was resolved successfully, so we populate the new - // NaClDesc with that information. - char* alloc_file_path = static_cast<char*>( - malloc(file_path_str.length() + 1)); - strcpy(alloc_file_path, file_path_str.c_str()); - scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper( - NaClDescIoDescFromHandleAllocCtor(handle, NACL_ABI_O_RDONLY))); - - // Mark the desc as OK for mapping as executable memory. - NaClDescMarkSafeForMmap(desc_wrapper->desc()); - - // Provide metadata for validation. - struct NaClRichFileInfo info; - NaClRichFileInfoCtor(&info); - info.known_file = 1; - info.file_path = alloc_file_path; // Takes ownership. - info.file_path_length = - static_cast<uint32_t>(file_path_str.length()); - NaClSetFileOriginInfo(desc_wrapper->desc(), &info); - NaClRichFileInfoDtor(&info); ppapi::proxy::SerializedHandle sh; sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0); scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh); scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); - rewritten_msg->AddDescriptor(desc_wrapper.release()); + struct NaClDesc* desc = + NaClDescCreateWithFilePathMetadata(handle, file_path_str.c_str()); + rewritten_msg->AddDescriptor(new NaClDescWrapper(desc)); { base::AutoLock lock(lock_); SaveMessage(*new_msg, rewritten_msg.get());
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc index ae865f8..604557c 100644 --- a/components/nacl/loader/nacl_listener.cc +++ b/components/nacl/loader/nacl_listener.cc
@@ -35,6 +35,7 @@ #include "native_client/src/public/nacl_file_info.h" #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" #include "third_party/mojo/src/mojo/edk/embedder/platform_support.h" +#include "third_party/mojo/src/mojo/edk/embedder/simple_platform_support.h" #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" @@ -433,7 +434,8 @@ #if !defined(OS_MACOSX) // Don't call mojo::embedder::Init on Mac; it's already been called from // ChromeMain() (see chrome/app/chrome_exe_main_mac.cc). - mojo::embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>()); + mojo::embedder::Init(make_scoped_ptr( + new mojo::embedder::SimplePlatformSupport())); #endif // InjectMojo adds a file descriptor to the process that allows Mojo calls // to use an implementation defined outside the NaCl sandbox. See
diff --git a/components/nacl/loader/nacl_main_platform_delegate_win.cc b/components/nacl/loader/nacl_main_platform_delegate_win.cc index f530961..cc75ad2 100644 --- a/components/nacl/loader/nacl_main_platform_delegate_win.cc +++ b/components/nacl/loader/nacl_main_platform_delegate_win.cc
@@ -26,6 +26,13 @@ // Warm up language subsystems before the sandbox is turned on. ::GetUserDefaultLangID(); ::GetUserDefaultLCID(); + +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + CHECK(LoadLibraryA("dbghelp.dll")); +#endif + // Turn the sandbox on. target_services->LowerToken(); }
diff --git a/components/nacl/loader/nacl_validation_query.cc b/components/nacl/loader/nacl_validation_query.cc index 0a3582e9..b79278c 100644 --- a/components/nacl/loader/nacl_validation_query.cc +++ b/components/nacl/loader/nacl_validation_query.cc
@@ -31,15 +31,6 @@ return query; } -bool NaClValidationQueryContext::ResolveFileToken( - struct NaClFileToken* file_token, - int32* fd, - std::string* path) { - // This should no longer be used. - CHECK(false); - return false; -} - NaClValidationQuery::NaClValidationQuery(NaClValidationDB* db, const std::string& profile_key) : state_(READY), @@ -138,24 +129,6 @@ delete static_cast<NaClValidationQuery*>(query); } -static int ResolveFileToken(void* handle, struct NaClFileToken* file_token, - int32* fd, char** file_path, - uint32* file_path_length) { - std::string path; - *file_path = NULL; - *file_path_length = 0; - bool ok = static_cast<NaClValidationQueryContext*>(handle)-> - ResolveFileToken(file_token, fd, &path); - if (ok) { - *file_path = static_cast<char*>(malloc(path.length() + 1)); - CHECK(*file_path); - memcpy(*file_path, path.data(), path.length()); - (*file_path)[path.length()] = 0; - *file_path_length = static_cast<uint32>(path.length()); - } - return ok; -} - struct NaClValidationCache* CreateValidationCache( NaClValidationDB* db, const std::string& profile_key, const std::string& nacl_version) { @@ -169,6 +142,5 @@ cache->QueryKnownToValidate = QueryKnownToValidate; cache->SetKnownToValidate = SetKnownToValidate; cache->DestroyQuery = DestroyQuery; - cache->ResolveFileToken = ResolveFileToken; return cache; }
diff --git a/components/nacl/loader/nacl_validation_query.h b/components/nacl/loader/nacl_validation_query.h index 19ca8b9..1cf67dc7 100644 --- a/components/nacl/loader/nacl_validation_query.h +++ b/components/nacl/loader/nacl_validation_query.h
@@ -11,7 +11,6 @@ #include "base/strings/string_piece.h" #include "crypto/hmac.h" -struct NaClFileToken; struct NaClValidationCache; class NaClValidationDB; class NaClValidationQuery; @@ -24,9 +23,6 @@ NaClValidationQuery* CreateQuery(); - bool ResolveFileToken(struct NaClFileToken* file_token, int32* fd, - std::string* path); - private: NaClValidationDB* db_;
diff --git a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc index 5c4fa42..8d4a2259 100644 --- a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc +++ b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc
@@ -6,6 +6,7 @@ #include <errno.h> #include <fcntl.h> +#include <sys/prctl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -22,7 +23,10 @@ #include "components/nacl/common/nacl_switches.h" #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" #include "components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.h" +#include "content/public/common/content_switches.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" +#include "sandbox/linux/services/credentials.h" +#include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/services/proc_util.h" #include "sandbox/linux/services/thread_helpers.h" #include "sandbox/linux/suid/client/setuid_sandbox_client.h" @@ -50,6 +54,21 @@ return proc_self_task.Pass(); } +bool MaybeSetProcessNonDumpable() { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kAllowSandboxDebugging)) { + return true; + } + + if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) { + PLOG(ERROR) << "Failed to set non-dumpable flag"; + return false; + } + + return prctl(PR_GET_DUMPABLE) == 0; +} + } // namespace NaClSandbox::NaClSandbox() @@ -91,27 +110,37 @@ // Get sandboxed. CHECK(setuid_sandbox_client_->ChrootMe()); + CHECK(MaybeSetProcessNonDumpable()); + CHECK(IsSandboxed()); + layer_one_enabled_ = true; + } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) { + CHECK(sandbox::Credentials::MoveToNewUserNS()); + CHECK(sandbox::Credentials::DropFileSystemAccess()); + CHECK(sandbox::Credentials::DropAllCapabilities()); CHECK(IsSandboxed()); layer_one_enabled_ = true; } } void NaClSandbox::CheckForExpectedNumberOfOpenFds() { + // We expect to have the following FDs open: + // 1-3) stdin, stdout, stderr. + // 4) The /dev/urandom FD used by base::GetUrandomFD(). + // 5) A dummy pipe FD used to overwrite kSandboxIPCChannel. + // 6) The socket for the Chrome IPC channel that's connected to the + // browser process, kPrimaryIPCChannel. + // We also have an fd for /proc (proc_fd_), but CountOpenFds excludes this. + // + // This sanity check ensures that dynamically loaded libraries don't + // leave any FDs open before we enable the sandbox. + int expected_num_fds = 6; if (setuid_sandbox_client_->IsSuidSandboxChild()) { - // We expect to have the following FDs open: - // 1-3) stdin, stdout, stderr. - // 4) The /dev/urandom FD used by base::GetUrandomFD(). - // 5) A dummy pipe FD used to overwrite kSandboxIPCChannel. - // 6) The socket created by the SUID sandbox helper, used by ChrootMe(). - // After ChrootMe(), this is no longer connected to anything. - // (Only present when running under the SUID sandbox.) - // 7) The socket for the Chrome IPC channel that's connected to the - // browser process, kPrimaryIPCChannel. - // - // This sanity check ensures that dynamically loaded libraries don't - // leave any FDs open before we enable the sandbox. - CHECK_EQ(7, sandbox::ProcUtil::CountOpenFds(proc_fd_.get())); + // When using the setuid sandbox, there is one additional socket used for + // ChrootMe(). After ChrootMe(), it is no longer connected to anything. + ++expected_num_fds; } + + CHECK_EQ(expected_num_fds, sandbox::ProcUtil::CountOpenFds(proc_fd_.get())); } void NaClSandbox::InitializeLayerTwoSandbox(bool uses_nonsfi_mode) {
diff --git a/components/nacl/zygote/nacl_fork_delegate_linux.cc b/components/nacl/zygote/nacl_fork_delegate_linux.cc index e424d2e4..428dbbe 100644 --- a/components/nacl/zygote/nacl_fork_delegate_linux.cc +++ b/components/nacl/zygote/nacl_fork_delegate_linux.cc
@@ -35,7 +35,9 @@ #include "components/nacl/loader/nacl_helper_linux.h" #include "content/public/common/content_descriptors.h" #include "content/public/common/content_switches.h" +#include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/suid/client/setuid_sandbox_client.h" +#include "sandbox/linux/suid/client/setuid_sandbox_host.h" #include "sandbox/linux/suid/common/sandbox.h" namespace { @@ -146,11 +148,23 @@ return; } + // TODO(rickyz): Make IsSuidSandboxChild a static function. scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client( sandbox::SetuidSandboxClient::Create()); + const bool using_setuid_sandbox = setuid_sandbox_client->IsSuidSandboxChild(); + const bool using_namespace_sandbox = + sandbox::NamespaceSandbox::InNewUserNamespace(); + + CHECK(!(using_setuid_sandbox && using_namespace_sandbox)); + if (enable_layer1_sandbox) { + CHECK(using_setuid_sandbox || using_namespace_sandbox); + } + + scoped_ptr<sandbox::SetuidSandboxHost> setuid_sandbox_host( + sandbox::SetuidSandboxHost::Create()); // For communications between the NaCl loader process and - // the SUID sandbox. + // the browser process. int nacl_sandbox_descriptor = base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; // Confirm a hard-wired assumption. @@ -209,6 +223,7 @@ // Append any switches that need to be forwarded to the NaCl helper. static const char* kForwardSwitches[] = { + switches::kAllowSandboxDebugging, switches::kDisableSeccompFilterSandbox, switches::kEnableNaClDebug, switches::kNaClDangerousNoSandboxNonSfi, @@ -239,15 +254,13 @@ base::LaunchOptions options; base::ScopedFD dummy_fd; - if (enable_layer1_sandbox) { + if (using_setuid_sandbox) { // NaCl needs to keep tight control of the cmd_line, so prepend the // setuid sandbox wrapper manually. - base::FilePath sandbox_path = - setuid_sandbox_client->GetSandboxBinaryPath(); + base::FilePath sandbox_path = setuid_sandbox_host->GetSandboxBinaryPath(); argv_to_launch.insert(argv_to_launch.begin(), sandbox_path.value()); - setuid_sandbox_client->SetupLaunchOptions( - &options, &fds_to_map, &dummy_fd); - setuid_sandbox_client->SetupLaunchEnvironment(); + setuid_sandbox_host->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd); + setuid_sandbox_host->SetupLaunchEnvironment(); } options.fds_to_remap = &fds_to_map; @@ -267,11 +280,16 @@ options.clear_environ = true; AddPassthroughEnvToOptions(&options); - if (!base::LaunchProcess(argv_to_launch, options).IsValid()) + base::Process process = + using_namespace_sandbox + ? sandbox::NamespaceSandbox::LaunchProcess(argv_to_launch, options) + : base::LaunchProcess(argv_to_launch, options); + + if (!process.IsValid()) status_ = kNaClHelperLaunchFailed; // parent and error cases are handled below - if (enable_layer1_sandbox) { + if (using_setuid_sandbox) { // Sanity check that dummy_fd was kept alive for LaunchProcess. DCHECK(dummy_fd.is_valid()); }
diff --git a/components/navigation_interception/intercept_navigation_delegate.h b/components/navigation_interception/intercept_navigation_delegate.h index 71914c25..8c120c63 100644 --- a/components/navigation_interception/intercept_navigation_delegate.h +++ b/components/navigation_interception/intercept_navigation_delegate.h
@@ -38,7 +38,7 @@ class InterceptNavigationDelegate : public base::SupportsUserData::Data { public: InterceptNavigationDelegate(JNIEnv* env, jobject jdelegate); - virtual ~InterceptNavigationDelegate(); + ~InterceptNavigationDelegate() override; // Associates the InterceptNavigationDelegate with a WebContents using the // SupportsUserData mechanism.
diff --git a/components/omnibox/autocomplete_match.cc b/components/omnibox/autocomplete_match.cc index 89aa684..51344fb 100644 --- a/components/omnibox/autocomplete_match.cc +++ b/components/omnibox/autocomplete_match.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -411,8 +412,7 @@ static const size_t prefix_len = arraysize(prefix) - 1; std::string host = stripped_destination_url.host(); if (host.compare(0, prefix_len, prefix) == 0) { - host = host.substr(prefix_len); - replacements.SetHostStr(host); + replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); needs_replacement = true; }
diff --git a/components/omnibox/search_suggestion_parser.cc b/components/omnibox/search_suggestion_parser.cc index 7e06d950..a554fbc 100644 --- a/components/omnibox/search_suggestion_parser.cc +++ b/components/omnibox/search_suggestion_parser.cc
@@ -343,14 +343,13 @@ // static scoped_ptr<base::Value> SearchSuggestionParser::DeserializeJsonData( - std::string json_data) { + base::StringPiece json_data) { // The JSON response should be an array. for (size_t response_start_index = json_data.find("["), i = 0; - response_start_index != std::string::npos && i < 5; + response_start_index != base::StringPiece::npos && i < 5; response_start_index = json_data.find("[", 1), i++) { // Remove any XSSI guards to allow for JSON parsing. - if (response_start_index > 0) - json_data.erase(0, response_start_index); + json_data.remove_prefix(response_start_index); JSONStringValueSerializer deserializer(json_data); deserializer.set_allow_trailing_comma(true);
diff --git a/components/omnibox/search_suggestion_parser.h b/components/omnibox/search_suggestion_parser.h index 4cba602..e86affb 100644 --- a/components/omnibox/search_suggestion_parser.h +++ b/components/omnibox/search_suggestion_parser.h
@@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/strings/string16.h" +#include "base/strings/string_piece.h" #include "components/omnibox/autocomplete_match.h" #include "components/omnibox/autocomplete_match_type.h" #include "components/omnibox/suggestion_answer.h" @@ -286,7 +287,8 @@ // Parses JSON response received from the provider, stripping XSSI // protection if needed. Returns the parsed data if successful, NULL // otherwise. - static scoped_ptr<base::Value> DeserializeJsonData(std::string json_data); + static scoped_ptr<base::Value> DeserializeJsonData( + base::StringPiece json_data); // Parses results from the suggest server and updates the appropriate suggest // and navigation result lists in |results|. |is_keyword_result| indicates
diff --git a/components/password_manager/content/browser/content_credential_manager_dispatcher_unittest.cc b/components/password_manager/content/browser/content_credential_manager_dispatcher_unittest.cc index e7bf309f..0c4c6dc8 100644 --- a/components/password_manager/content/browser/content_credential_manager_dispatcher_unittest.cc +++ b/components/password_manager/content/browser/content_credential_manager_dispatcher_unittest.cc
@@ -261,13 +261,32 @@ } TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifySignedOut) { + store_->AddLogin(form_); + store_->AddLogin(cross_origin_form_); + RunAllPendingTasks(); + + TestPasswordStore::PasswordMap passwords = store_->stored_passwords(); + EXPECT_EQ(2U, passwords.size()); + EXPECT_EQ(1U, passwords[form_.signon_realm].size()); + EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size()); + EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click); + EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click); + dispatcher()->OnNotifySignedOut(kRequestId); + RunAllPendingTasks(); const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedOut::ID; const IPC::Message* message = process()->sink().GetFirstMessageMatching(kMsgID); EXPECT_TRUE(message); process()->sink().ClearMessages(); + + passwords = store_->stored_passwords(); + EXPECT_EQ(2U, passwords.size()); + EXPECT_EQ(1U, passwords[form_.signon_realm].size()); + EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size()); + EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click); + EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click); } TEST_F(CredentialManagerDispatcherTest,
diff --git a/components/password_manager/content/browser/credential_manager_dispatcher.cc b/components/password_manager/content/browser/credential_manager_dispatcher.cc index d459cfa..fdb6f5f 100644 --- a/components/password_manager/content/browser/credential_manager_dispatcher.cc +++ b/components/password_manager/content/browser/credential_manager_dispatcher.cc
@@ -23,6 +23,8 @@ namespace password_manager { +// CredentialManagerDispatcher::PendingRequestTask ----------------------------- + class CredentialManagerDispatcher::PendingRequestTask : public PasswordStoreConsumer { public: @@ -102,6 +104,60 @@ DISALLOW_COPY_AND_ASSIGN(PendingRequestTask); }; +// CredentialManagerDispatcher::PendingSignedOutTask --------------------------- + +class CredentialManagerDispatcher::PendingSignedOutTask + : public PasswordStoreConsumer { + public: + PendingSignedOutTask(CredentialManagerDispatcher* const dispatcher, + const GURL& origin); + + void AddOrigin(const GURL& origin); + + // PasswordStoreConsumer implementation. + void OnGetPasswordStoreResults( + const std::vector<autofill::PasswordForm*>& results) override; + + private: + // Backlink to the CredentialManagerDispatcher that owns this object. + CredentialManagerDispatcher* const dispatcher_; + std::set<std::string> origins_; + + DISALLOW_COPY_AND_ASSIGN(PendingSignedOutTask); +}; + +CredentialManagerDispatcher::PendingSignedOutTask::PendingSignedOutTask( + CredentialManagerDispatcher* const dispatcher, + const GURL& origin) + : dispatcher_(dispatcher) { + origins_.insert(origin.spec()); +} + +void CredentialManagerDispatcher::PendingSignedOutTask::AddOrigin( + const GURL& origin) { + origins_.insert(origin.spec()); +} + +void CredentialManagerDispatcher::PendingSignedOutTask:: + OnGetPasswordStoreResults( + const std::vector<autofill::PasswordForm*>& results) { + PasswordStore* store = dispatcher_->GetPasswordStore(); + for (autofill::PasswordForm* form : results) { + if (origins_.count(form->origin.spec())) { + form->skip_zero_click = true; + store->UpdateLogin(*form); + } + // We own the PasswordForms, so we need to dispose of them. This is safe to + // do, as ::UpdateLogin ends up copying the form while posting a task to + // update the PasswordStore. + delete form; + } + + dispatcher_->DoneSigningOut(); +} + +// CredentialManagerDispatcher ------------------------------------------------- + CredentialManagerDispatcher::CredentialManagerDispatcher( content::WebContents* web_contents, PasswordManagerClient* client) @@ -153,6 +209,7 @@ scoped_ptr<autofill::PasswordForm> form(CreatePasswordFormFromCredentialInfo( credential, web_contents()->GetLastCommittedURL().GetOrigin())); + form->skip_zero_click = !IsZeroClickAllowed(); // TODO(mkwst): This is a stub; we should be checking the PasswordStore to // determine whether or not the credential exists, and calling UpdateLogin @@ -168,7 +225,22 @@ void CredentialManagerDispatcher::OnNotifySignedOut(int request_id) { DCHECK(request_id); - // TODO(mkwst): This is a stub. + + PasswordStore* store = GetPasswordStore(); + if (store) { + if (!pending_sign_out_) { + pending_sign_out_.reset(new PendingSignedOutTask( + this, web_contents()->GetLastCommittedURL().GetOrigin())); + + // This will result in a callback to + // PendingSignedOutTask::OnGetPasswordStoreResults(). + store->GetAutofillableLogins(pending_sign_out_.get()); + } else { + pending_sign_out_->AddOrigin( + web_contents()->GetLastCommittedURL().GetOrigin()); + } + } + web_contents()->GetRenderViewHost()->Send( new CredentialManagerMsg_AcknowledgeSignedOut( web_contents()->GetRenderViewHost()->GetRoutingID(), request_id)); @@ -234,6 +306,9 @@ const CredentialInfo& info) { DCHECK(pending_request_); DCHECK_EQ(pending_request_->id(), request_id); + // TODO(mkwst): We need to update the underlying PasswordForm if the user + // has enabled zeroclick globally, and clicks through a non-zeroclick form + // for an origin. web_contents()->GetRenderViewHost()->Send( new CredentialManagerMsg_SendCredential( web_contents()->GetRenderViewHost()->GetRoutingID(), @@ -241,4 +316,9 @@ pending_request_.reset(); } +void CredentialManagerDispatcher::DoneSigningOut() { + DCHECK(pending_sign_out_); + pending_sign_out_.reset(); +} + } // namespace password_manager
diff --git a/components/password_manager/content/browser/credential_manager_dispatcher.h b/components/password_manager/content/browser/credential_manager_dispatcher.h index fdcfc81..ef32f1c1 100644 --- a/components/password_manager/content/browser/credential_manager_dispatcher.h +++ b/components/password_manager/content/browser/credential_manager_dispatcher.h
@@ -72,6 +72,7 @@ private: class PendingRequestTask; + class PendingSignedOutTask; PasswordStore* GetPasswordStore(); @@ -83,6 +84,7 @@ virtual base::WeakPtr<PasswordManagerDriver> GetDriver(); void SendCredential(int request_id, const CredentialInfo& info); + void DoneSigningOut(); PasswordManagerClient* client_; scoped_ptr<CredentialManagerPasswordFormManager> form_manager_; @@ -95,6 +97,7 @@ // they can properly respond to the request once the PasswordStore gives // us data. scoped_ptr<PendingRequestTask> pending_request_; + scoped_ptr<PendingSignedOutTask> pending_sign_out_; DISALLOW_COPY_AND_ASSIGN(CredentialManagerDispatcher); };
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index fb7d3bb..8b7130c 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -8,7 +8,6 @@ #include <vector> #include "base/callback.h" -#include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" @@ -20,32 +19,16 @@ #include "components/password_manager/core/browser/password_store_sync.h" #include "sync/api/syncable_service.h" -class Task; - namespace autofill { struct PasswordForm; } -namespace password_manager { -class PasswordStore; -} // namespace password_manager - -namespace passwords_helper { -void AddLogin(password_manager::PasswordStore* store, - const autofill::PasswordForm& form); -void RemoveLogin(password_manager::PasswordStore* store, - const autofill::PasswordForm& form); -void UpdateLogin(password_manager::PasswordStore* store, - const autofill::PasswordForm& form); -} - namespace syncer { class SyncableService; } namespace password_manager { -class PasswordManagerClient; class PasswordStoreConsumer; class PasswordSyncableService; @@ -188,7 +171,6 @@ protected: friend class base::RefCountedThreadSafe<PasswordStore>; - FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, IgnoreOldWwwGoogleLogins); typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask;
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc index 1ea86a59..89c8258 100644 --- a/components/plugins/renderer/loadable_plugin_placeholder.cc +++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -50,6 +50,19 @@ } #endif +void LoadablePluginPlaceholder::SetPremadePlugin( + blink::WebPlugin* plugin, + content::PluginInstanceThrottler* throttler) { + DCHECK(plugin); + DCHECK(throttler); + DCHECK(!premade_plugin_); + DCHECK(!premade_throttler_); + premade_plugin_ = plugin; + premade_throttler_ = throttler; + + premade_throttler_->AddObserver(this); +} + LoadablePluginPlaceholder::LoadablePluginPlaceholder( content::RenderFrame* render_frame, WebLocalFrame* frame, @@ -65,6 +78,8 @@ is_blocked_for_prerendering_(false), is_blocked_for_power_saver_poster_(false), power_saver_mode_(PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL), + premade_plugin_(nullptr), + premade_throttler_(nullptr), allow_loading_(false), placeholder_was_replaced_(false), hidden_(false), @@ -74,6 +89,9 @@ LoadablePluginPlaceholder::~LoadablePluginPlaceholder() { #if defined(ENABLE_PLUGINS) + DCHECK(!premade_plugin_); + DCHECK(!premade_throttler_); + if (!placeholder_was_replaced_ && !is_blocked_for_prerendering_ && power_saver_mode_ != PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL) { PluginInstanceThrottler::RecordUnthrottleMethodMetric( @@ -89,7 +107,12 @@ return; power_saver_mode_ = PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL; - PluginInstanceThrottler::RecordUnthrottleMethodMetric(method); + if (premade_throttler_) { + premade_throttler_->MarkPluginEssential(method); + } else { + PluginInstanceThrottler::RecordUnthrottleMethodMetric(method); + } + if (is_blocked_for_power_saver_poster_) { is_blocked_for_power_saver_poster_ = false; if (!LoadingBlocked()) @@ -117,7 +140,7 @@ // Save the element in case the plug-in is removed from the page during // initialization. WebElement element = container->element(); - if (!new_plugin->initialize(container)) { + if (new_plugin != premade_plugin_ && !new_plugin->initialize(container)) { // We couldn't initialize the new plug-in. Restore the old one and abort. container->setPlugin(plugin()); return; @@ -130,6 +153,8 @@ return; } + placeholder_was_replaced_ = true; + // During initialization, the new plug-in might have replaced itself in turn // with another plug-in. Make sure not to use the passed in |new_plugin| after // this point. @@ -140,8 +165,6 @@ container->reportGeometry(); plugin()->ReplayReceivedData(new_plugin); plugin()->destroy(); - - placeholder_was_replaced_ = true; } void LoadablePluginPlaceholder::HidePlugin() { @@ -207,10 +230,19 @@ WebScriptSource(base::UTF8ToUTF16(script))); } -void LoadablePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) { - // Does nothing by default. Will be overridden if a specific browser wants - // a context menu. - return; +void LoadablePluginPlaceholder::PluginDestroyed() { + // Since the premade plugin has been detached from the container, it will not + // be automatically destroyed along with the page. + if (!placeholder_was_replaced_ && premade_plugin_) { + DCHECK(premade_throttler_); + premade_throttler_->RemoveObserver(this); + premade_throttler_ = nullptr; + + premade_plugin_->destroy(); + premade_plugin_ = nullptr; + } + + PluginPlaceholder::PluginDestroyed(); } void LoadablePluginPlaceholder::WasShown() { @@ -221,6 +253,15 @@ } } +void LoadablePluginPlaceholder::OnThrottleStateChange() { + DCHECK(premade_plugin_); + DCHECK(premade_throttler_); + if (!premade_throttler_->IsThrottled()) { + // Premade plugin has been unthrottled externally (by audio playback, etc.). + LoadPlugin(); + } +} + void LoadablePluginPlaceholder::OnLoadBlockedPlugins( const std::string& identifier) { if (!identifier.empty() && identifier != identifier_) @@ -253,17 +294,27 @@ return; } - // TODO(mmenke): In the case of prerendering, feed into - // ChromeContentRendererClient::CreatePlugin instead, to - // reduce the chance of future regressions. - scoped_ptr<PluginInstanceThrottler> throttler; + if (premade_plugin_) { + premade_throttler_->RemoveObserver(this); + premade_throttler_->SetHiddenForPlaceholder(false /* hidden */); + premade_throttler_ = nullptr; + + ReplacePlugin(premade_plugin_); + premade_plugin_ = nullptr; + } else { + // TODO(mmenke): In the case of prerendering, feed into + // ChromeContentRendererClient::CreatePlugin instead, to + // reduce the chance of future regressions. + scoped_ptr<PluginInstanceThrottler> throttler; #if defined(ENABLE_PLUGINS) - throttler = PluginInstanceThrottler::Get( - render_frame(), GetPluginParams().url, power_saver_mode_); + throttler = PluginInstanceThrottler::Get( + render_frame(), GetPluginParams().url, power_saver_mode_); #endif - WebPlugin* plugin = render_frame()->CreatePlugin( - GetFrame(), plugin_info_, GetPluginParams(), throttler.Pass()); - ReplacePlugin(plugin); + WebPlugin* plugin = render_frame()->CreatePlugin( + GetFrame(), plugin_info_, GetPluginParams(), throttler.Pass()); + + ReplacePlugin(plugin); + } } void LoadablePluginPlaceholder::LoadCallback() { @@ -286,6 +337,11 @@ finished_loading_ = true; if (message_.length() > 0) UpdateMessage(); + + // Wait for the placeholder to finish loading to hide the premade plugin. + // This is necessary to prevent a flicker. + if (premade_plugin_ && !placeholder_was_replaced_) + premade_throttler_->SetHiddenForPlaceholder(true /* hidden */); } void LoadablePluginPlaceholder::SetPluginInfo(
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.h b/components/plugins/renderer/loadable_plugin_placeholder.h index 402fdc7..401ec7d 100644 --- a/components/plugins/renderer/loadable_plugin_placeholder.h +++ b/components/plugins/renderer/loadable_plugin_placeholder.h
@@ -13,7 +13,9 @@ namespace plugins { // Placeholders can be used if a plug-in is missing or not available // (blocked or disabled). -class LoadablePluginPlaceholder : public PluginPlaceholder { +class LoadablePluginPlaceholder + : public PluginPlaceholder, + public content::PluginInstanceThrottler::Observer { public: void set_blocked_for_background_tab(bool blocked_for_background_tab) { is_blocked_for_background_tab_ = blocked_for_background_tab; @@ -34,6 +36,10 @@ void set_allow_loading(bool allow_loading) { allow_loading_ = allow_loading; } + // When we load the plugin, use this already-created plugin, not a new one. + void SetPremadePlugin(blink::WebPlugin* plugin, + content::PluginInstanceThrottler* throttler); + protected: LoadablePluginPlaceholder(content::RenderFrame* render_frame, blink::WebLocalFrame* frame, @@ -73,11 +79,14 @@ private: // WebViewPlugin::Delegate methods: - void ShowContextMenu(const blink::WebMouseEvent&) override; + void PluginDestroyed() override; // RenderFrameObserver methods: void WasShown() override; + // content::PluginInstanceThrottler::Observer methods: + void OnThrottleStateChange() override; + // Javascript callbacks: // Load the blocked plugin by calling LoadPlugin(). @@ -110,6 +119,10 @@ // This is independent of deferred plugin load due to a Power Saver poster. content::PluginPowerSaverMode power_saver_mode_; + // When we load, uses this premade plugin instead of creating a new one. + blink::WebPlugin* premade_plugin_; + content::PluginInstanceThrottler* premade_throttler_; + bool allow_loading_; // True if the placeholder was replaced with the real plugin.
diff --git a/components/plugins/renderer/plugin_placeholder.h b/components/plugins/renderer/plugin_placeholder.h index b0f0f4ce..b3e47c75 100644 --- a/components/plugins/renderer/plugin_placeholder.h +++ b/components/plugins/renderer/plugin_placeholder.h
@@ -35,11 +35,11 @@ blink::WebLocalFrame* GetFrame(); const blink::WebPluginParams& GetPluginParams() const; - private: // WebViewPlugin::Delegate methods: void ShowContextMenu(const blink::WebMouseEvent&) override; void PluginDestroyed() override; + private: // RenderFrameObserver methods: void OnDestruct() override;
diff --git a/components/policy/core/browser/managed_bookmarks_tracker.cc b/components/policy/core/browser/managed_bookmarks_tracker.cc index 336ef02..eb12731 100644 --- a/components/policy/core/browser/managed_bookmarks_tracker.cc +++ b/components/policy/core/browser/managed_bookmarks_tracker.cc
@@ -20,6 +20,8 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; namespace policy {
diff --git a/components/policy/core/browser/managed_bookmarks_tracker.h b/components/policy/core/browser/managed_bookmarks_tracker.h index 99f0761..c355390 100644 --- a/components/policy/core/browser/managed_bookmarks_tracker.h +++ b/components/policy/core/browser/managed_bookmarks_tracker.h
@@ -11,8 +11,6 @@ #include "base/strings/string16.h" #include "components/policy/policy_export.h" -class BookmarkNode; -class BookmarkPermanentNode; class GURL; class PrefService; @@ -22,6 +20,8 @@ namespace bookmarks { class BookmarkModel; +class BookmarkNode; +class BookmarkPermanentNode; } namespace policy { @@ -49,17 +49,18 @@ // Loads the initial managed bookmarks in |list| into |folder|. New nodes // will be assigned IDs starting at |next_node_id|. // Returns the next node ID to use. - static int64 LoadInitial(BookmarkNode* folder, + static int64 LoadInitial(bookmarks::BookmarkNode* folder, const base::ListValue* list, int64 next_node_id); // Starts tracking the policy for updates to the managed bookmarks. Should // be called after loading the initial bookmarks. - void Init(BookmarkPermanentNode* managed_node); + void Init(bookmarks::BookmarkPermanentNode* managed_node); private: void ReloadManagedBookmarks(); - void UpdateBookmarks(const BookmarkNode* folder, const base::ListValue* list); + void UpdateBookmarks(const bookmarks::BookmarkNode* folder, + const base::ListValue* list); static bool LoadBookmark(const base::ListValue* list, size_t index, base::string16* title, @@ -67,7 +68,7 @@ const base::ListValue** children); bookmarks::BookmarkModel* model_; - BookmarkPermanentNode* managed_node_; + bookmarks::BookmarkPermanentNode* managed_node_; PrefService* prefs_; PrefChangeRegistrar registrar_; GetManagementDomainCallback get_management_domain_callback_; @@ -78,3 +79,4 @@ } // namespace policy #endif // COMPONENTS_POLICY_CORE_BROWSER_MANAGED_BOOKMARKS_TRACKER_H_ +
diff --git a/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc b/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc index 238fac4..c2149fc 100644 --- a/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc +++ b/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc
@@ -25,6 +25,8 @@ #include "url/gurl.h" using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; +using bookmarks::BookmarkPermanentNode; using testing::Mock; using testing::_;
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 6f4768a..6f7fbf93 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -79,7 +79,8 @@ dm_token_ = dm_token; client_id_ = client_id; - request_job_.reset(); + request_jobs_.clear(); + policy_fetch_request_job_.reset(); STLDeleteValues(&responses_); NotifyRegistrationStateChanged(); @@ -104,14 +105,14 @@ client_id_ = client_id; } - request_job_.reset( + policy_fetch_request_job_.reset( service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, GetRequestContext())); - request_job_->SetOAuthToken(auth_token); - request_job_->SetClientID(client_id_); + policy_fetch_request_job_->SetOAuthToken(auth_token); + policy_fetch_request_job_->SetClientID(client_id_); em::DeviceRegisterRequest* request = - request_job_->GetRequest()->mutable_register_request(); + policy_fetch_request_job_->GetRequest()->mutable_register_request(); if (!client_id.empty()) request->set_reregister(true); request->set_type(type); @@ -125,11 +126,12 @@ request->set_server_backed_state_key(current_state_key); request->set_flavor(flavor); - request_job_->SetRetryCallback( + policy_fetch_request_job_->SetRetryCallback( base::Bind(&CloudPolicyClient::OnRetryRegister, base::Unretained(this))); - request_job_->Start(base::Bind(&CloudPolicyClient::OnRegisterCompleted, - base::Unretained(this))); + policy_fetch_request_job_->Start( + base::Bind(&CloudPolicyClient::OnRegisterCompleted, + base::Unretained(this))); } void CloudPolicyClient::SetInvalidationInfo( @@ -143,14 +145,15 @@ CHECK(is_registered()); CHECK(!types_to_fetch_.empty()); - request_job_.reset( + policy_fetch_request_job_.reset( service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, GetRequestContext())); - request_job_->SetDMToken(dm_token_); - request_job_->SetClientID(client_id_); - request_job_->SetUserAffiliation(user_affiliation_); + policy_fetch_request_job_->SetDMToken(dm_token_); + policy_fetch_request_job_->SetClientID(client_id_); + policy_fetch_request_job_->SetUserAffiliation(user_affiliation_); - em::DeviceManagementRequest* request = request_job_->GetRequest(); + em::DeviceManagementRequest* request = + policy_fetch_request_job_->GetRequest(); // Build policy fetch requests. em::DevicePolicyRequest* policy_request = request->mutable_policy_request(); @@ -201,65 +204,70 @@ fetched_invalidation_version_ = invalidation_version_; // Fire the job. - request_job_->Start(base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted, - base::Unretained(this))); + policy_fetch_request_job_->Start( + base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted, + base::Unretained(this))); } void CloudPolicyClient::FetchRobotAuthCodes(const std::string& auth_token) { CHECK(is_registered()); DCHECK(!auth_token.empty()); - request_job_.reset(service_->CreateJob( + policy_fetch_request_job_.reset(service_->CreateJob( DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH, GetRequestContext())); // The credentials of a domain user are needed in order to mint a new OAuth2 // authorization token for the robot account. - request_job_->SetOAuthToken(auth_token); - request_job_->SetDMToken(dm_token_); - request_job_->SetClientID(client_id_); + policy_fetch_request_job_->SetOAuthToken(auth_token); + policy_fetch_request_job_->SetDMToken(dm_token_); + policy_fetch_request_job_->SetClientID(client_id_); em::DeviceServiceApiAccessRequest* request = - request_job_->GetRequest()->mutable_service_api_access_request(); + policy_fetch_request_job_->GetRequest()-> + mutable_service_api_access_request(); request->set_oauth2_client_id( GaiaUrls::GetInstance()->oauth2_chrome_client_id()); request->add_auth_scope(GaiaConstants::kAnyApiOAuth2Scope); - request_job_->Start( + policy_fetch_request_job_->Start( base::Bind(&CloudPolicyClient::OnFetchRobotAuthCodesCompleted, base::Unretained(this))); } void CloudPolicyClient::Unregister() { DCHECK(service_); - request_job_.reset( + policy_fetch_request_job_.reset( service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION, GetRequestContext())); - request_job_->SetDMToken(dm_token_); - request_job_->SetClientID(client_id_); - request_job_->GetRequest()->mutable_unregister_request(); - request_job_->Start(base::Bind(&CloudPolicyClient::OnUnregisterCompleted, - base::Unretained(this))); + policy_fetch_request_job_->SetDMToken(dm_token_); + policy_fetch_request_job_->SetClientID(client_id_); + policy_fetch_request_job_->GetRequest()->mutable_unregister_request(); + policy_fetch_request_job_->Start( + base::Bind(&CloudPolicyClient::OnUnregisterCompleted, + base::Unretained(this))); } void CloudPolicyClient::UploadCertificate( const std::string& certificate_data, const CloudPolicyClient::StatusCallback& callback) { CHECK(is_registered()); - request_job_.reset( + scoped_ptr<DeviceManagementRequestJob> request_job( service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE, GetRequestContext())); - request_job_->SetDMToken(dm_token_); - request_job_->SetClientID(client_id_); + request_job->SetDMToken(dm_token_); + request_job->SetClientID(client_id_); - em::DeviceManagementRequest* request = request_job_->GetRequest(); + em::DeviceManagementRequest* request = request_job->GetRequest(); request->mutable_cert_upload_request()->set_device_certificate( certificate_data); DeviceManagementRequestJob::Callback job_callback = base::Bind( &CloudPolicyClient::OnCertificateUploadCompleted, base::Unretained(this), + request_job.get(), callback); - request_job_->Start(job_callback); + request_jobs_.push_back(request_job.Pass()); + request_jobs_.back()->Start(job_callback); } void CloudPolicyClient::UploadDeviceStatus( @@ -269,13 +277,13 @@ CHECK(is_registered()); // Should pass in at least one type of status. DCHECK(device_status || session_status); - request_job_.reset( + scoped_ptr<DeviceManagementRequestJob> request_job( service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS, GetRequestContext())); - request_job_->SetDMToken(dm_token_); - request_job_->SetClientID(client_id_); + request_job->SetDMToken(dm_token_); + request_job->SetClientID(client_id_); - em::DeviceManagementRequest* request = request_job_->GetRequest(); + em::DeviceManagementRequest* request = request_job->GetRequest(); if (device_status) *request->mutable_device_status_report_request() = *device_status; if (session_status) @@ -284,12 +292,11 @@ DeviceManagementRequestJob::Callback job_callback = base::Bind( &CloudPolicyClient::OnStatusUploadCompleted, base::Unretained(this), + request_job.get(), callback); - // TODO(atwilson): Change CloudPolicyClient to support multiple requests in - // parallel, so status upload requests don't get cancelled by things like - // policy fetches (http://crbug.com/452563). - request_job_->Start(job_callback); + request_jobs_.push_back(request_job.Pass()); + request_jobs_.back()->Start(job_callback); } void CloudPolicyClient::AddObserver(Observer* observer) { @@ -330,8 +337,12 @@ return request_context_; } +int CloudPolicyClient::GetActiveRequestCountForTest() const { + return request_jobs_.size(); +} + void CloudPolicyClient::OnRetryRegister(DeviceManagementRequestJob* job) { - DCHECK_EQ(request_job_.get(), job); + DCHECK_EQ(policy_fetch_request_job_.get(), job); // If the initial request managed to get to the server but the response didn't // arrive at the client then retrying with the same client ID will fail. // Set the re-registration flag so that the server accepts it. @@ -450,6 +461,8 @@ status_ = status; if (status == DM_STATUS_SUCCESS) { dm_token_.clear(); + // Cancel all outstanding jobs. + request_jobs_.clear(); NotifyRegistrationStateChanged(); } else { NotifyClientError(); @@ -457,26 +470,39 @@ } void CloudPolicyClient::OnCertificateUploadCompleted( + const DeviceManagementRequestJob* job, const CloudPolicyClient::StatusCallback& callback, DeviceManagementStatus status, int net_error, const enterprise_management::DeviceManagementResponse& response) { - if (status == DM_STATUS_SUCCESS && !response.has_cert_upload_response()) { - LOG(WARNING) << "Empty upload certificate response."; - callback.Run(false); - return; - } - + bool success = true; status_ = status; if (status != DM_STATUS_SUCCESS) { + success = false; NotifyClientError(); - callback.Run(false); - return; + } else if (!response.has_cert_upload_response()) { + LOG(WARNING) << "Empty upload certificate response."; + success = false; } - callback.Run(true); + callback.Run(success); + // Must call RemoveJob() last, because it frees |callback|. + RemoveJob(job); +} + +void CloudPolicyClient::RemoveJob(const DeviceManagementRequestJob* job) { + for (auto it = request_jobs_.begin(); it != request_jobs_.end(); ++it) { + if (*it == job) { + request_jobs_.erase(it); + return; + } + } + // This job was already deleted from our list, somehow. This shouldn't + // happen since deleting the job should cancel the callback. + NOTREACHED(); } void CloudPolicyClient::OnStatusUploadCompleted( + const DeviceManagementRequestJob* job, const CloudPolicyClient::StatusCallback& callback, DeviceManagementStatus status, int net_error, @@ -486,6 +512,8 @@ NotifyClientError(); callback.Run(status == DM_STATUS_SUCCESS); + // Must call RemoveJob() last, because it frees |callback|. + RemoveJob(job); } void CloudPolicyClient::NotifyPolicyFetched() {
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index 3cb8468..4fefa864 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -14,6 +14,7 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "base/observer_list.h" #include "base/time/time.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" @@ -216,6 +217,9 @@ scoped_refptr<net::URLRequestContextGetter> GetRequestContext(); + // Returns the number of active requests. + int GetActiveRequestCountForTest() const; + protected: // A set of (policy type, settings entity ID) pairs to fetch. typedef std::set<std::pair<std::string, std::string>> PolicyTypeSet; @@ -249,6 +253,7 @@ // Callback for certificate upload requests. void OnCertificateUploadCompleted( + const DeviceManagementRequestJob* job, const StatusCallback& callback, DeviceManagementStatus status, int net_error, @@ -256,11 +261,15 @@ // Callback for status upload requests. void OnStatusUploadCompleted( + const DeviceManagementRequestJob* job, const StatusCallback& callback, DeviceManagementStatus status, int net_error, const enterprise_management::DeviceManagementResponse& response); + // Helper to remove a job from request_jobs_. + void RemoveJob(const DeviceManagementRequestJob* job); + // Observer notification helpers. void NotifyPolicyFetched(); void NotifyRegistrationStateChanged(); @@ -293,7 +302,14 @@ // Used for issuing requests to the cloud. DeviceManagementService* service_; - scoped_ptr<DeviceManagementRequestJob> request_job_; + + // Only one outstanding policy fetch is allowed, so this is tracked in + // its own member variable. + scoped_ptr<DeviceManagementRequestJob> policy_fetch_request_job_; + + // All of the outstanding non-policy-fetch request jobs. These jobs are + // silently cancelled if Unregister() is called. + ScopedVector<DeviceManagementRequestJob> request_jobs_; // The policy responses returned by the last policy fetch operation. ResponseMap responses_;
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc index f209e1a..dc9faf0 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -8,6 +8,7 @@ #include <set> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -479,7 +480,7 @@ TEST_F(CloudPolicyClientTest, PolicyFetchWithExtensionPolicy) { Register(); - // Setup the |expected_responses| and |policy_response_|. + // Set up the |expected_responses| and |policy_response_|. static const char* kExtensions[] = { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -603,6 +604,76 @@ EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); } +TEST_F(CloudPolicyClientTest, UploadStatusWhilePolicyFetchActive) { + Register(); + MockDeviceManagementJob* upload_status_job = nullptr; + EXPECT_CALL(service_, + CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS, + request_context_)) + .WillOnce(service_.CreateAsyncJob(&upload_status_job)); + EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _)); + EXPECT_CALL(upload_observer_, OnUploadComplete(true)).Times(1); + CloudPolicyClient::StatusCallback callback = base::Bind( + &MockUploadObserver::OnUploadComplete, + base::Unretained(&upload_observer_)); + em::DeviceStatusReportRequest device_status; + em::SessionStatusReportRequest session_status; + client_->UploadDeviceStatus(&device_status, &session_status, callback); + + // Now initiate a policy fetch - this should not cancel the upload job. + ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone); + EXPECT_CALL(observer_, OnPolicyFetched(_)); + client_->FetchPolicy(); + CheckPolicyResponse(); + + upload_status_job->SendResponse(DM_STATUS_SUCCESS, upload_status_response_); + EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); +} + +TEST_F(CloudPolicyClientTest, MultipleActiveRequests) { + Register(); + + // Set up pending upload status job. + MockDeviceManagementJob* upload_status_job = nullptr; + EXPECT_CALL(service_, + CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS, + request_context_)) + .WillOnce(service_.CreateAsyncJob(&upload_status_job)); + EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _)); + CloudPolicyClient::StatusCallback callback = base::Bind( + &MockUploadObserver::OnUploadComplete, + base::Unretained(&upload_observer_)); + em::DeviceStatusReportRequest device_status; + em::SessionStatusReportRequest session_status; + client_->UploadDeviceStatus(&device_status, &session_status, callback); + + // Set up pending upload certificate job. + MockDeviceManagementJob* upload_certificate_job = nullptr; + EXPECT_CALL(service_, + CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE, + request_context_)) + .WillOnce(service_.CreateAsyncJob(&upload_certificate_job)); + EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _)); + + // Expect two calls on our upload observer, one for the status upload and + // one for the certificate upload. + CloudPolicyClient::StatusCallback callback2 = base::Bind( + &MockUploadObserver::OnUploadComplete, + base::Unretained(&upload_observer_)); + client_->UploadCertificate(kDeviceCertificate, callback2); + EXPECT_EQ(2, client_->GetActiveRequestCountForTest()); + + // Now satisfy both active jobs. + EXPECT_CALL(upload_observer_, OnUploadComplete(true)).Times(2); + upload_status_job->SendResponse(DM_STATUS_SUCCESS, upload_status_response_); + EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); + upload_certificate_job->SendResponse(DM_STATUS_SUCCESS, + upload_certificate_response_); + EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); + + EXPECT_EQ(0, client_->GetActiveRequestCountForTest()); +} + TEST_F(CloudPolicyClientTest, UploadStatusFailure) { Register(); @@ -623,4 +694,27 @@ EXPECT_EQ(DM_STATUS_REQUEST_FAILED, client_->status()); } +TEST_F(CloudPolicyClientTest, RequestCancelOnUnregister) { + Register(); + + // Set up pending upload status job. + MockDeviceManagementJob* upload_status_job = nullptr; + EXPECT_CALL(service_, + CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS, + request_context_)) + .WillOnce(service_.CreateAsyncJob(&upload_status_job)); + EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _)); + CloudPolicyClient::StatusCallback callback = base::Bind( + &MockUploadObserver::OnUploadComplete, + base::Unretained(&upload_observer_)); + em::DeviceStatusReportRequest device_status; + em::SessionStatusReportRequest session_status; + client_->UploadDeviceStatus(&device_status, &session_status, callback); + EXPECT_EQ(1, client_->GetActiveRequestCountForTest()); + EXPECT_CALL(observer_, OnRegistrationStateChanged(_)); + ExpectUnregistration(kDMToken); + client_->Unregister(); + EXPECT_EQ(0, client_->GetActiveRequestCountForTest()); +} + } // namespace policy
diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc index 2989a36..bfa675c 100644 --- a/components/policy/core/common/policy_loader_win.cc +++ b/components/policy/core/common/policy_loader_win.cc
@@ -683,7 +683,8 @@ void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("PolicyLoaderWin_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 PolicyLoaderWin::OnObjectSignaled")); DCHECK(object == user_policy_changed_event_.handle() || object == machine_policy_changed_event_.handle())
diff --git a/components/policy/core/common/policy_provider_android.h b/components/policy/core/common/policy_provider_android.h index c09f95f..76bc515b 100644 --- a/components/policy/core/common/policy_provider_android.h +++ b/components/policy/core/common/policy_provider_android.h
@@ -18,7 +18,7 @@ class POLICY_EXPORT PolicyProviderAndroid : public ConfigurationPolicyProvider { public: PolicyProviderAndroid(); - virtual ~PolicyProviderAndroid(); + ~PolicyProviderAndroid() override; // Call this method to tell the policy system whether it should wait for // policies to be loaded by this provider. If this method is called, @@ -33,9 +33,9 @@ void SetPolicies(scoped_ptr<PolicyBundle> policy); // ConfigurationPolicyProvider: - virtual void Shutdown() override; - virtual bool IsInitializationComplete(PolicyDomain domain) const override; - virtual void RefreshPolicies() override; + void Shutdown() override; + bool IsInitializationComplete(PolicyDomain domain) const override; + void RefreshPolicies() override; private: PolicyProviderAndroidDelegate* delegate_;
diff --git a/components/policy/core/common/policy_provider_android_unittest.cc b/components/policy/core/common/policy_provider_android_unittest.cc index bdfe7650..12844f3 100644 --- a/components/policy/core/common/policy_provider_android_unittest.cc +++ b/components/policy/core/common/policy_provider_android_unittest.cc
@@ -60,10 +60,10 @@ class PolicyProviderAndroidTest : public ::testing::Test { protected: PolicyProviderAndroidTest(); - virtual ~PolicyProviderAndroidTest(); + ~PolicyProviderAndroidTest() override; - virtual void SetUp() override; - virtual void TearDown() override; + void SetUp() override; + void TearDown() override; private: DISALLOW_COPY_AND_ASSIGN(PolicyProviderAndroidTest);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index ed4a6b0..93db565 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -7028,7 +7028,7 @@ 'example_value': 'ssl3', 'id': 279, 'caption': '''Minimum SSL version enabled''', - 'desc': '''Warning: SSLv3 support will be entirely removed from Chrome after version 43 (around July 2015) after which the setting "ssl3" will be ignored and the default of "tls1" used instead. + 'desc': '''Warning: SSLv3 support will be entirely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> after version 43 (around July 2015) and this policy will be removed at the same time. If this policy is not configured then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> uses a default minimum version which is SSLv3 in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 39 and TLS 1.0 in later versions. @@ -7083,7 +7083,7 @@ 'example_value': 'tls1', 'id': 280, 'caption': '''Minimum SSL version to fallback to''', - 'desc': '''Warning: SSLv3 support will be entirely removed from Chrome after version 43 (around July 2015) after which the setting "ssl3" will be ignored and the default of "tls1" used instead. + 'desc': '''Warning: SSLv3 support will be entirely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> after version 43 (around July 2015) and this policy will be removed at the same time. When an SSL/TLS handshake fails, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will retry the connection with a lesser version of SSL/TLS in order to work around bugs in HTTPS servers. This setting configures the version at which this fallback process will stop. If a server performs version negotiation correctly (i.e. without breaking the connection) then this setting doesn't apply. Regardless, the resulting connection must still comply with SSLVersionMin.
diff --git a/components/printing.gypi b/components/printing.gypi index bdc9da4b..c2e3d3e 100644 --- a/components/printing.gypi +++ b/components/printing.gypi
@@ -45,6 +45,22 @@ ], # TODO(dgn): C4267: http://crbug.com/167187 size_t -> int 'msvs_disabled_warnings': [ 4267 ], + },{ + # GN: //components/printing/test:printing_test_support + 'target_name': 'printing_test_support', + 'type': 'static_library', + 'dependencies': [ + '<(DEPTH)/testing/gtest.gyp:gtest', + 'printing_renderer', + ], + 'sources': [ + 'printing/test/mock_printer.h', + 'printing/test/mock_printer.cc', + 'printing/test/print_mock_render_thread.h', + 'printing/test/print_mock_render_thread.cc', + 'printing/test/print_test_content_renderer_client.cc', + 'printing/test/print_test_content_renderer_client.h', + ], }, ], }
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc index 4c1c058..d6bf626 100644 --- a/components/printing/renderer/print_web_view_helper.cc +++ b/components/printing/renderer/print_web_view_helper.cc
@@ -144,14 +144,14 @@ return page_css_params; } - page_css_params.content_size = gfx::Size( - ConvertUnit(new_content_width, kPixelsPerInch, dpi), - ConvertUnit(new_content_height, kPixelsPerInch, dpi)); + page_css_params.content_size = + gfx::Size(ConvertUnit(new_content_width, kPixelsPerInch, dpi), + ConvertUnit(new_content_height, kPixelsPerInch, dpi)); if (original_page_size_in_pixels != page_size_in_pixels) { - page_css_params.page_size = gfx::Size( - ConvertUnit(page_size_in_pixels.width, kPixelsPerInch, dpi), - ConvertUnit(page_size_in_pixels.height, kPixelsPerInch, dpi)); + page_css_params.page_size = + gfx::Size(ConvertUnit(page_size_in_pixels.width, kPixelsPerInch, dpi), + ConvertUnit(page_size_in_pixels.height, kPixelsPerInch, dpi)); } else { // Printing frame doesn't have any page size css. Pixels to dpi conversion // causes rounding off errors. Therefore use the default page size values @@ -197,8 +197,8 @@ params_to_fit->margin_left = static_cast<int>( (default_page_size_width - css_page_size_width * scale_factor) / 2 + (params_to_fit->margin_left * scale_factor)); - params_to_fit->content_size = gfx::Size( - static_cast<int>(content_width), static_cast<int>(content_height)); + params_to_fit->content_size = gfx::Size(static_cast<int>(content_width), + static_cast<int>(content_height)); params_to_fit->page_size = page_params.page_size; return scale_factor; } @@ -210,10 +210,10 @@ int content_width = params.content_size.width(); int content_height = params.content_size.height(); - int margin_bottom = params.page_size.height() - - content_height - params.margin_top; - int margin_right = params.page_size.width() - - content_width - params.margin_left; + int margin_bottom = + params.page_size.height() - content_height - params.margin_top; + int margin_right = + params.page_size.width() - content_width - params.margin_left; page_layout_in_points->content_width = ConvertUnit(content_width, dpi, kPointsPerInch); @@ -253,37 +253,30 @@ webkit_print_params->printerDPI = dpi; webkit_print_params->printScalingOption = print_params.print_scaling_option; - webkit_print_params->printContentArea.width = - ConvertUnit(print_params.content_size.width(), dpi, - print_params.desired_dpi); - webkit_print_params->printContentArea.height = - ConvertUnit(print_params.content_size.height(), dpi, - print_params.desired_dpi); + webkit_print_params->printContentArea.width = ConvertUnit( + print_params.content_size.width(), dpi, print_params.desired_dpi); + webkit_print_params->printContentArea.height = ConvertUnit( + print_params.content_size.height(), dpi, print_params.desired_dpi); - webkit_print_params->printableArea.x = - ConvertUnit(print_params.printable_area.x(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.y = - ConvertUnit(print_params.printable_area.y(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.width = - ConvertUnit(print_params.printable_area.width(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.height = - ConvertUnit(print_params.printable_area.height(), - dpi, print_params.desired_dpi); + webkit_print_params->printableArea.x = ConvertUnit( + print_params.printable_area.x(), dpi, print_params.desired_dpi); + webkit_print_params->printableArea.y = ConvertUnit( + print_params.printable_area.y(), dpi, print_params.desired_dpi); + webkit_print_params->printableArea.width = ConvertUnit( + print_params.printable_area.width(), dpi, print_params.desired_dpi); + webkit_print_params->printableArea.height = ConvertUnit( + print_params.printable_area.height(), dpi, print_params.desired_dpi); - webkit_print_params->paperSize.width = - ConvertUnit(print_params.page_size.width(), dpi, - print_params.desired_dpi); - webkit_print_params->paperSize.height = - ConvertUnit(print_params.page_size.height(), dpi, - print_params.desired_dpi); + webkit_print_params->paperSize.width = ConvertUnit( + print_params.page_size.width(), dpi, print_params.desired_dpi); + webkit_print_params->paperSize.height = ConvertUnit( + print_params.page_size.height(), dpi, print_params.desired_dpi); } blink::WebPlugin* GetPlugin(const blink::WebFrame* frame) { - return frame->document().isPluginDocument() ? - frame->document().to<blink::WebPluginDocument>().plugin() : NULL; + return frame->document().isPluginDocument() + ? frame->document().to<blink::WebPluginDocument>().plugin() + : NULL; } bool PrintingNodeOrPdfFrame(const blink::WebFrame* frame, @@ -366,8 +359,8 @@ bool ignore_css_margins, bool fit_to_page, double* scale_factor) { - PrintMsg_Print_Params css_params = GetCssPrintParams(frame, page_index, - page_params); + PrintMsg_Print_Params css_params = + GetCssPrintParams(frame, page_index, page_params); PrintMsg_Print_Params params = page_params; EnsureOrientationMatches(css_params, ¶ms); @@ -384,14 +377,15 @@ // Since we are ignoring the margins, the css page size is no longer // valid. int default_margin_right = params.page_size.width() - - params.content_size.width() - params.margin_left; + params.content_size.width() - params.margin_left; int default_margin_bottom = params.page_size.height() - - params.content_size.height() - params.margin_top; - result_params.content_size = gfx::Size( - result_params.page_size.width() - result_params.margin_left - - default_margin_right, - result_params.page_size.height() - result_params.margin_top - - default_margin_bottom); + params.content_size.height() - + params.margin_top; + result_params.content_size = + gfx::Size(result_params.page_size.width() - result_params.margin_left - + default_margin_right, + result_params.page_size.height() - result_params.margin_top - + default_margin_bottom); } if (fit_to_page) { @@ -429,7 +423,7 @@ if (view_ == NULL || frame_ == NULL) return NULL; for (blink::WebFrame* frame = view_->mainFrame(); frame != NULL; - frame = frame->traverseNext(false)) { + frame = frame->traverseNext(false)) { if (frame == frame_) return frame_; } @@ -531,17 +525,11 @@ // Prepares frame for printing. void StartPrinting(); - blink::WebLocalFrame* frame() { - return frame_.GetFrame(); - } + blink::WebLocalFrame* frame() { return frame_.GetFrame(); } - const blink::WebNode& node() const { - return node_to_print_; - } + const blink::WebNode& node() const { return node_to_print_; } - int GetExpectedPageCount() const { - return expected_pages_count_; - } + int GetExpectedPageCount() const { return expected_pages_count_; } void FinishPrinting(); @@ -607,12 +595,11 @@ !PrintingNodeOrPdfFrame(frame, node_to_print_)) { bool fit_to_page = ignore_css_margins && print_params.print_scaling_option == - blink::WebPrintScalingOptionFitToPrintableArea; + blink::WebPrintScalingOptionFitToPrintableArea; ComputeWebKitPrintParamsInDesiredDpi(params, &web_print_params_); frame->printBegin(web_print_params_, node_to_print_); - print_params = CalculatePrintParamsForCss(frame, 0, print_params, - ignore_css_margins, fit_to_page, - NULL); + print_params = CalculatePrintParamsForCss( + frame, 0, print_params, ignore_css_margins, fit_to_page, NULL); frame->printEnd(); } ComputeWebKitPrintParamsInDesiredDpi(print_params, &web_print_params_); @@ -644,7 +631,6 @@ web_view->resize(print_layout_size); } - void PrepareFrameAndViewForPrint::StartPrinting() { ResizeForPrinting(); blink::WebView* web_view = frame_.view(); @@ -701,9 +687,8 @@ // Don't call callback here, because it can delete |this| and WebView that is // called didStopLoading. base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PrepareFrameAndViewForPrint::CallOnReady, - weak_ptr_factory_.GetWeakPtr())); + FROM_HERE, base::Bind(&PrepareFrameAndViewForPrint::CallOnReady, + weak_ptr_factory_.GetWeakPtr())); } blink::WebFrame* PrepareFrameAndViewForPrint::createChildFrame( @@ -764,9 +749,8 @@ return true; } -PrintWebViewHelper::PrintWebViewHelper( - content::RenderView* render_view, - scoped_ptr<Delegate> delegate) +PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view, + scoped_ptr<Delegate> delegate) : content::RenderViewObserver(render_view), content::RenderViewObserverTracker<PrintWebViewHelper>(render_view), reset_prep_frame_view_(false), @@ -784,15 +768,16 @@ DisablePreview(); } -PrintWebViewHelper::~PrintWebViewHelper() {} +PrintWebViewHelper::~PrintWebViewHelper() { +} // static void PrintWebViewHelper::DisablePreview() { g_is_preview_enabled_ = false; } -bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed( - blink::WebFrame* frame, bool user_initiated) { +bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed(blink::WebFrame* frame, + bool user_initiated) { if (!delegate_->IsScriptedPrintEnabled()) return false; @@ -885,7 +870,7 @@ blink::WebLocalFrame* plugin_frame = pdf_element.document().frame(); blink::WebElement plugin_element = pdf_element; if (delegate_->IsOutOfProcessPdfEnabled() && - pdf_element.hasHTMLTagName("iframe")) { + pdf_element.hasHTMLTagName("iframe")) { plugin_frame = blink::WebLocalFrame::fromFrameOwnerElement(pdf_element); plugin_element = delegate_->GetPdfElement(plugin_frame); if (plugin_element.isNull()) { @@ -966,11 +951,9 @@ gfx::Size* page_size, gfx::Rect* content_area) { *page_size = gfx::Size( - page_layout_in_points.content_width + - page_layout_in_points.margin_right + + page_layout_in_points.content_width + page_layout_in_points.margin_right + page_layout_in_points.margin_left, - page_layout_in_points.content_height + - page_layout_in_points.margin_top + + page_layout_in_points.content_height + page_layout_in_points.margin_top + page_layout_in_points.margin_bottom); *content_area = gfx::Rect(page_layout_in_points.margin_left, page_layout_in_points.margin_top, @@ -1009,9 +992,9 @@ print_preview_context_.source_node(), settings)) { if (print_preview_context_.last_error() != PREVIEW_ERROR_BAD_SETTING) { Send(new PrintHostMsg_PrintPreviewInvalidPrinterSettings( - routing_id(), - print_pages_params_ ? - print_pages_params_->params.document_cookie : 0)); + routing_id(), print_pages_params_ + ? print_pages_params_->params.document_cookie + : 0)); notify_browser_of_print_failure_ = false; // Already sent. } DidFinishPrinting(FAIL_PREVIEW); @@ -1033,8 +1016,7 @@ print_pages_params_->params.supports_alpha_blend = true; bool generate_draft_pages = false; - if (!settings.GetBoolean(kSettingGenerateDraftData, - &generate_draft_pages)) { + if (!settings.GetBoolean(kSettingGenerateDraftData, &generate_draft_pages)) { NOTREACHED(); } print_preview_context_.set_generate_draft_pages(generate_draft_pages); @@ -1058,11 +1040,9 @@ } const PrintMsg_Print_Params& print_params = print_pages_params_->params; - prep_frame_view_.reset( - new PrepareFrameAndViewForPrint(print_params, - print_preview_context_.source_frame(), - print_preview_context_.source_node(), - ignore_css_margins_)); + prep_frame_view_.reset(new PrepareFrameAndViewForPrint( + print_params, print_preview_context_.source_frame(), + print_preview_context_.source_node(), ignore_css_margins_)); prep_frame_view_->CopySelectionIfNeeded( render_view()->GetWebkitPreferences(), base::Bind(&PrintWebViewHelper::OnFramePreparedForPreviewDocument, @@ -1097,9 +1077,9 @@ print_params, ignore_css_margins_, NULL, &default_page_layout); - bool has_page_size_style = PrintingFrameHasPageSizeStyle( - print_preview_context_.prepared_frame(), - print_preview_context_.total_page_count()); + bool has_page_size_style = + PrintingFrameHasPageSizeStyle(print_preview_context_.prepared_frame(), + print_preview_context_.total_page_count()); int dpi = GetDPI(&print_params); gfx::Rect printable_area_in_points( @@ -1208,9 +1188,9 @@ return; } print_preview_context_.InitWithFrame(frame); - RequestPrintPreview(selection_only ? - PRINT_PREVIEW_USER_INITIATED_SELECTION : - PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME); + RequestPrintPreview(selection_only + ? PRINT_PREVIEW_USER_INITIATED_SELECTION + : PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME); } bool PrintWebViewHelper::IsPrintingEnabled() { @@ -1271,8 +1251,7 @@ // Ask the browser to show UI to retrieve the final print settings. if (delegate_->IsAskPrintSettingsEnabled() && - !GetPrintSettingsFromUser(frame_ref.GetFrame(), node, - expected_page_count, + !GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count, is_scripted)) { DidFinishPrinting(OK); // Release resources and fail silently. return; @@ -1303,8 +1282,8 @@ break; case FAIL_PREVIEW: - int cookie = print_pages_params_ ? - print_pages_params_->params.document_cookie : 0; + int cookie = + print_pages_params_ ? print_pages_params_->params.document_cookie : 0; if (notify_browser_of_print_failure_) { LOG(ERROR) << "CreatePreviewDocument failed"; Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); @@ -1357,7 +1336,6 @@ #endif // !defined(OS_CHROMEOS) } - if (!PrintPagesNative(prep_frame_view_->frame(), page_count)) { LOG(ERROR) << "Printing failed."; return DidFinishPrinting(FAIL_PRINT); @@ -1425,8 +1403,7 @@ ignore_css_margins_ = false; settings.pages.clear(); - settings.params.print_scaling_option = - blink::WebPrintScalingOptionSourceSize; + settings.params.print_scaling_option = blink::WebPrintScalingOptionSourceSize; if (fit_to_paper_size) { settings.params.print_scaling_option = blink::WebPrintScalingOptionFitToPrintableArea; @@ -1500,12 +1477,12 @@ // Send the cookie so that UpdatePrintSettings can reuse PrinterQuery when // possible. - int cookie = print_pages_params_ ? - print_pages_params_->params.document_cookie : 0; + int cookie = + print_pages_params_ ? print_pages_params_->params.document_cookie : 0; PrintMsg_PrintPages_Params settings; bool canceled = false; - Send(new PrintHostMsg_UpdatePrintSettings( - routing_id(), cookie, *job_settings, &settings, &canceled)); + Send(new PrintHostMsg_UpdatePrintSettings(routing_id(), cookie, *job_settings, + &settings, &canceled)); if (canceled) { notify_browser_of_print_failure_ = false; return false; @@ -1604,8 +1581,9 @@ base::SharedMemoryHandle* shared_mem_handle) { uint32 buf_size = metafile->GetDataSize(); scoped_ptr<base::SharedMemory> shared_buf( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); + content::RenderThread::Get() + ->HostAllocateSharedMemoryBuffer(buf_size) + .release()); if (shared_buf) { if (shared_buf->Map(buf_size)) { @@ -1621,8 +1599,8 @@ void PrintWebViewHelper::ShowScriptedPrintPreview() { if (is_scripted_preview_delayed_) { is_scripted_preview_delayed_ = false; - Send(new PrintHostMsg_ShowScriptedPrintPreview(routing_id(), - print_preview_context_.IsModifiable())); + Send(new PrintHostMsg_ShowScriptedPrintPreview( + routing_id(), print_preview_context_.IsModifiable())); } } @@ -1649,9 +1627,8 @@ base::Unretained(this)); } else { base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview, - weak_ptr_factory_.GetWeakPtr())); + FROM_HERE, base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview, + weak_ptr_factory_.GetWeakPtr())); } IPC::SyncMessage* msg = new PrintHostMsg_SetupScriptedPrintPreview(routing_id()); @@ -1667,8 +1644,7 @@ if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { on_stop_loading_closure_ = base::Bind(&PrintWebViewHelper::RequestPrintPreview, - base::Unretained(this), - type); + base::Unretained(this), type); return; } @@ -1684,8 +1660,7 @@ if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { on_stop_loading_closure_ = base::Bind(&PrintWebViewHelper::RequestPrintPreview, - base::Unretained(this), - type); + base::Unretained(this), type); return; } @@ -1737,7 +1712,7 @@ uint32 buf_size = metafile->GetDataSize(); DCHECK_GT(buf_size, 0u); if (!CopyMetafileDataToSharedMem( - metafile, &(preview_page_params.metafile_data_handle))) { + metafile, &(preview_page_params.metafile_data_handle))) { LOG(ERROR) << "CopyMetafileDataToSharedMem failed"; print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED); return false; @@ -1815,9 +1790,9 @@ pages_to_render_ = pages; // Sort and make unique. std::sort(pages_to_render_.begin(), pages_to_render_.end()); - pages_to_render_.resize(std::unique(pages_to_render_.begin(), - pages_to_render_.end()) - - pages_to_render_.begin()); + pages_to_render_.resize( + std::unique(pages_to_render_.begin(), pages_to_render_.end()) - + pages_to_render_.begin()); // Remove invalid pages. pages_to_render_.resize(std::lower_bound(pages_to_render_.begin(), pages_to_render_.end(), @@ -1873,8 +1848,8 @@ UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime", document_render_time_); - base::TimeDelta total_time = (base::TimeTicks::Now() - begin_time) + - document_render_time_; + base::TimeDelta total_time = + (base::TimeTicks::Now() - begin_time) + document_render_time_; UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime", total_time); UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage", @@ -1924,7 +1899,7 @@ return current_page_index_ == print_ready_metafile_page_count_; } -bool PrintWebViewHelper::PrintPreviewContext::IsFinalPageRendered() const { +bool PrintWebViewHelper::PrintPreviewContext::IsFinalPageRendered() const { DCHECK(IsRendering()); return static_cast<size_t>(current_page_index_) == pages_to_render_.size(); }
diff --git a/components/printing/renderer/print_web_view_helper.h b/components/printing/renderer/print_web_view_helper.h index 885f80a..6786d65 100644 --- a/components/printing/renderer/print_web_view_helper.h +++ b/components/printing/renderer/print_web_view_helper.h
@@ -66,7 +66,6 @@ : public content::RenderViewObserver, public content::RenderViewObserverTracker<PrintWebViewHelper> { public: - class Delegate { public: virtual ~Delegate() {}
diff --git a/components/printing/renderer/print_web_view_helper_linux.cc b/components/printing/renderer/print_web_view_helper_linux.cc index 1ebc2ca..79b82e9c 100644 --- a/components/printing/renderer/print_web_view_helper_linux.cc +++ b/components/printing/renderer/print_web_view_helper_linux.cc
@@ -12,7 +12,6 @@ #include "printing/page_size_margins.h" #include "printing/pdf_metafile_skia.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) @@ -118,8 +117,9 @@ { scoped_ptr<base::SharedMemory> shared_mem( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); + content::RenderThread::Get() + ->HostAllocateSharedMemoryBuffer(buf_size) + .release()); if (!shared_mem.get()) { NOTREACHED() << "AllocateSharedMemoryBuffer failed"; return false; @@ -161,7 +161,7 @@ gfx::Rect canvas_area = params.params.display_header_footer ? gfx::Rect(page_size) : content_area; - skia::VectorCanvas* canvas = + skia::PlatformCanvas* canvas = metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor); if (!canvas) return;
diff --git a/components/printing/renderer/print_web_view_helper_mac.mm b/components/printing/renderer/print_web_view_helper_mac.mm index ba1c946..7aa503c 100644 --- a/components/printing/renderer/print_web_view_helper_mac.mm +++ b/components/printing/renderer/print_web_view_helper_mac.mm
@@ -13,7 +13,6 @@ #include "printing/metafile_skia_wrapper.h" #include "printing/page_size_margins.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/platform/WebCanvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -118,7 +117,7 @@ params.display_header_footer ? gfx::Rect(*page_size) : content_area; { - skia::VectorCanvas* canvas = metafile->GetVectorCanvasForNewPage( + skia::PlatformCanvas* canvas = metafile->GetVectorCanvasForNewPage( *page_size, canvas_area, scale_factor); if (!canvas) return;
diff --git a/components/printing/renderer/print_web_view_helper_pdf_win.cc b/components/printing/renderer/print_web_view_helper_pdf_win.cc index 58096399..a121448 100644 --- a/components/printing/renderer/print_web_view_helper_pdf_win.cc +++ b/components/printing/renderer/print_web_view_helper_pdf_win.cc
@@ -14,10 +14,8 @@ #include "printing/pdf_metafile_skia.h" #include "printing/units.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" - namespace printing { using blink::WebFrame; @@ -160,10 +158,10 @@ // Calculate the actual page size and content area in dpi. if (page_size_in_dpi) { *page_size_in_dpi = - gfx::Size(static_cast<int>(ConvertUnitDouble( - page_size.width(), kPointsPerInch, dpi)), - static_cast<int>(ConvertUnitDouble( - page_size.height(), kPointsPerInch, dpi))); + gfx::Size(static_cast<int>(ConvertUnitDouble(page_size.width(), + kPointsPerInch, dpi)), + static_cast<int>(ConvertUnitDouble(page_size.height(), + kPointsPerInch, dpi))); } if (content_area_in_dpi) { @@ -179,7 +177,7 @@ frame->getPrintPageShrink(params.page_number); float scale_factor = css_scale_factor * webkit_page_shrink_factor; - skia::VectorCanvas* canvas = + skia::PlatformCanvas* canvas = metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor); if (!canvas) return;
diff --git a/components/printing/test/BUILD.gn b/components/printing/test/BUILD.gn new file mode 100644 index 0000000..963e5e4a --- /dev/null +++ b/components/printing/test/BUILD.gn
@@ -0,0 +1,21 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +static_library("printing_test_support") { + testonly = true + + sources = [ + "mock_printer.cc", + "mock_printer.h", + "print_mock_render_thread.cc", + "print_mock_render_thread.h", + "print_test_content_renderer_client.cc", + "print_test_content_renderer_client.h", + ] + + deps = [ + "//components/printing/renderer:printing_renderer", + "//testing/gtest", + ] +}
diff --git a/chrome/renderer/printing/mock_printer.cc b/components/printing/test/mock_printer.cc similarity index 85% rename from chrome/renderer/printing/mock_printer.cc rename to components/printing/test/mock_printer.cc index 210534c..a832e9c0 100644 --- a/chrome/renderer/printing/mock_printer.cc +++ b/components/printing/test/mock_printer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/printing/mock_printer.h" +#include "components/printing/test/mock_printer.h" #include "base/basictypes.h" #include "base/files/file_util.h" @@ -45,45 +45,44 @@ MockPrinterPage::MockPrinterPage(const void* source_data, uint32 source_size, const printing::Image& image) - : source_size_(source_size), - image_(image) { + : source_size_(source_size), image_(image) { // Create copies of the source data source_data_.reset(new uint8[source_size]); if (source_data_.get()) memcpy(source_data_.get(), source_data, source_size); } -MockPrinterPage::~MockPrinterPage() {} +MockPrinterPage::~MockPrinterPage() { +} MockPrinter::MockPrinter() - : dpi_(printing::kPointsPerInch), - max_shrink_(2.0), - min_shrink_(1.25), - desired_dpi_(printing::kPointsPerInch), - selection_only_(false), - should_print_backgrounds_(false), - document_cookie_(-1), - current_document_cookie_(0), - printer_status_(PRINTER_READY), - number_pages_(0), - page_number_(0), - is_first_request_(true), - print_to_pdf_(false), - preview_request_id_(0), - print_scaling_option_(blink::WebPrintScalingOptionSourceSize), - display_header_footer_(false), - title_(base::ASCIIToUTF16("title")), - url_(base::ASCIIToUTF16("url")), - use_invalid_settings_(false) { + : dpi_(printing::kPointsPerInch), + max_shrink_(2.0), + min_shrink_(1.25), + desired_dpi_(printing::kPointsPerInch), + selection_only_(false), + should_print_backgrounds_(false), + document_cookie_(-1), + current_document_cookie_(0), + printer_status_(PRINTER_READY), + number_pages_(0), + page_number_(0), + is_first_request_(true), + print_to_pdf_(false), + preview_request_id_(0), + print_scaling_option_(blink::WebPrintScalingOptionSourceSize), + display_header_footer_(false), + title_(base::ASCIIToUTF16("title")), + url_(base::ASCIIToUTF16("url")), + use_invalid_settings_(false) { page_size_.SetSize(static_cast<int>(8.5 * dpi_), static_cast<int>(11.0 * dpi_)); content_size_.SetSize(static_cast<int>((7.5 * dpi_)), - static_cast<int>((10.0 * dpi_))); + static_cast<int>((10.0 * dpi_))); margin_left_ = margin_top_ = static_cast<int>(0.5 * dpi_); - printable_area_.SetRect(static_cast<int>(0.25 * dpi_), - static_cast<int>(0.25 *dpi_), - static_cast<int>(8 * dpi_), - static_cast<int>(10.5 * dpi_)); + printable_area_.SetRect( + static_cast<int>(0.25 * dpi_), static_cast<int>(0.25 * dpi_), + static_cast<int>(8 * dpi_), static_cast<int>(10.5 * dpi_)); } MockPrinter::~MockPrinter() { @@ -220,9 +219,8 @@ #endif metafile.InitFromData(metafile_data.memory(), params.data_size); printing::Image image(metafile); - MockPrinterPage* page_data = new MockPrinterPage(metafile_data.memory(), - params.data_size, - image); + MockPrinterPage* page_data = + new MockPrinterPage(metafile_data.memory(), params.data_size, image); scoped_refptr<MockPrinterPage> page(page_data); pages_.push_back(page); #endif @@ -259,16 +257,16 @@ return pages_[page]->height(); } -bool MockPrinter::GetBitmapChecksum( - unsigned int page, std::string* checksum) const { +bool MockPrinter::GetBitmapChecksum(unsigned int page, + std::string* checksum) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; *checksum = pages_[page]->image().checksum(); return true; } -bool MockPrinter::SaveSource( - unsigned int page, const base::FilePath& filepath) const { +bool MockPrinter::SaveSource(unsigned int page, + const base::FilePath& filepath) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; const uint8* source_data = pages_[page]->source_data(); @@ -278,8 +276,8 @@ return true; } -bool MockPrinter::SaveBitmap( - unsigned int page, const base::FilePath& filepath) const { +bool MockPrinter::SaveBitmap(unsigned int page, + const base::FilePath& filepath) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false;
diff --git a/chrome/renderer/printing/mock_printer.h b/components/printing/test/mock_printer.h similarity index 94% rename from chrome/renderer/printing/mock_printer.h rename to components/printing/test/mock_printer.h index ebdcb28..9e828a7 100644 --- a/chrome/renderer/printing/mock_printer.h +++ b/components/printing/test/mock_printer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_PRINTING_MOCK_PRINTER_H_ -#define CHROME_RENDERER_PRINTING_MOCK_PRINTER_H_ +#ifndef COMPONENTS_PRINTING_TEST_MOCK_PRINTER_H_ +#define COMPONENTS_PRINTING_TEST_MOCK_PRINTER_H_ #include <string> #include <vector> @@ -80,7 +80,8 @@ int expected_pages_count, bool has_selection, PrintMsg_PrintPages_Params* settings); - void UpdateSettings(int cookie, PrintMsg_PrintPages_Params* params, + void UpdateSettings(int cookie, + PrintMsg_PrintPages_Params* params, const std::vector<int>& page_range_array, int margins_type); void SetPrintedPagesCount(int cookie, int number_pages); @@ -158,9 +159,9 @@ // Used for generating invalid settings. bool use_invalid_settings_; - std::vector<scoped_refptr<MockPrinterPage> > pages_; + std::vector<scoped_refptr<MockPrinterPage>> pages_; DISALLOW_COPY_AND_ASSIGN(MockPrinter); }; -#endif // CHROME_RENDERER_PRINTING_MOCK_PRINTER_H_ +#endif // COMPONENTS_PRINTING_TEST_MOCK_PRINTER_H_
diff --git a/components/printing/test/print_mock_render_thread.cc b/components/printing/test/print_mock_render_thread.cc new file mode 100644 index 0000000..4cf3b74 --- /dev/null +++ b/components/printing/test/print_mock_render_thread.cc
@@ -0,0 +1,217 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/printing/test/print_mock_render_thread.h" + +#include <vector> + +#include "base/values.h" +#include "components/printing/test/mock_printer.h" +#include "ipc/ipc_sync_message.h" +#include "printing/page_range.h" +#include "printing/print_job_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_CHROMEOS) +#include <fcntl.h> + +#include "base/files/file_util.h" +#endif + +#if defined(ENABLE_PRINTING) +#include "components/printing/common/print_messages.h" +#endif + +PrintMockRenderThread::PrintMockRenderThread() +#if defined(ENABLE_PRINTING) + : printer_(new MockPrinter), + print_dialog_user_response_(true), + print_preview_cancel_page_number_(-1), + print_preview_pages_remaining_(0) +#endif +{ +} + +PrintMockRenderThread::~PrintMockRenderThread() { +} + +scoped_refptr<base::MessageLoopProxy> +PrintMockRenderThread::GetIOMessageLoopProxy() { + return io_message_loop_proxy_; +} + +void PrintMockRenderThread::set_io_message_loop_proxy( + const scoped_refptr<base::MessageLoopProxy>& proxy) { + io_message_loop_proxy_ = proxy; +} + +bool PrintMockRenderThread::OnMessageReceived(const IPC::Message& msg) { + if (content::MockRenderThread::OnMessageReceived(msg)) + return true; + + // Some messages we do special handling. + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PrintMockRenderThread, msg) +#if defined(ENABLE_PRINTING) + IPC_MESSAGE_HANDLER(PrintHostMsg_GetDefaultPrintSettings, + OnGetDefaultPrintSettings) + IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint) + IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, + OnDidGetPrintedPagesCount) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, + OnDidGetPreviewPageCount) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection) +#endif +#if defined(OS_CHROMEOS) + IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting, + OnAllocateTempFileForPrinting) + IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten, + OnTempFileForPrintingWritten) +#endif // defined(OS_CHROMEOS) +#endif // defined(ENABLE_PRINTING) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +#if defined(ENABLE_PRINTING) +#if defined(OS_CHROMEOS) +void PrintMockRenderThread::OnAllocateTempFileForPrinting( + int render_view_id, + base::FileDescriptor* renderer_fd, + int* browser_fd) { + renderer_fd->fd = *browser_fd = -1; + renderer_fd->auto_close = false; + + base::FilePath path; + if (base::CreateTemporaryFile(&path)) { + int fd = open(path.value().c_str(), O_WRONLY); + DCHECK_GE(fd, 0); + renderer_fd->fd = *browser_fd = fd; + } +} + +void PrintMockRenderThread::OnTempFileForPrintingWritten(int render_view_id, + int browser_fd) { + close(browser_fd); +} +#endif // defined(OS_CHROMEOS) + +void PrintMockRenderThread::OnGetDefaultPrintSettings( + PrintMsg_Print_Params* params) { + printer_->GetDefaultPrintSettings(params); +} + +void PrintMockRenderThread::OnScriptedPrint( + const PrintHostMsg_ScriptedPrint_Params& params, + PrintMsg_PrintPages_Params* settings) { + if (print_dialog_user_response_) { + printer_->ScriptedPrint(params.cookie, params.expected_pages_count, + params.has_selection, settings); + } +} + +void PrintMockRenderThread::OnDidGetPrintedPagesCount(int cookie, + int number_pages) { + printer_->SetPrintedPagesCount(cookie, number_pages); +} + +void PrintMockRenderThread::OnDidPrintPage( + const PrintHostMsg_DidPrintPage_Params& params) { + printer_->PrintPage(params); +} + +void PrintMockRenderThread::OnDidGetPreviewPageCount( + const PrintHostMsg_DidGetPreviewPageCount_Params& params) { + print_preview_pages_remaining_ = params.page_count; +} + +void PrintMockRenderThread::OnDidPreviewPage( + const PrintHostMsg_DidPreviewPage_Params& params) { + DCHECK_GE(params.page_number, printing::FIRST_PAGE_INDEX); + print_preview_pages_remaining_--; +} + +void PrintMockRenderThread::OnCheckForCancel(int32 preview_ui_id, + int preview_request_id, + bool* cancel) { + *cancel = + (print_preview_pages_remaining_ == print_preview_cancel_page_number_); +} + +void PrintMockRenderThread::OnUpdatePrintSettings( + int document_cookie, + const base::DictionaryValue& job_settings, + PrintMsg_PrintPages_Params* params, + bool* canceled) { + if (canceled) + *canceled = false; + // Check and make sure the required settings are all there. + // We don't actually care about the values. + std::string dummy_string; + int margins_type = 0; + if (!job_settings.GetBoolean(printing::kSettingLandscape, NULL) || + !job_settings.GetBoolean(printing::kSettingCollate, NULL) || + !job_settings.GetInteger(printing::kSettingColor, NULL) || + !job_settings.GetBoolean(printing::kSettingPrintToPDF, NULL) || + !job_settings.GetBoolean(printing::kIsFirstRequest, NULL) || + !job_settings.GetString(printing::kSettingDeviceName, &dummy_string) || + !job_settings.GetInteger(printing::kSettingDuplexMode, NULL) || + !job_settings.GetInteger(printing::kSettingCopies, NULL) || + !job_settings.GetInteger(printing::kPreviewUIID, NULL) || + !job_settings.GetInteger(printing::kPreviewRequestID, NULL) || + !job_settings.GetInteger(printing::kSettingMarginsType, &margins_type)) { + return; + } + + // Just return the default settings. + const base::ListValue* page_range_array; + printing::PageRanges new_ranges; + if (job_settings.GetList(printing::kSettingPageRange, &page_range_array)) { + for (size_t index = 0; index < page_range_array->GetSize(); ++index) { + const base::DictionaryValue* dict; + if (!page_range_array->GetDictionary(index, &dict)) + continue; + printing::PageRange range; + if (!dict->GetInteger(printing::kSettingPageRangeFrom, &range.from) || + !dict->GetInteger(printing::kSettingPageRangeTo, &range.to)) { + continue; + } + // Page numbers are 1-based in the dictionary. + // Page numbers are 0-based for the printing context. + range.from--; + range.to--; + new_ranges.push_back(range); + } + } + std::vector<int> pages(printing::PageRange::GetPages(new_ranges)); + printer_->UpdateSettings(document_cookie, params, pages, margins_type); + + job_settings.GetBoolean(printing::kSettingShouldPrintSelectionOnly, + ¶ms->params.selection_only); + job_settings.GetBoolean(printing::kSettingShouldPrintBackgrounds, + ¶ms->params.should_print_backgrounds); +} + +MockPrinter* PrintMockRenderThread::printer() { + return printer_.get(); +} + +void PrintMockRenderThread::set_print_dialog_user_response(bool response) { + print_dialog_user_response_ = response; +} + +void PrintMockRenderThread::set_print_preview_cancel_page_number(int page) { + print_preview_cancel_page_number_ = page; +} + +int PrintMockRenderThread::print_preview_pages_remaining() const { + return print_preview_pages_remaining_; +} +#endif // defined(ENABLE_PRINTING)
diff --git a/components/printing/test/print_mock_render_thread.h b/components/printing/test/print_mock_render_thread.h new file mode 100644 index 0000000..961341e --- /dev/null +++ b/components/printing/test/print_mock_render_thread.h
@@ -0,0 +1,109 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PRINTING_TEST_PRINT_MOCK_RENDER_THREAD_H_ +#define COMPONENTS_PRINTING_TEST_PRINT_MOCK_RENDER_THREAD_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "content/public/test/mock_render_thread.h" + +namespace base { +class DictionaryValue; +} + +class MockPrinter; +struct PrintHostMsg_DidGetPreviewPageCount_Params; +struct PrintHostMsg_DidPreviewPage_Params; +struct PrintHostMsg_DidPrintPage_Params; +struct PrintHostMsg_ScriptedPrint_Params; +struct PrintMsg_PrintPages_Params; +struct PrintMsg_Print_Params; + +// Extends content::MockRenderThread to know about printing +class PrintMockRenderThread : public content::MockRenderThread { + public: + PrintMockRenderThread(); + ~PrintMockRenderThread() override; + + // content::RenderThread overrides. + scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() override; + + ////////////////////////////////////////////////////////////////////////// + // The following functions are called by the test itself. + + // Set IO message loop proxy. + void set_io_message_loop_proxy( + const scoped_refptr<base::MessageLoopProxy>& proxy); + +#if defined(ENABLE_PRINTING) + // Returns the pseudo-printer instance. + MockPrinter* printer(); + + // Call with |response| set to true if the user wants to print. + // False if the user decides to cancel. + void set_print_dialog_user_response(bool response); + + // Cancel print preview when print preview has |page| remaining pages. + void set_print_preview_cancel_page_number(int page); + + // Get the number of pages to generate for print preview. + int print_preview_pages_remaining() const; +#endif + + private: + // Overrides base class implementation to add custom handling for print + bool OnMessageReceived(const IPC::Message& msg) override; + +#if defined(ENABLE_PRINTING) +#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + void OnAllocateTempFileForPrinting(int render_view_id, + base::FileDescriptor* renderer_fd, + int* browser_fd); + void OnTempFileForPrintingWritten(int render_view_id, int browser_fd); +#endif + + // PrintWebViewHelper expects default print settings. + void OnGetDefaultPrintSettings(PrintMsg_Print_Params* setting); + + // PrintWebViewHelper expects final print settings from the user. + void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params, + PrintMsg_PrintPages_Params* settings); + + void OnDidGetPrintedPagesCount(int cookie, int number_pages); + void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params); + void OnDidGetPreviewPageCount( + const PrintHostMsg_DidGetPreviewPageCount_Params& params); + void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params); + void OnCheckForCancel(int32 preview_ui_id, + int preview_request_id, + bool* cancel); + + // For print preview, PrintWebViewHelper will update settings. + void OnUpdatePrintSettings(int document_cookie, + const base::DictionaryValue& job_settings, + PrintMsg_PrintPages_Params* params, + bool* canceled); + + // A mock printer device used for printing tests. + scoped_ptr<MockPrinter> printer_; + + // True to simulate user clicking print. False to cancel. + bool print_dialog_user_response_; + + // Simulates cancelling print preview if |print_preview_pages_remaining_| + // equals this. + int print_preview_cancel_page_number_; + + // Number of pages to generate for print preview. + int print_preview_pages_remaining_; +#endif + + scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; + + DISALLOW_COPY_AND_ASSIGN(PrintMockRenderThread); +}; + +#endif // COMPONENTS_PRINTING_TEST_PRINT_MOCK_RENDER_THREAD_H_
diff --git a/components/printing/test/print_test_content_renderer_client.cc b/components/printing/test/print_test_content_renderer_client.cc new file mode 100644 index 0000000..0e8f427 --- /dev/null +++ b/components/printing/test/print_test_content_renderer_client.cc
@@ -0,0 +1,48 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/printing/test/print_test_content_renderer_client.h" + +#include "components/printing/renderer/print_web_view_helper.h" +#include "third_party/WebKit/public/web/WebElement.h" + +namespace printing { + +namespace { +class PrintWebViewHelperDelegate : public PrintWebViewHelper::Delegate { + public: + ~PrintWebViewHelperDelegate() override {} + bool CancelPrerender(content::RenderView* render_view, + int routing_id) override { + return false; + } + blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override { + return blink::WebElement(); + } + bool IsOutOfProcessPdfEnabled() override { return false; } + bool IsPrintPreviewEnabled() override { +#if defined(ENABLE_PRINT_PREVIEW) + return true; +#else + return false; +#endif + } + bool OverridePrint(blink::WebLocalFrame* frame) override { return false; } +}; +} + +PrintTestContentRendererClient::PrintTestContentRendererClient() { +} + +PrintTestContentRendererClient::~PrintTestContentRendererClient() { +} + +void PrintTestContentRendererClient::RenderViewCreated( + content::RenderView* render_view) { + new printing::PrintWebViewHelper( + render_view, scoped_ptr<printing::PrintWebViewHelper::Delegate>( + new PrintWebViewHelperDelegate())); +} + +} // namespace printing
diff --git a/components/printing/test/print_test_content_renderer_client.h b/components/printing/test/print_test_content_renderer_client.h new file mode 100644 index 0000000..d186244 --- /dev/null +++ b/components/printing/test/print_test_content_renderer_client.h
@@ -0,0 +1,22 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PRINTING_TEST_PRINT_TEST_CONTENT_RENDERER_CLIENT_H_ +#define COMPONENTS_PRINTING_TEST_PRINT_TEST_CONTENT_RENDERER_CLIENT_H_ + +#include "content/public/renderer/content_renderer_client.h" + +namespace printing { + +class PrintTestContentRendererClient : public content::ContentRendererClient { + public: + PrintTestContentRendererClient(); + ~PrintTestContentRendererClient() override; + + void RenderViewCreated(content::RenderView* render_view) override; +}; + +} // namespace printing + +#endif // COMPONENTS_PRINTING_TEST_PRINT_TEST_CONTENT_RENDERER_CLIENT_H_
diff --git a/chrome/renderer/printing/print_web_view_helper_browsertest.cc b/components/printing/test/print_web_view_helper_browsertest.cc similarity index 85% rename from chrome/renderer/printing/print_web_view_helper_browsertest.cc rename to components/printing/test/print_web_view_helper_browsertest.cc index 1e743cc..bfdc311 100644 --- a/chrome/renderer/printing/print_web_view_helper_browsertest.cc +++ b/components/printing/test/print_web_view_helper_browsertest.cc
@@ -4,12 +4,13 @@ #include "base/command_line.h" #include "base/run_loop.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/renderer/printing/mock_printer.h" -#include "chrome/test/base/chrome_render_view_test.h" #include "components/printing/common/print_messages.h" #include "components/printing/renderer/print_web_view_helper.h" +#include "components/printing/test/mock_printer.h" +#include "components/printing/test/print_mock_render_thread.h" +#include "components/printing/test/print_test_content_renderer_client.h" #include "content/public/renderer/render_view.h" +#include "content/public/test/render_view_test.h" #include "ipc/ipc_listener.h" #include "printing/print_job_constants.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,14 +45,14 @@ // HTML with 3 pages. const char kMultipageHTML[] = - "<html><head><style>" - ".break { page-break-after: always; }" - "</style></head>" - "<body>" - "<div class='break'>page1</div>" - "<div class='break'>page2</div>" - "<div>page3</div>" - "</body></html>"; + "<html><head><style>" + ".break { page-break-after: always; }" + "</style></head>" + "<body>" + "<div class='break'>page1</div>" + "<div class='break'>page2</div>" + "<div>page3</div>" + "</body></html>"; // A simple web page with print page size css. const char kHTMLWithPageSizeCss[] = @@ -125,12 +126,32 @@ } // namespace -class PrintWebViewHelperTestBase : public ChromeRenderViewTest { +class PrintWebViewHelperTestBase : public content::RenderViewTest { public: - PrintWebViewHelperTestBase() {} + PrintWebViewHelperTestBase() : print_render_thread_(NULL) {} ~PrintWebViewHelperTestBase() override {} protected: + void SetUp() override { + print_render_thread_ = new PrintMockRenderThread(); + render_thread_.reset(print_render_thread_); + + content::RenderViewTest::SetUp(); + } + + content::ContentRendererClient* CreateContentRendererClient() override { + return new PrintTestContentRendererClient(); + } + + void TearDown() override { +#if defined(LEAK_SANITIZER) + // Do this before shutting down V8 in RenderViewTest::TearDown(). + // http://crbug.com/328552 + __lsan_do_leak_check(); +#endif + content::RenderViewTest::TearDown(); + } + void PrintWithJavaScript() { ExecuteJavaScript("window.print();"); ProcessPendingMessages(); @@ -161,7 +182,7 @@ void VerifyPreviewPageCount(int count) { const IPC::Message* page_cnt_msg = render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_DidGetPreviewPageCount::ID); + PrintHostMsg_DidGetPreviewPageCount::ID); ASSERT_TRUE(page_cnt_msg); PrintHostMsg_DidGetPreviewPageCount::Param post_page_count_param; PrintHostMsg_DidGetPreviewPageCount::Read(page_cnt_msg, @@ -172,8 +193,9 @@ // Verifies whether the pages printed or not. void VerifyPagesPrinted(bool printed) { #if defined(OS_CHROMEOS) - bool did_print_msg = (render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_TempFileForPrintingWritten::ID) != NULL); + bool did_print_msg = + (render_thread_->sink().GetUniqueMessageMatching( + PrintHostMsg_TempFileForPrintingWritten::ID) != NULL); ASSERT_EQ(printed, did_print_msg); #else const IPC::Message* print_msg = @@ -220,6 +242,9 @@ ProcessPendingMessages(); } + // Naked pointer as ownership is with content::RenderViewTest::render_thread_. + PrintMockRenderThread* print_render_thread_; + DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTestBase); }; @@ -228,7 +253,7 @@ PrintWebViewHelperTest() {} ~PrintWebViewHelperTest() override {} - void SetUp() override { ChromeRenderViewTest::SetUp(); } + void SetUp() override { PrintWebViewHelperTestBase::SetUp(); } protected: DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTest); @@ -240,7 +265,7 @@ // frequently. TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrinting) { // Pretend user will cancel printing. - chrome_render_thread_->set_print_dialog_user_response(false); + print_render_thread_->set_print_dialog_user_response(false); // Try to print with window.print() a few times. PrintWithJavaScript(); PrintWithJavaScript(); @@ -248,13 +273,13 @@ VerifyPagesPrinted(false); // Pretend user will print. (but printing is blocked.) - chrome_render_thread_->set_print_dialog_user_response(true); + print_render_thread_->set_print_dialog_user_response(true); PrintWithJavaScript(); VerifyPagesPrinted(false); // Unblock script initiated printing and verify printing works. PrintWebViewHelper::Get(view_)->scripting_throttler_.Reset(); - chrome_render_thread_->printer()->ResetPrinter(); + print_render_thread_->printer()->ResetPrinter(); PrintWithJavaScript(); VerifyPageCount(1); VerifyPagesPrinted(true); @@ -264,7 +289,7 @@ // initiated. TEST_F(PrintWebViewHelperTest, AllowUserOriginatedPrinting) { // Pretend user will cancel printing. - chrome_render_thread_->set_print_dialog_user_response(false); + print_render_thread_->set_print_dialog_user_response(false); // Try to print with window.print() a few times. PrintWithJavaScript(); PrintWithJavaScript(); @@ -272,12 +297,12 @@ VerifyPagesPrinted(false); // Pretend user will print. (but printing is blocked.) - chrome_render_thread_->set_print_dialog_user_response(true); + print_render_thread_->set_print_dialog_user_response(true); PrintWithJavaScript(); VerifyPagesPrinted(false); // Try again as if user initiated, without resetting the print count. - chrome_render_thread_->printer()->ResetPrinter(); + print_render_thread_->printer()->ResetPrinter(); LoadHTML(kPrintOnUserAction); gfx::Size new_size(200, 100); Resize(new_size, gfx::Rect(), false); @@ -352,7 +377,7 @@ VerifyPagesPrinted(true); // Verify output through MockPrinter. - const MockPrinter* printer(chrome_render_thread_->printer()); + const MockPrinter* printer(print_render_thread_->printer()); ASSERT_EQ(1, printer->GetPrintedPages()); const Image& image1(printer->GetPrintedPage(0)->image()); @@ -380,26 +405,32 @@ #if defined(OS_WIN) || defined(OS_MACOSX) const TestPageData kTestPages[] = { - {"<html>" - "<head>" - "<meta" - " http-equiv=\"Content-Type\"" - " content=\"text/html; charset=utf-8\"/>" - "<title>Test 1</title>" - "</head>" - "<body style=\"background-color: white;\">" - "<p style=\"font-family: arial;\">Hello World!</p>" - "</body>", + { + "<html>" + "<head>" + "<meta" + " http-equiv=\"Content-Type\"" + " content=\"text/html; charset=utf-8\"/>" + "<title>Test 1</title>" + "</head>" + "<body style=\"background-color: white;\">" + "<p style=\"font-family: arial;\">Hello World!</p>" + "</body>", #if defined(OS_MACOSX) - // Mac printing code compensates for the WebKit scale factor while generating - // the metafile, so we expect smaller pages. - 1, 600, 780, + // Mac printing code compensates for the WebKit scale factor while + // generating + // the metafile, so we expect smaller pages. + 1, + 600, + 780, #else - 1, 675, 900, + 1, + 675, + 900, #endif - NULL, - NULL, - }, + NULL, + NULL, + }, }; #endif // defined(OS_WIN) || defined(OS_MACOSX) } // namespace @@ -412,7 +443,7 @@ TEST_F(PrintWebViewHelperTest, PrintLayoutTest) { bool baseline = false; - EXPECT_TRUE(chrome_render_thread_->printer() != NULL); + EXPECT_TRUE(print_render_thread_->printer() != NULL); for (size_t i = 0; i < arraysize(kTestPages); ++i) { // Load an HTML page and print it. LoadHTML(kTestPages[i].page); @@ -425,12 +456,12 @@ // has been already finished. // So, we can start checking the output pages of this printing job. // Retrieve the number of pages actually printed. - size_t pages = chrome_render_thread_->printer()->GetPrintedPages(); + size_t pages = print_render_thread_->printer()->GetPrintedPages(); EXPECT_EQ(kTestPages[i].printed_pages, pages); // Retrieve the width and height of the output page. - int width = chrome_render_thread_->printer()->GetWidth(0); - int height = chrome_render_thread_->printer()->GetHeight(0); + int width = print_render_thread_->printer()->GetWidth(0); + int height = print_render_thread_->printer()->GetHeight(0); // Check with margin for error. This has been failing with a one pixel // offset on our buildbot. @@ -438,13 +469,13 @@ EXPECT_GT(kTestPages[i].width * (100 + kErrorMargin) / 100, width); EXPECT_LT(kTestPages[i].width * (100 - kErrorMargin) / 100, width); EXPECT_GT(kTestPages[i].height * (100 + kErrorMargin) / 100, height); - EXPECT_LT(kTestPages[i].height* (100 - kErrorMargin) / 100, height); + EXPECT_LT(kTestPages[i].height * (100 - kErrorMargin) / 100, height); // Retrieve the checksum of the bitmap data from the pseudo printer and // compare it with the expected result. std::string bitmap_actual; EXPECT_TRUE( - chrome_render_thread_->printer()->GetBitmapChecksum(0, &bitmap_actual)); + print_render_thread_->printer()->GetBitmapChecksum(0, &bitmap_actual)); if (kTestPages[i].checksum) EXPECT_EQ(kTestPages[i].checksum, bitmap_actual); @@ -453,11 +484,11 @@ // create base-line results. base::FilePath source_path; base::CreateTemporaryFile(&source_path); - chrome_render_thread_->printer()->SaveSource(0, source_path); + print_render_thread_->printer()->SaveSource(0, source_path); base::FilePath bitmap_path; base::CreateTemporaryFile(&bitmap_path); - chrome_render_thread_->printer()->SaveBitmap(0, bitmap_path); + print_render_thread_->printer()->SaveBitmap(0, bitmap_path); } } } @@ -474,14 +505,14 @@ void VerifyPrintPreviewCancelled(bool did_cancel) { bool print_preview_cancelled = (render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_PrintPreviewCancelled::ID) != NULL); + PrintHostMsg_PrintPreviewCancelled::ID) != NULL); EXPECT_EQ(did_cancel, print_preview_cancelled); } void VerifyPrintPreviewFailed(bool did_fail) { bool print_preview_failed = (render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_PrintPreviewFailed::ID) != NULL); + PrintHostMsg_PrintPreviewFailed::ID) != NULL); EXPECT_EQ(did_fail, print_preview_failed); } @@ -502,14 +533,14 @@ void VerifyPrintFailed(bool did_fail) { bool print_failed = (render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_PrintingFailed::ID) != NULL); + PrintHostMsg_PrintingFailed::ID) != NULL); EXPECT_EQ(did_fail, print_failed); } void VerifyPrintPreviewInvalidPrinterSettings(bool settings_invalid) { bool print_preview_invalid_printer_settings = (render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_PrintPreviewInvalidPrinterSettings::ID) != NULL); + PrintHostMsg_PrintPreviewInvalidPrinterSettings::ID) != NULL); EXPECT_EQ(settings_invalid, print_preview_invalid_printer_settings); } @@ -535,9 +566,12 @@ ASSERT_EQ(generate_draft_pages, msg_found); } - void VerifyDefaultPageLayout(int content_width, int content_height, - int margin_top, int margin_bottom, - int margin_left, int margin_right, + void VerifyDefaultPageLayout(int content_width, + int content_height, + int margin_top, + int margin_bottom, + int margin_left, + int margin_right, bool page_has_print_css) { const IPC::Message* default_page_layout_msg = render_thread_->sink().GetUniqueMessageMatching( @@ -604,7 +638,7 @@ CreatePrintSettingsDictionary(&dict); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -633,7 +667,7 @@ dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(519, 432, 216, 144, 21, 72, false); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -653,7 +687,7 @@ dict.SetInteger(kSettingMarginsType, NO_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(612, 792, 0, 0, 0, 0, true); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -670,11 +704,10 @@ base::DictionaryValue dict; CreatePrintSettingsDictionary(&dict); dict.SetBoolean(kSettingPrintToPDF, true); - dict.SetInteger(kSettingMarginsType, - PRINTABLE_AREA_MARGINS); + dict.SetInteger(kSettingMarginsType, PRINTABLE_AREA_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page // size. VerifyDefaultPageLayout(252, 252, 18, 18, 18, 18, true); @@ -706,7 +739,7 @@ dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page // size. VerifyDefaultPageLayout(915, 648, 216, 144, 21, 72, true); @@ -726,7 +759,7 @@ dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(216, 216, 288, 288, 198, 198, true); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -756,7 +789,7 @@ dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(571, 652, 69, 71, 20, 21, true); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -774,7 +807,7 @@ dict.SetInteger(kSettingMarginsType, NO_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(792, 612, 0, 0, 0, 0, true); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -792,7 +825,7 @@ dict.SetInteger(kSettingMarginsType, CUSTOM_MARGINS); OnPrintPreview(dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyDefaultPageLayout(748, 568, 21, 23, 21, 23, true); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); @@ -861,7 +894,7 @@ base::DictionaryValue empty_dict; OnPrintPreview(empty_dict); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(true); VerifyPrintPreviewGenerated(false); @@ -873,14 +906,13 @@ LoadHTML(kLongPageHTML); const int kCancelPage = 3; - chrome_render_thread_->set_print_preview_cancel_page_number(kCancelPage); + print_render_thread_->set_print_preview_cancel_page_number(kCancelPage); // Fill in some dummy values. base::DictionaryValue dict; CreatePrintSettingsDictionary(&dict); OnPrintPreview(dict); - EXPECT_EQ(kCancelPage, - chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(kCancelPage, print_render_thread_->print_preview_pages_remaining()); VerifyPrintPreviewCancelled(true); VerifyPrintPreviewFailed(false); VerifyPrintPreviewGenerated(false); @@ -920,7 +952,7 @@ LoadHTML(kPrintPreviewHTML); // Set mock printer to provide invalid settings. - chrome_render_thread_->printer()->UseInvalidSettings(); + print_render_thread_->printer()->UseInvalidSettings(); // Fill in some dummy values. base::DictionaryValue dict; @@ -929,7 +961,7 @@ // We should have received invalid printer settings from |printer_|. VerifyPrintPreviewInvalidPrinterSettings(true); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); // It should receive the invalid printer settings message only. VerifyPrintPreviewFailed(false); @@ -938,18 +970,17 @@ // Tests that when the selected printer has invalid page settings, print preview // receives error message. -TEST_F(PrintWebViewHelperPreviewTest, - OnPrintPreviewUsingInvalidPageSize) { +TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewUsingInvalidPageSize) { LoadHTML(kPrintPreviewHTML); - chrome_render_thread_->printer()->UseInvalidPageSize(); + print_render_thread_->printer()->UseInvalidPageSize(); base::DictionaryValue dict; CreatePrintSettingsDictionary(&dict); OnPrintPreview(dict); VerifyPrintPreviewInvalidPrinterSettings(true); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); // It should receive the invalid printer settings message only. VerifyPrintPreviewFailed(false); @@ -958,18 +989,17 @@ // Tests that when the selected printer has invalid content settings, print // preview receives error message. -TEST_F(PrintWebViewHelperPreviewTest, - OnPrintPreviewUsingInvalidContentSize) { +TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewUsingInvalidContentSize) { LoadHTML(kPrintPreviewHTML); - chrome_render_thread_->printer()->UseInvalidContentSize(); + print_render_thread_->printer()->UseInvalidContentSize(); base::DictionaryValue dict; CreatePrintSettingsDictionary(&dict); OnPrintPreview(dict); VerifyPrintPreviewInvalidPrinterSettings(true); - EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining()); + EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining()); // It should receive the invalid printer settings message only. VerifyPrintPreviewFailed(false); @@ -981,7 +1011,7 @@ LoadHTML(kPrintPreviewHTML); // Set mock printer to provide invalid settings. - chrome_render_thread_->printer()->UseInvalidSettings(); + print_render_thread_->printer()->UseInvalidSettings(); // Fill in some dummy values. base::DictionaryValue dict;
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index bb99ad398..187d91b 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -9,7 +9,7 @@ // definitions. // The following unique IDs are available: -// 11, 12, 13, 14, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 33, 34, 39, 37, +// 7, 11, 12, 13, 14, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 33, 34, 39, 37, // 38, 40, 41, 42, 46, 47, 48, 49, 51, 52, 58, 59, 69, 71, 72, 82, 84, 86, // 88, 89, 91+ // @@ -18,7 +18,7 @@ // NOTES: // - CHANGE THE ABOVE NUMBERS IF YOU ADD A NEW ENGINE; ID conflicts = bad! // - Make sure you update the int_variables below as required. -// - NOTIFY the Chrome Webstore team if you add/delete a search engine or +// - NOTIFY the Chrome Webstore team if you add/delete a search engine or // change domain of an existing one (send email to webstore-eng@google.com). // They need to know the mapping between an engine's "id" and its URLs. @@ -30,7 +30,7 @@ // Increment this if you change the data in ways that mean users with // existing data should get a new version. - "kCurrentDataVersion": 79 + "kCurrentDataVersion": 80 }, // The following engines are included in country lists and are added to the @@ -88,432 +88,13 @@ "name": "Bing", "keyword": "bing.com", "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", + "search_url": "https://www.bing.com/search?q={searchTerms}&PC=U316&FORM=CHROMN", + "suggest_url": "https://www.bing.com/osjson.aspx?query={searchTerms}&language={language}&PC=U316", "new_tab_url": "https://www.bing.com/chrome/newtab", "type": "SEARCH_ENGINE_BING", "id": 3 }, - "bing_ar_XA": { - "name": "Bing (\u0627\u0644\u0639\u0631\u0628\u064a\u0629)", - "keyword": "bing.com_", // bing.com is taken by bing_en_XA. - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=ar-XA&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ar-XA", - "type": "SEARCH_ENGINE_BING", - "id": 7 // Can't be 3 as this has to appear in the Arabian countries' - // lists alongside bing_en_XA. - }, - - "bing_da_DK": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=da-DK&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=da-DK", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_de_AT": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=de-AT&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-AT", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_de_CH": { - "name": "Bing (Deutsch)", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=de-CH&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-CH", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_de_DE": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=de-DE&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-DE", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_AU": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-AU&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-AU", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_CA": { - "name": "Bing (English)", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-CA&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-CA", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_GB": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-GB&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-GB", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_IE": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-IE&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-IE", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_IN": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-IN&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-IN", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_NZ": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-NZ&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-NZ", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_PH": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-PH&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-PH", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_SG": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-SG&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-SG", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_US": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-US&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-US", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_en_XA": { - "name": "Bing (English)", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=en-XA&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-XA", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_es_AR": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=es-AR&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-AR", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_es_CL": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=es-CL&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-CL", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_es_ES": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=es-ES&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-ES", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_es_MX": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=es-MX&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-MX", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_es_XL": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=es-XL&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-XL", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_fi_FI": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=fi-FI&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fi-FI", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_fr_BE": { - "name": "Bing (Fran\u00e7ais)", - "keyword": "bing.com_", // bing.com is taken by bing_nl_BE. - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=fr-BE&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-BE", - "type": "SEARCH_ENGINE_BING", - "id": 7 - }, - - "bing_fr_CA": { - "name": "Bing (Fran\u00e7ais)", - "keyword": "bing.com_", // bing.com is taken by bing_en_CA. - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=fr-CA&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-CA", - "type": "SEARCH_ENGINE_BING", - "id": 7 - }, - - "bing_fr_CH": { - "name": "Bing (Fran\u00e7ais)", - "keyword": "bing.com_", // bing.com is taken by bing_de_CH. - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=fr-CH&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-CH", - "type": "SEARCH_ENGINE_BING", - "id": 7 - }, - - "bing_fr_FR": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=fr-FR&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-FR", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_it_IT": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=it-IT&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=it-IT", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_ja_JP": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=ja-JP&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ja-JP", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_lv_LV": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=lv-LV&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=lv-LV", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_nb_NO": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=nb-NO&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=nb-NO", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_nl_BE": { - "name": "Bing (Nederlandstalige)", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=nl-BE&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=nl-BE", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_pl_PL": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=pl-PL&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pl-PL", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_pt_BR": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=pt-BR&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pt-BR", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_pt_PT": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=pt-PT&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pt-PT", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_ru_RU": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=ru-RU&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ru-RU", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_sv_SE": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=sv-SE&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=sv-SE", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_tr_TR": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=tr-TR&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=tr-TR", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_zh_HK": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=zh-HK&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=zh-HK", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - - "bing_zh_TW": { - "name": "Bing", - "keyword": "bing.com", - "favicon_url": "https://www.bing.com/s/a/bing_p.ico", - "search_url": "https://www.bing.com/search?setmkt=zh-TW&q={searchTerms}", - "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}", - "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=zh-TW", - "type": "SEARCH_ENGINE_BING", - "id": 3 - }, - "daum": { "name": "Daum", "keyword": "daum.net",
diff --git a/components/search_engines/search_terms_data.cc b/components/search_engines/search_terms_data.cc index b1e9ed3..da27139 100644 --- a/components/search_engines/search_terms_data.cc +++ b/components/search_engines/search_terms_data.cc
@@ -26,11 +26,7 @@ GURL::Replacements repl; // Replace any existing path with "/complete/". - // SetPathStr() requires its argument to stay in scope as long as |repl| is, - // so "/complete/" can't be passed to SetPathStr() directly, it needs to be in - // a variable. - const std::string suggest_path("/complete/"); - repl.SetPathStr(suggest_path); + repl.SetPathStr("/complete/"); // Clear the query and ref. repl.ClearQuery();
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index f960485..a9b6c9b6 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -28,6 +28,7 @@ #include "net/base/escape.h" #include "net/base/mime_util.h" #include "net/base/net_util.h" +#include "url/gurl.h" namespace { @@ -1359,7 +1360,7 @@ std::string new_params(old_params, 0, search_terms_position.begin); new_params += base::UTF16ToUTF8(search_terms_args.search_terms); new_params += old_params.substr(search_terms_position.end()); - url::StdStringReplacements<std::string> replacements; + GURL::Replacements replacements; if (search_term_component == url::Parsed::REF) replacements.SetRefStr(new_params); else
diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc index 35e2fd1..c1add44 100644 --- a/components/search_engines/template_url_prepopulate_data.cc +++ b/components/search_engines/template_url_prepopulate_data.cc
@@ -53,23 +53,23 @@ // United Arab Emirates const PrepopulatedEngine* engines_AE[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Albania const PrepopulatedEngine* engines_AL[] = - { &google, &yahoo, &bing_en_XA, &bing_ar_XA, }; + { &google, &yahoo, &bing, }; // Argentina const PrepopulatedEngine* engines_AR[] = - { &google, &bing_es_AR, &yahoo_ar, }; + { &google, &bing, &yahoo_ar, }; // Austria const PrepopulatedEngine* engines_AT[] = - { &google, &bing_de_AT, &yahoo_at, }; + { &google, &bing, &yahoo_at, }; // Australia const PrepopulatedEngine* engines_AU[] = - { &google, &bing_en_AU, &yahoo_au, }; + { &google, &bing, &yahoo_au, }; // Bosnia and Herzegovina const PrepopulatedEngine* engines_BA[] = @@ -77,7 +77,7 @@ // Belgium const PrepopulatedEngine* engines_BE[] = - { &google, &bing_nl_BE, &bing_fr_BE, &yahoo, &yahoo_fr, }; + { &google, &bing, &yahoo, &yahoo_fr, }; // Bulgaria const PrepopulatedEngine* engines_BG[] = @@ -85,7 +85,7 @@ // Bahrain const PrepopulatedEngine* engines_BH[] = - { &google, &yahoo_maktoob, &bing_en_XA, &bing_ar_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Burundi const PrepopulatedEngine* engines_BI[] = @@ -97,15 +97,15 @@ // Bolivia const PrepopulatedEngine* engines_BO[] = - { &google, &bing_es_XL, &yahoo, }; + { &google, &bing, &yahoo, }; // Brazil const PrepopulatedEngine* engines_BR[] = - { &google, &ask_br, &bing_pt_BR, &yahoo_br, }; + { &google, &ask_br, &bing, &yahoo_br, }; // Belarus const PrepopulatedEngine* engines_BY[] = - { &google, &yahoo_ru, &bing_ru_RU, }; + { &google, &yahoo_ru, &bing, }; // Belize const PrepopulatedEngine* engines_BZ[] = @@ -113,15 +113,15 @@ // Canada const PrepopulatedEngine* engines_CA[] = - { &google, &bing_en_CA, &bing_fr_CA, &ask, &yahoo_ca, &yahoo_qc, }; + { &google, &bing, &ask, &yahoo_ca, &yahoo_qc, }; // Switzerland const PrepopulatedEngine* engines_CH[] = - { &google, &bing_de_CH, &bing_fr_CH, &yahoo_ch, }; + { &google, &bing, &yahoo_ch, }; // Chile const PrepopulatedEngine* engines_CL[] = - { &google, &bing_es_CL, &yahoo_cl, }; + { &google, &bing, &yahoo_cl, }; // China const PrepopulatedEngine* engines_CN[] = @@ -129,11 +129,11 @@ // Colombia const PrepopulatedEngine* engines_CO[] = - { &google, &bing_es_XL, &yahoo_co, }; + { &google, &bing, &yahoo_co, }; // Costa Rica const PrepopulatedEngine* engines_CR[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Czech Republic const PrepopulatedEngine* engines_CZ[] = @@ -141,23 +141,23 @@ // Germany const PrepopulatedEngine* engines_DE[] = - { &google, &bing_de_DE, &yahoo_de }; + { &google, &bing, &yahoo_de }; // Denmark const PrepopulatedEngine* engines_DK[] = - { &google, &bing_da_DK, &yahoo_dk, }; + { &google, &bing, &yahoo_dk, }; // Dominican Republic const PrepopulatedEngine* engines_DO[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Algeria const PrepopulatedEngine* engines_DZ[] = - { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, }; + { &google, &bing, &yahoo_maktoob, }; // Ecuador const PrepopulatedEngine* engines_EC[] = - { &google, &bing_es_XL, &yahoo, }; + { &google, &bing, &yahoo, }; // Estonia const PrepopulatedEngine* engines_EE[] = @@ -165,27 +165,27 @@ // Egypt const PrepopulatedEngine* engines_EG[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Spain const PrepopulatedEngine* engines_ES[] = - { &google, &bing_es_ES, &yahoo_es, }; + { &google, &bing, &yahoo_es, }; // Faroe Islands const PrepopulatedEngine* engines_FO[] = - { &google, &bing_da_DK, &ask, }; + { &google, &bing, &ask, }; // Finland const PrepopulatedEngine* engines_FI[] = - { &google, &bing_fi_FI, &yahoo_fi, }; + { &google, &bing, &yahoo_fi, }; // France const PrepopulatedEngine* engines_FR[] = - { &google, &bing_fr_FR, &yahoo_fr, }; + { &google, &bing, &yahoo_fr, }; // United Kingdom const PrepopulatedEngine* engines_GB[] = - { &google, &bing_en_GB, &yahoo_uk, &ask_uk, }; + { &google, &bing, &yahoo_uk, &ask_uk, }; // Greece const PrepopulatedEngine* engines_GR[] = @@ -193,15 +193,15 @@ // Guatemala const PrepopulatedEngine* engines_GT[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Hong Kong const PrepopulatedEngine* engines_HK[] = - { &google, &yahoo_hk, &baidu, &bing_zh_HK, }; + { &google, &yahoo_hk, &baidu, &bing, }; // Honduras const PrepopulatedEngine* engines_HN[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Croatia const PrepopulatedEngine* engines_HR[] = @@ -217,7 +217,7 @@ // Ireland const PrepopulatedEngine* engines_IE[] = - { &google, &bing_en_IE, &yahoo_uk, }; + { &google, &bing, &yahoo_uk, }; // Israel const PrepopulatedEngine* engines_IL[] = @@ -225,11 +225,11 @@ // India const PrepopulatedEngine* engines_IN[] = - { &google, &bing_en_IN, &yahoo_in, }; + { &google, &bing, &yahoo_in, }; // Iraq const PrepopulatedEngine* engines_IQ[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Iran const PrepopulatedEngine* engines_IR[] = @@ -241,7 +241,7 @@ // Italy const PrepopulatedEngine* engines_IT[] = - { &google, &virgilio, &bing_it_IT, }; + { &google, &virgilio, &bing, }; // Jamaica const PrepopulatedEngine* engines_JM[] = @@ -249,11 +249,11 @@ // Jordan const PrepopulatedEngine* engines_JO[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Japan const PrepopulatedEngine* engines_JP[] = - { &google, &yahoo_jp, &bing_ja_JP, }; + { &google, &yahoo_jp, &bing, }; // Kenya const PrepopulatedEngine* engines_KE[] = @@ -261,7 +261,7 @@ // Kuwait const PrepopulatedEngine* engines_KW[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // South Korea const PrepopulatedEngine* engines_KR[] = @@ -273,11 +273,11 @@ // Lebanon const PrepopulatedEngine* engines_LB[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Liechtenstein const PrepopulatedEngine* engines_LI[] = - { &google, &bing_de_DE, &yahoo_de, }; + { &google, &bing, &yahoo_de, }; // Lithuania const PrepopulatedEngine* engines_LT[] = @@ -285,7 +285,7 @@ // Luxembourg const PrepopulatedEngine* engines_LU[] = - { &google, &bing_fr_FR, &yahoo_fr, }; + { &google, &bing, &yahoo_fr, }; // Latvia const PrepopulatedEngine* engines_LV[] = @@ -293,15 +293,15 @@ // Libya const PrepopulatedEngine* engines_LY[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Morocco const PrepopulatedEngine* engines_MA[] = - { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, }; + { &google, &bing, &yahoo_maktoob, }; // Monaco const PrepopulatedEngine* engines_MC[] = - { &google, &yahoo_fr, &bing_fr_FR, }; + { &google, &yahoo_fr, &bing, }; // Moldova const PrepopulatedEngine* engines_MD[] = @@ -317,7 +317,7 @@ // Mexico const PrepopulatedEngine* engines_MX[] = - { &google, &bing_es_MX, &yahoo_mx, }; + { &google, &bing, &yahoo_mx, }; // Malaysia const PrepopulatedEngine* engines_MY[] = @@ -325,7 +325,7 @@ // Nicaragua const PrepopulatedEngine* engines_NI[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Netherlands const PrepopulatedEngine* engines_NL[] = @@ -333,27 +333,27 @@ // Norway const PrepopulatedEngine* engines_NO[] = - { &google, &bing_nb_NO, &kvasir, }; + { &google, &bing, &kvasir, }; // New Zealand const PrepopulatedEngine* engines_NZ[] = - { &google, &bing_en_NZ, &yahoo_nz, }; + { &google, &bing, &yahoo_nz, }; // Oman const PrepopulatedEngine* engines_OM[] = - { &google, &bing_ar_XA, &yahoo_maktoob, &bing_en_XA, }; + { &google, &bing, &yahoo_maktoob, }; // Panama const PrepopulatedEngine* engines_PA[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Peru const PrepopulatedEngine* engines_PE[] = - { &google, &bing_es_XL, &yahoo_pe, }; + { &google, &bing, &yahoo_pe, }; // Philippines const PrepopulatedEngine* engines_PH[] = - { &google, &yahoo_ph, &bing_en_PH, }; + { &google, &yahoo_ph, &bing, }; // Pakistan const PrepopulatedEngine* engines_PK[] = @@ -361,23 +361,23 @@ // Puerto Rico const PrepopulatedEngine* engines_PR[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Poland const PrepopulatedEngine* engines_PL[] = - { &google, &onet, &bing_pl_PL, }; + { &google, &onet, &bing, }; // Portugal const PrepopulatedEngine* engines_PT[] = - { &google, &bing_pt_PT, &yahoo, }; + { &google, &bing, &yahoo, }; // Paraguay const PrepopulatedEngine* engines_PY[] = - { &google, &bing_es_XL, &yahoo, }; + { &google, &bing, &yahoo, }; // Qatar const PrepopulatedEngine* engines_QA[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Romania const PrepopulatedEngine* engines_RO[] = @@ -397,15 +397,15 @@ // Saudi Arabia const PrepopulatedEngine* engines_SA[] = - { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, }; + { &google, &yahoo_maktoob, &bing, }; // Sweden const PrepopulatedEngine* engines_SE[] = - { &google, &bing_sv_SE, &yahoo_se, }; + { &google, &bing, &yahoo_se, }; // Singapore const PrepopulatedEngine* engines_SG[] = - { &google, &yahoo_sg, &bing_en_SG, }; + { &google, &yahoo_sg, &bing, }; // Slovenia const PrepopulatedEngine* engines_SI[] = @@ -417,11 +417,11 @@ // El Salvador const PrepopulatedEngine* engines_SV[] = - { &google, &yahoo, &bing_es_XL, }; + { &google, &yahoo, &bing, }; // Syria const PrepopulatedEngine* engines_SY[] = - { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, }; + { &google, &bing, &yahoo_maktoob, }; // Thailand const PrepopulatedEngine* engines_TH[] = @@ -429,11 +429,11 @@ // Tunisia const PrepopulatedEngine* engines_TN[] = - { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, }; + { &google, &bing, &yahoo_maktoob, }; // Turkey const PrepopulatedEngine* engines_TR[] = - { &google, &bing_tr_TR, &yahoo_tr, &yandex_tr, }; + { &google, &bing, &yahoo_tr, &yandex_tr, }; // Trinidad and Tobago const PrepopulatedEngine* engines_TT[] = @@ -441,7 +441,7 @@ // Taiwan const PrepopulatedEngine* engines_TW[] = - { &google, &yahoo_tw, &bing_zh_TW, }; + { &google, &yahoo_tw, &bing, }; // Tanzania const PrepopulatedEngine* engines_TZ[] = @@ -449,19 +449,19 @@ // Ukraine const PrepopulatedEngine* engines_UA[] = - { &google, &yandex_ua, &bing_ru_RU, }; + { &google, &yandex_ua, &bing, }; // United States const PrepopulatedEngine* engines_US[] = - { &google, &bing_en_US, &yahoo, &aol, &ask, }; + { &google, &bing, &yahoo, &aol, &ask, }; // Uruguay const PrepopulatedEngine* engines_UY[] = - { &google, &bing_es_XL, &yahoo, }; + { &google, &bing, &yahoo, }; // Venezuela const PrepopulatedEngine* engines_VE[] = - { &google, &bing_es_XL, &yahoo_ve, }; + { &google, &bing, &yahoo_ve, }; // Vietnam const PrepopulatedEngine* engines_VN[] = @@ -469,7 +469,7 @@ // Yemen const PrepopulatedEngine* engines_YE[] = - { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, }; + { &google, &bing, &yahoo_maktoob, }; // South Africa const PrepopulatedEngine* engines_ZA[] = @@ -483,24 +483,17 @@ const PrepopulatedEngine* kAllEngines[] = { // Prepopulated engines: &aol, &ask, &ask_br, &ask_uk, &baidu, - &bing, &bing_ar_XA, &bing_da_DK, &bing_de_AT, &bing_de_CH, - &bing_de_DE, &bing_en_AU, &bing_en_CA, &bing_en_GB, &bing_en_IE, - &bing_en_IN, &bing_en_NZ, &bing_en_PH, &bing_en_SG, &bing_en_US, - &bing_en_XA, &bing_es_AR, &bing_es_CL, &bing_es_ES, &bing_es_MX, - &bing_es_XL, &bing_fi_FI, &bing_fr_BE, &bing_fr_CA, &bing_fr_CH, - &bing_fr_FR, &bing_it_IT, &bing_ja_JP, &bing_lv_LV, &bing_nb_NO, - &bing_nl_BE, &bing_pl_PL, &bing_pt_BR, &bing_pt_PT, &bing_ru_RU, - &bing_sv_SE, &bing_tr_TR, &bing_zh_HK, &bing_zh_TW, &daum, - &google, &kvasir, &mail_ru, &najdi, &naver, - &onet, &seznam, &sogou, &vinden, &virgilio, - &yahoo, &yahoo_ar, &yahoo_at, &yahoo_au, &yahoo_br, - &yahoo_ca, &yahoo_ch, &yahoo_cl, &yahoo_co, &yahoo_de, - &yahoo_dk, &yahoo_es, &yahoo_fi, &yahoo_fr, &yahoo_gr, - &yahoo_hk, &yahoo_id, &yahoo_in, &yahoo_jp, &yahoo_maktoob, - &yahoo_mx, &yahoo_my, &yahoo_nl, &yahoo_nz, &yahoo_pe, - &yahoo_ph, &yahoo_qc, &yahoo_ro, &yahoo_ru, &yahoo_se, - &yahoo_sg, &yahoo_th, &yahoo_tr, &yahoo_tw, &yahoo_uk, - &yahoo_ve, &yahoo_vn, &yandex_ru, &yandex_tr, &yandex_ua, + &bing, &daum, &google, &kvasir, &mail_ru, + &najdi, &naver, &onet, &seznam, &sogou, + &vinden, &virgilio, &yahoo, &yahoo_ar, &yahoo_at, + &yahoo_au, &yahoo_br, &yahoo_ca, &yahoo_ch, &yahoo_cl, + &yahoo_co, &yahoo_de, &yahoo_dk, &yahoo_es, &yahoo_fi, + &yahoo_fr, &yahoo_gr, &yahoo_hk, &yahoo_id, &yahoo_in, + &yahoo_jp, &yahoo_maktoob,&yahoo_mx, &yahoo_my, &yahoo_nl, + &yahoo_nz, &yahoo_pe, &yahoo_ph, &yahoo_qc, &yahoo_ro, + &yahoo_ru, &yahoo_se, &yahoo_sg, &yahoo_th, &yahoo_tr, + &yahoo_tw, &yahoo_uk, &yahoo_ve, &yahoo_vn, &yandex_ru, + &yandex_tr, &yandex_ua, // UMA-only engines: &atlas_cz, &atlas_sk, &avg, &babylon, &conduit,
diff --git a/components/test/data/password_manager/automated_tests/environment.py b/components/test/data/password_manager/automated_tests/environment.py index 86685b3..71eca92 100644 --- a/components/test/data/password_manager/automated_tests/environment.py +++ b/components/test/data/password_manager/automated_tests/environment.py
@@ -87,10 +87,7 @@ try: shutil.rmtree(profile_path) except Exception, e: - # The tests execution can continue, but this make them less stable. - logging.error("Error: Could not wipe the chrome profile directory (%s). \ - This affects the stability of the tests. Continuing to run tests." - % e) + pass # If |chrome_path| is not defined, this means that we are in the dashboard # website, and we just need to get the list of all websites. In this case, # we don't need to initilize the webdriver.
diff --git a/components/test/data/password_manager/automated_tests/run_tests.py b/components/test/data/password_manager/automated_tests/run_tests.py index 4e05853f..0db26e6 100644 --- a/components/test/data/password_manager/automated_tests/run_tests.py +++ b/components/test/data/password_manager/automated_tests/run_tests.py
@@ -7,190 +7,218 @@ Running this script requires passing --config-path with a path to a config file of the following structure: - [credentials] + [data_files] + passwords_path=<path to a file with passwords> + [binaries] + chrome-path=<chrome binary path> + chromedriver-path=<chrome driver path> + [run_options] + write_to_sheet=[false|true] + tests_in_parrallel=<number of parallel tests> + # |tests_to_runs| field is optional, if it is absent all tests will be run. + tests_to_run=<test names to run, comma delimited> + [output] + save-path=<file where to save result> + [sheet_info] + # This section is required only when write_to_sheet=true pkey=full_path client_email=email_assigned_by_google_dev_console - [drive] - key=sheet_key_from_sheet_url - [data_files] - passwords_path=full_path_to_the_file_with_passwords + sheet_key=sheet_key_from_sheet_url """ -from Sheet import Sheet -from apiclient.discovery import build from datetime import datetime -from gdata.gauth import OAuth2TokenFromCredentials -from gdata.spreadsheet.service import SpreadsheetsService -from oauth2client.client import SignedJwtAssertionCredentials import ConfigParser -import argparse +import sys import httplib2 -import oauth2client.tools import os +import shutil import subprocess import tempfile +import time +sheet_libraries_import_error = None +try: + from Sheet import Sheet + from apiclient.discovery import build + from gdata.gauth import OAuth2TokenFromCredentials + from gdata.spreadsheet.service import SpreadsheetsService + from oauth2client.client import SignedJwtAssertionCredentials + import oauth2client.tools +except ImportError as err: + sheet_libraries_import_error = err + from environment import Environment import tests _CREDENTIAL_SCOPES = "https://spreadsheets.google.com/feeds" -# TODO(melandory): Function _authenticate belongs to separate module. -def _authenticate(pkey, client_email): - """ Authenticates user. +# TODO(dvadym) Change all prints in this file to correspond logging. - Args: - pkey: Full path to file with private key generated by Google - Developer Console. - client_email: Email address corresponding to private key and also - generated by Google Developer Console. - """ - http, token = None, None - with open(pkey) as pkey_file: - private_key = pkey_file.read() - credentials = SignedJwtAssertionCredentials( - client_email, private_key, _CREDENTIAL_SCOPES) - http = httplib2.Http() - http = credentials.authorize(http) - build('drive', 'v2', http=http) - token = OAuth2TokenFromCredentials(credentials).access_token - return http, token +# TODO(dvadym) Consider to move this class to separate file. +class SheetWriter(object): -# TODO(melandory): Functionality of _spredsheeet_for_logging belongs -# to websitetests, because this way we do not need to write results of run -# in separate file and then read it here. -def _spredsheeet_for_logging(sheet_key, access_token): - """ Connects to document where result of test run will be logged. - Args: - sheet_key: Key of sheet in Trix. Can be found in sheet's URL. - access_token: Access token of an account which should have edit rights. - """ - # Connect to trix - service = SpreadsheetsService(additional_headers={ - "Authorization": "Bearer " + access_token}) - sheet = Sheet(service, sheet_key) - return sheet + def __init__(self, config): + self.write_to_sheet = config.getboolean("run_options", "write_to_sheet") + if not self.write_to_sheet: + return + if sheet_libraries_import_error: + raise sheet_libraries_import_error + self.pkey = config.get("sheet_info", "pkey") + self.client_mail = config.get("sheet_info", "client_email") + self.sheet_key = config.get("sheet_info", "sheet_key") + _, self.access_token = self._authenticate() + self.sheet = self._spredsheeet_for_logging() -def _try_run_individual_test(test_cmd, results_path): - """ Runs individual test and logs results to trix. + # TODO(melandory): Function _authenticate belongs to separate module. + def _authenticate(self): + http, token = None, None + with open(self.pkey) as pkey_file: + private_key = pkey_file.read() + credentials = SignedJwtAssertionCredentials( + self.client_email, private_key, _CREDENTIAL_SCOPES) + http = httplib2.Http() + http = credentials.authorize(http) + build("drive", "v2", http=http) + token = OAuth2TokenFromCredentials(credentials).access_token + return http, token - Args: - test_cmd: String contains command which runs test. - results_path: Full path to file where results of test run will be logged. - """ - failures = [] - # The tests can be flaky. This is why we try to rerun up to 3 times. - for x in xrange(3): - # TODO(rchtara): Using "pkill" is just temporary until a better, - # platform-independent solution is found. - # Using any kind of kill and process name isn't best solution. - # Mainly because it kills every running instace of Chrome on the machine, - # which is unpleasant experience, when you're running tests locally. - # In my opinion proper solution is to invoke chrome using subproceses and - # then kill only this particular instance of it. - os.system("pkill chrome") + # TODO(melandory): Functionality of _spredsheeet_for_logging belongs + # to websitetests, because this way we do not need to write results of run + # in separate file and then read it here. + def _spredsheeet_for_logging(self): + """ Connects to document where result of test run will be logged. """ + # Connect to trix + service = SpreadsheetsService(additional_headers={ + "Authorization": "Bearer " + self.access_token}) + sheet = Sheet(service, self.sheet_key) + return sheet + + def write_line_to_sheet(self, data): + if not self.write_to_sheet: + return try: - os.remove(results_path) + self.sheet.InsertRow(self.sheet.row_count, data) except Exception: - pass + pass # TODO(melandory): Sometimes writing to spreadsheet fails. We need + # to deal with it better that just ignoring it. + +class TestRunner(object): + + def __init__(self, general_test_cmd, test_name): + """ Args: + general_test_cmd: String contains part of run command common for all tests, + [2] is placeholder for test name. + test_name: Test name (facebook for example). + """ + self.profile_path = tempfile.mkdtemp() + results = tempfile.NamedTemporaryFile(delete=False) + self.results_path = results.name + results.close() + self.test_cmd = general_test_cmd + ["--profile-path", self.profile_path, + "--save-path", self.results_path] + self.test_cmd[2] = self.test_name = test_name # TODO(rchtara): Using "timeout is just temporary until a better, # platform-independent solution is found. - # The website test runs in two passes, each pass has an internal # timeout of 200s for waiting (see |remaining_time_to_wait| and # Wait() in websitetest.py). Accounting for some more time spent on # the non-waiting execution, 300 seconds should be the upper bound on # the runtime of one pass, thus 600 seconds for the whole test. - subprocess.call(["timeout", "600"] + test_cmd) - if os.path.isfile(results_path): - results = open(results_path, "r") - count = 0 # Count the number of successful tests. + self.test_cmd = ["timeout", "600"] + self.test_cmd + self.runner_process = None + # The tests can be flaky. This is why we try to rerun up to 3 times. + self.max_test_runs_left = 3 + self.failures = [] + self._run_test() + + def get_test_result(self): + """ Return None if result is not ready yet.""" + test_running = self.runner_process and self.runner_process.poll() is None + if test_running: return None + # Test is not running, now we have to check if we want to start it again. + if self._check_if_test_passed(): + print "Test " + self.test_name + " passed" + return "pass", [] + if self.max_test_runs_left == 0: + print "Test " + self.test_name + " failed" + return "fail", self.failures + self._run_test() + return None + + def _check_if_test_passed(self): + if os.path.isfile(self.results_path): + results = open(self.results_path, "r") + count = 0 # Count the number of successful tests. for line in results: # TODO(melandory): We do not need to send all this data to sheet. - failures.append(line) + self.failures.append(line) count += line.count("successful='True'") results.close() # There is only two tests running for every website: the prompt and # the normal test. If both of the tests were successful, the tests # would be stopped for the current website. + print "Test run of %s %s" % (self.test_name, "passed" + if count == 2 else "failed") if count == 2: - return "pass", [] - else: + return True + return False + + def _run_test(self): + """Run separate process that once run test for one site.""" + try: + os.remove(self.results_path) + except Exception: pass - return "fail", failures + try: + shutil.rmtree(self.profile_path) + except Exception: + pass + self.max_test_runs_left -= 1 + print "Run of test %s started" % self.test_name + self.runner_process = subprocess.Popen(self.test_cmd) - -def run_tests( - chrome_path, chromedriver_path, - profile_path, config_path, *args, **kwargs): - """ Runs automated tests. - - Args: - save_path: File, where results of run will be logged. - chrome_path: Location of Chrome binary. - chromedriver_path: Location of Chrome Driver. - passwords_path: Location of file with credentials. - profile_path: Location of profile path. - *args: Variable length argument list. - **kwargs: Arbitrary keyword arguments. - """ - environment = Environment('', '', '', None, False) +def run_tests(config_path): + """ Runs automated tests. """ + environment = Environment("", "", "", None, False) tests.Tests(environment) config = ConfigParser.ConfigParser() config.read(config_path) date = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') - try: - _, access_token = _authenticate(config.get("credentials", "pkey"), - config.get("credentials", "client_email")) - sheet = _spredsheeet_for_logging(config.get("drive", "key"), access_token) - results = tempfile.NamedTemporaryFile( - dir=os.path.join(tempfile.gettempdir()), delete=False) - results_path = results.name - results.close() + max_tests_in_parrallel = config.getint("run_options", "tests_in_parrallel") + sheet_writer = SheetWriter(config) + full_path = os.path.realpath(__file__) + tests_dir = os.path.dirname(full_path) + tests_path = os.path.join(tests_dir, "tests.py") + general_test_cmd = ["python", tests_path, "test_name_placeholder", + "--chrome-path", config.get("binaries", "chrome-path"), + "--chromedriver-path", config.get("binaries", "chromedriver-path"), + "--passwords-path", config.get("data_files", "passwords_path")] + runners = [] + tests_to_run = [test.name for test in environment.websitetests] + if config.has_option("run_options", "tests_to_run"): + user_selected_tests = config.get("run_options", "tests_to_run").split(',') + # TODO((dvadym) Validate the user selected tests are available. + tests_to_run = list(set(tests_to_run) & set(user_selected_tests)) - full_path = os.path.realpath(__file__) - tests_dir = os.path.dirname(full_path) - tests_path = os.path.join(tests_dir, "tests.py") - - for websitetest in environment.websitetests: - test_cmd = ["python", tests_path, websitetest.name, - "--chrome-path", chrome_path, - "--chromedriver-path", chromedriver_path, - "--passwords-path", - config.get("data_files", "passwords_path"), - "--profile-path", profile_path, - "--save-path", results_path] - status, log = _try_run_individual_test(test_cmd, results_path) - try: - sheet.InsertRow(sheet.row_count, - [websitetest.name, status, date, " | ".join(log)]) - except Exception: - pass # TODO(melandory): Sometimes writing to spreadsheet fails. We need - # deal with it better that just ignoring. - finally: - try: - os.remove(results_path) - except Exception: - pass - + with open(config.get("output", "save-path"), 'w') as savefile: + print "Tests to run %d\nTests: %s" % (len(tests_to_run), tests_to_run) + while len(runners) + len(tests_to_run) > 0: + i = 0 + while i < len(runners): + result = runners[i].get_test_result() + if result: # This test run is finished. + status, log = result + testinfo = [runners[i].test_name, status, date, " | ".join(log)] + sheet_writer.write_line_to_sheet(testinfo) + print>>savefile, " ".join(testinfo) + del runners[i] + else: + i += 1 + while len(runners) < max_tests_in_parrallel and len(tests_to_run) > 0: + runners.append(TestRunner(general_test_cmd, tests_to_run.pop())) + time.sleep(1) # Let us wait for worker process to finish. if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Password Manager automated tests runner help.") - parser.add_argument( - "--chrome-path", action="store", dest="chrome_path", - help="Set the chrome path (required).", required=True) - parser.add_argument( - "--chromedriver-path", action="store", dest="chromedriver_path", - help="Set the chromedriver path (required).", required=True) - parser.add_argument( - "--config-path", action="store", dest="config_path", - help="File with configuration data: drive credentials, password path", - required=True) - parser.add_argument( - "--profile-path", action="store", dest="profile_path", - help="Set the profile path (required). You just need to choose a " - "temporary empty folder. If the folder is not empty all its content " - "is going to be removed.", - required=True) - args = vars(parser.parse_args()) - run_tests(**args) + if len(sys.argv) != 2: + print "Synopsis:\n python run_tests.py <config_path>" + config_path = sys.argv[1] + run_tests(config_path)
diff --git a/components/update_client/component_patcher.cc b/components/update_client/component_patcher.cc index 651756e..3077bc4f 100644 --- a/components/update_client/component_patcher.cc +++ b/components/update_client/component_patcher.cc
@@ -16,6 +16,7 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" #include "components/update_client/component_patcher_operation.h" +#include "components/update_client/update_client.h" namespace update_client { @@ -42,7 +43,7 @@ ComponentPatcher::ComponentPatcher( const base::FilePath& input_dir, const base::FilePath& unpack_dir, - ComponentInstaller* installer, + scoped_refptr<ComponentInstaller> installer, scoped_refptr<OutOfProcessPatcher> out_of_process_patcher, scoped_refptr<base::SequencedTaskRunner> task_runner) : input_dir_(input_dir),
diff --git a/components/update_client/component_patcher.h b/components/update_client/component_patcher.h index b7dd216d..394edfe 100644 --- a/components/update_client/component_patcher.h +++ b/components/update_client/component_patcher.h
@@ -61,7 +61,7 @@ // out-of-process. ComponentPatcher(const base::FilePath& input_dir, const base::FilePath& unpack_dir, - ComponentInstaller* installer, + scoped_refptr<ComponentInstaller> installer, scoped_refptr<OutOfProcessPatcher> out_of_process_patcher, scoped_refptr<base::SequencedTaskRunner> task_runner); @@ -86,7 +86,7 @@ const base::FilePath input_dir_; const base::FilePath unpack_dir_; - ComponentInstaller* const installer_; + scoped_refptr<ComponentInstaller> installer_; scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_; ComponentUnpacker::Callback callback_; scoped_ptr<base::ListValue> commands_;
diff --git a/components/update_client/component_patcher_operation.cc b/components/update_client/component_patcher_operation.cc index adb5b8f..c5e74374 100644 --- a/components/update_client/component_patcher_operation.cc +++ b/components/update_client/component_patcher_operation.cc
@@ -43,7 +43,7 @@ DeltaUpdateOp* CreateDeltaUpdateOp( const std::string& operation, - scoped_refptr<OutOfProcessPatcher> out_of_process_patcher) { + const scoped_refptr<OutOfProcessPatcher>& out_of_process_patcher) { if (operation == "copy") { return new DeltaUpdateOpCopy(); } else if (operation == "create") { @@ -60,12 +60,13 @@ DeltaUpdateOp::~DeltaUpdateOp() { } -void DeltaUpdateOp::Run(const base::DictionaryValue* command_args, - const base::FilePath& input_dir, - const base::FilePath& unpack_dir, - ComponentInstaller* installer, - const ComponentUnpacker::Callback& callback, - scoped_refptr<base::SequencedTaskRunner> task_runner) { +void DeltaUpdateOp::Run( + const base::DictionaryValue* command_args, + const base::FilePath& input_dir, + const base::FilePath& unpack_dir, + const scoped_refptr<ComponentInstaller>& installer, + const ComponentUnpacker::Callback& callback, + const scoped_refptr<base::SequencedTaskRunner>& task_runner) { callback_ = callback; task_runner_ = task_runner; std::string output_rel_path; @@ -140,7 +141,7 @@ ComponentUnpacker::Error DeltaUpdateOpCopy::DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) { + const scoped_refptr<ComponentInstaller>& installer) { std::string input_rel_path; if (!command_args->GetString(kInput, &input_rel_path)) return ComponentUnpacker::kDeltaBadCommands; @@ -167,7 +168,7 @@ ComponentUnpacker::Error DeltaUpdateOpCreate::DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) { + const scoped_refptr<ComponentInstaller>& installer) { std::string patch_rel_path; if (!command_args->GetString(kPatch, &patch_rel_path)) return ComponentUnpacker::kDeltaBadCommands; @@ -198,7 +199,7 @@ ComponentUnpacker::Error DeltaUpdateOpPatch::DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) { + const scoped_refptr<ComponentInstaller>& installer) { std::string patch_rel_path; std::string input_rel_path; if (!command_args->GetString(kPatch, &patch_rel_path) ||
diff --git a/components/update_client/component_patcher_operation.h b/components/update_client/component_patcher_operation.h index 8f31c043..0771757 100644 --- a/components/update_client/component_patcher_operation.h +++ b/components/update_client/component_patcher_operation.h
@@ -37,9 +37,9 @@ void Run(const base::DictionaryValue* command_args, const base::FilePath& input_dir, const base::FilePath& unpack_dir, - ComponentInstaller* installer, + const scoped_refptr<ComponentInstaller>& installer, const ComponentUnpacker::Callback& callback, - scoped_refptr<base::SequencedTaskRunner> task_runner); + const scoped_refptr<base::SequencedTaskRunner>& task_runner); protected: virtual ~DeltaUpdateOp(); @@ -60,7 +60,7 @@ virtual ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) = 0; + const scoped_refptr<ComponentInstaller>& installer) = 0; // Subclasses must override DoRun to actually perform the patching operation. // They must call the provided callback when they have completed their @@ -92,7 +92,7 @@ ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) override; + const scoped_refptr<ComponentInstaller>& installer) override; void DoRun(const ComponentUnpacker::Callback& callback) override; @@ -116,7 +116,7 @@ ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) override; + const scoped_refptr<ComponentInstaller>& installer) override; void DoRun(const ComponentUnpacker::Callback& callback) override; @@ -129,12 +129,13 @@ class OutOfProcessPatcher : public base::RefCountedThreadSafe<OutOfProcessPatcher> { public: - virtual void Patch(const std::string& operation, - scoped_refptr<base::SequencedTaskRunner> task_runner, - const base::FilePath& input_abs_path, - const base::FilePath& patch_abs_path, - const base::FilePath& output_abs_path, - base::Callback<void(int result)> callback) = 0; + virtual void Patch( + const std::string& operation, + scoped_refptr<base::SequencedTaskRunner> task_runner, + const base::FilePath& input_abs_path, + const base::FilePath& patch_abs_path, + const base::FilePath& output_abs_path, + base::Callback<void(int result)> callback) = 0; protected: friend class base::RefCountedThreadSafe<OutOfProcessPatcher>; @@ -159,7 +160,7 @@ ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, - ComponentInstaller* installer) override; + const scoped_refptr<ComponentInstaller>& installer) override; void DoRun(const ComponentUnpacker::Callback& callback) override; @@ -177,7 +178,7 @@ DeltaUpdateOp* CreateDeltaUpdateOp( const std::string& operation, - scoped_refptr<OutOfProcessPatcher> out_of_process_patcher); + const scoped_refptr<OutOfProcessPatcher>& out_of_process_patcher); } // namespace update_client
diff --git a/components/update_client/component_unpacker.cc b/components/update_client/component_unpacker.cc index 27d75b9..eb1b2d89 100644 --- a/components/update_client/component_unpacker.cc +++ b/components/update_client/component_unpacker.cc
@@ -102,9 +102,9 @@ const std::vector<uint8_t>& pk_hash, const base::FilePath& path, const std::string& fingerprint, - ComponentInstaller* installer, - scoped_refptr<OutOfProcessPatcher> oop_patcher, - scoped_refptr<base::SequencedTaskRunner> task_runner) + const scoped_refptr<ComponentInstaller>& installer, + const scoped_refptr<OutOfProcessPatcher>& oop_patcher, + const scoped_refptr<base::SequencedTaskRunner>& task_runner) : pk_hash_(pk_hash), path_(path), is_delta_(false),
diff --git a/components/update_client/component_unpacker.h b/components/update_client/component_unpacker.h index 7c2b6efc..033fd33 100644 --- a/components/update_client/component_unpacker.h +++ b/components/update_client/component_unpacker.h
@@ -95,12 +95,13 @@ // Constructs an unpacker for a specific component unpacking operation. // |pk_hash| is the expected/ public key SHA256 hash. |path| is the current // location of the CRX. - ComponentUnpacker(const std::vector<uint8_t>& pk_hash, - const base::FilePath& path, - const std::string& fingerprint, - ComponentInstaller* installer, - scoped_refptr<OutOfProcessPatcher> oop_patcher, - scoped_refptr<base::SequencedTaskRunner> task_runner); + ComponentUnpacker( + const std::vector<uint8_t>& pk_hash, + const base::FilePath& path, + const std::string& fingerprint, + const scoped_refptr<ComponentInstaller>& installer, + const scoped_refptr<OutOfProcessPatcher>& oop_patcher, + const scoped_refptr<base::SequencedTaskRunner>& task_runner); // Begins the actual unpacking of the files. May invoke a patcher if the // package is a differential update. Calls |callback| with the result. @@ -147,7 +148,7 @@ bool is_delta_; std::string fingerprint_; scoped_refptr<ComponentPatcher> patcher_; - ComponentInstaller* installer_; + scoped_refptr<ComponentInstaller> installer_; Callback callback_; scoped_refptr<OutOfProcessPatcher> oop_patcher_; Error error_;
diff --git a/components/update_client/crx_update_item.h b/components/update_client/crx_update_item.h index ba38a1b..09af62f 100644 --- a/components/update_client/crx_update_item.h +++ b/components/update_client/crx_update_item.h
@@ -71,6 +71,10 @@ // enforce conditions or notify observers of the change. Status status; + // True if the component was recently unregistered and will be uninstalled + // soon (after the currently operation is finished, if there is one). + bool unregistered; + std::string id; CrxComponent component;
diff --git a/components/update_client/test/component_patcher_unittest.cc b/components/update_client/test/component_patcher_unittest.cc index ce6e7a1..4f5e143 100644 --- a/components/update_client/test/component_patcher_unittest.cc +++ b/components/update_client/test/component_patcher_unittest.cc
@@ -69,7 +69,7 @@ EXPECT_TRUE(unpack_dir_.CreateUniqueTempDir()); EXPECT_TRUE(input_dir_.CreateUniqueTempDir()); EXPECT_TRUE(installed_dir_.CreateUniqueTempDir()); - installer_.reset(new ReadOnlyTestInstaller(installed_dir_.path())); + installer_ = new ReadOnlyTestInstaller(installed_dir_.path()); task_runner_ = base::MessageLoop::current()->task_runner(); }
diff --git a/components/update_client/test/component_patcher_unittest.h b/components/update_client/test/component_patcher_unittest.h index f7a4aea..2fcd5f5 100644 --- a/components/update_client/test/component_patcher_unittest.h +++ b/components/update_client/test/component_patcher_unittest.h
@@ -30,7 +30,7 @@ base::ScopedTempDir input_dir_; base::ScopedTempDir installed_dir_; base::ScopedTempDir unpack_dir_; - scoped_ptr<ReadOnlyTestInstaller> installer_; + scoped_refptr<ReadOnlyTestInstaller> installer_; scoped_refptr<base::SequencedTaskRunner> task_runner_; private:
diff --git a/components/update_client/test/test_installer.cc b/components/update_client/test/test_installer.cc index b6a3f843..6c03f49 100644 --- a/components/update_client/test/test_installer.cc +++ b/components/update_client/test/test_installer.cc
@@ -30,12 +30,11 @@ return false; } -int TestInstaller::error() const { - return error_; +TestInstaller::~TestInstaller() { } -int TestInstaller::install_count() const { - return install_count_; +bool TestInstaller::Uninstall() { + return false; } ReadOnlyTestInstaller::ReadOnlyTestInstaller(const base::FilePath& install_dir)
diff --git a/components/update_client/test/test_installer.h b/components/update_client/test/test_installer.h index 933fe21..a31c499 100644 --- a/components/update_client/test/test_installer.h +++ b/components/update_client/test/test_installer.h
@@ -31,11 +31,19 @@ bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; - int error() const; + bool Uninstall() override; - int install_count() const; + int error() const { + return error_; + } + + int install_count() const { + return install_count_; + } protected: + ~TestInstaller() override; + int error_; int install_count_; }; @@ -46,12 +54,12 @@ public: explicit ReadOnlyTestInstaller(const base::FilePath& installed_path); - ~ReadOnlyTestInstaller() override; - bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) override; private: + ~ReadOnlyTestInstaller() override; + base::FilePath install_directory_; }; @@ -61,8 +69,6 @@ public: VersionedTestInstaller(); - ~VersionedTestInstaller() override; - bool Install(const base::DictionaryValue& manifest, const base::FilePath& unpack_path) override; @@ -70,6 +76,8 @@ base::FilePath* installed_file) override; private: + ~VersionedTestInstaller() override; + base::FilePath install_directory_; Version current_version_; };
diff --git a/components/update_client/update_client.cc b/components/update_client/update_client.cc index b7fff2b5..35cc5bb 100644 --- a/components/update_client/update_client.cc +++ b/components/update_client/update_client.cc
@@ -10,6 +10,7 @@ CrxUpdateItem::CrxUpdateItem() : status(kNew), + unregistered(false), on_demand(false), diff_update_failed(false), error_category(0), @@ -23,8 +24,7 @@ CrxUpdateItem::~CrxUpdateItem() { } -CrxComponent::CrxComponent() - : installer(NULL), allow_background_download(true) { +CrxComponent::CrxComponent() : allow_background_download(true) { } CrxComponent::~CrxComponent() {
diff --git a/components/update_client/update_client.h b/components/update_client/update_client.h index 07b5617..35b3cca 100644 --- a/components/update_client/update_client.h +++ b/components/update_client/update_client.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/memory/ref_counted.h" #include "base/version.h" namespace base { @@ -21,7 +22,8 @@ // Component specific installers must derive from this class and implement // OnUpdateError() and Install(). A valid instance of this class must be // given to ComponentUpdateService::RegisterComponent(). -class ComponentInstaller { +class ComponentInstaller + : public base::RefCountedThreadSafe<ComponentInstaller> { public: // Called by the component updater on the main thread when there was a // problem unpacking or verifying the component. |error| is a non-zero @@ -43,6 +45,14 @@ virtual bool GetInstalledFile(const std::string& file, base::FilePath* installed_file) = 0; + // Called by the component updater when a component has been unregistered and + // all versions should be uninstalled from disk. Returns true if + // uninstallation is supported, false otherwise. + virtual bool Uninstall() = 0; + + protected: + friend class base::RefCountedThreadSafe<ComponentInstaller>; + virtual ~ComponentInstaller() {} }; @@ -57,7 +67,7 @@ // the issue 340448 is resolved. struct CrxComponent { std::vector<uint8_t> pk_hash; - ComponentInstaller* installer; + scoped_refptr<ComponentInstaller> installer; Version version; std::string fingerprint; std::string name;
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index 684a0035..a413cce18 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -19,7 +19,6 @@ namespace chromeos { class ChromeUserManagerImpl; -class FakeLoginUtils; class FakeChromeUserManager; class MockUserManager; class SupervisedUserManagerImpl; @@ -173,7 +172,6 @@ friend class FakeUserManager; friend class chromeos::FakeChromeUserManager; friend class chromeos::MockUserManager; - friend class chromeos::FakeLoginUtils; friend class chromeos::UserAddingScreenTest; // Do not allow anyone else to create new User instances.
diff --git a/components/web_contents_delegate_android/color_chooser_android.h b/components/web_contents_delegate_android/color_chooser_android.h index 3966d1b..27042b01 100644 --- a/components/web_contents_delegate_android/color_chooser_android.h +++ b/components/web_contents_delegate_android/color_chooser_android.h
@@ -28,13 +28,13 @@ ColorChooserAndroid(content::WebContents* tab, SkColor initial_color, const std::vector<content::ColorSuggestion>& suggestions); - virtual ~ColorChooserAndroid(); + ~ColorChooserAndroid() override; void OnColorChosen(JNIEnv* env, jobject obj, jint color); // ColorChooser interface - virtual void End() override; - virtual void SetSelectedColor(SkColor color) override; + void End() override; + void SetSelectedColor(SkColor color) override; private: base::android::ScopedJavaGlobalRef<jobject> j_color_chooser_;
diff --git a/components/web_contents_delegate_android/web_contents_delegate_android.h b/components/web_contents_delegate_android/web_contents_delegate_android.h index a326d96..1552ac8 100644 --- a/components/web_contents_delegate_android/web_contents_delegate_android.h +++ b/components/web_contents_delegate_android/web_contents_delegate_android.h
@@ -43,7 +43,7 @@ class WebContentsDelegateAndroid : public content::WebContentsDelegate { public: WebContentsDelegateAndroid(JNIEnv* env, jobject obj); - virtual ~WebContentsDelegateAndroid(); + ~WebContentsDelegateAndroid() override; // Binds this WebContentsDelegateAndroid to the passed WebContents instance, // such that when that WebContents is destroyed, this @@ -51,33 +51,31 @@ void SetOwnerWebContents(content::WebContents* contents); // Overridden from WebContentsDelegate: - virtual content::WebContents* OpenURLFromTab( + content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; - virtual content::ColorChooser* OpenColorChooser( + content::ColorChooser* OpenColorChooser( content::WebContents* source, SkColor color, const std::vector<content::ColorSuggestion>& suggestions) override; - virtual void NavigationStateChanged( - content::WebContents* source, - content::InvalidateTypes changed_flags) override; - virtual void VisibleSSLStateChanged( - const content::WebContents* source) override; - virtual void ActivateContents(content::WebContents* contents) override; - virtual void DeactivateContents(content::WebContents* contents) override; - virtual void LoadingStateChanged(content::WebContents* source, - bool to_different_document) override; - virtual void LoadProgressChanged(content::WebContents* source, - double load_progress) override; - virtual void RendererUnresponsive(content::WebContents* source) override; - virtual void RendererResponsive(content::WebContents* source) override; - virtual void DidNavigateToPendingEntry(content::WebContents* source) override; - virtual void WebContentsCreated(content::WebContents* source_contents, - int opener_render_frame_id, - const base::string16& frame_name, - const GURL& target_url, - content::WebContents* new_contents) override; - virtual bool ShouldCreateWebContents( + void NavigationStateChanged(content::WebContents* source, + content::InvalidateTypes changed_flags) override; + void VisibleSSLStateChanged(const content::WebContents* source) override; + void ActivateContents(content::WebContents* contents) override; + void DeactivateContents(content::WebContents* contents) override; + void LoadingStateChanged(content::WebContents* source, + bool to_different_document) override; + void LoadProgressChanged(content::WebContents* source, + double load_progress) override; + void RendererUnresponsive(content::WebContents* source) override; + void RendererResponsive(content::WebContents* source) override; + void DidNavigateToPendingEntry(content::WebContents* source) override; + void WebContentsCreated(content::WebContents* source_contents, + int opener_render_frame_id, + const base::string16& frame_name, + const GURL& target_url, + content::WebContents* new_contents) override; + bool ShouldCreateWebContents( content::WebContents* web_contents, int route_id, int main_frame_route_id, @@ -86,38 +84,33 @@ const GURL& target_url, const std::string& partition_id, content::SessionStorageNamespace* session_storage_namespace) override; - virtual bool OnGoToEntryOffset(int offset) override; - virtual void CloseContents(content::WebContents* source) override; - virtual void MoveContents(content::WebContents* source, - const gfx::Rect& pos) override; - virtual bool AddMessageToConsole(content::WebContents* source, - int32 level, - const base::string16& message, - int32 line_no, - const base::string16& source_id) override; - virtual void UpdateTargetURL(content::WebContents* source, - const GURL& url) override; - virtual void HandleKeyboardEvent( + bool OnGoToEntryOffset(int offset) override; + void CloseContents(content::WebContents* source) override; + void MoveContents(content::WebContents* source, + const gfx::Rect& pos) override; + bool AddMessageToConsole(content::WebContents* source, + int32 level, + const base::string16& message, + int32 line_no, + const base::string16& source_id) override; + void UpdateTargetURL(content::WebContents* source, const GURL& url) override; + void HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - virtual bool TakeFocus(content::WebContents* source, bool reverse) override; - virtual void ShowRepostFormWarningDialog( - content::WebContents* source) override; - virtual void EnterFullscreenModeForTab(content::WebContents* web_contents, - const GURL& origin) override; - virtual void ExitFullscreenModeForTab( - content::WebContents* web_contents) override; - virtual bool IsFullscreenForTabOrPending( + bool TakeFocus(content::WebContents* source, bool reverse) override; + void ShowRepostFormWarningDialog(content::WebContents* source) override; + void EnterFullscreenModeForTab(content::WebContents* web_contents, + const GURL& origin) override; + void ExitFullscreenModeForTab(content::WebContents* web_contents) override; + bool IsFullscreenForTabOrPending( const content::WebContents* web_contents) const override; - virtual void ShowValidationMessage(content::WebContents* web_contents, - const gfx::Rect& anchor_in_root_view, - const base::string16& main_text, - const base::string16& sub_text) override; - virtual void HideValidationMessage( - content::WebContents* web_contents) override; - virtual void MoveValidationMessage( - content::WebContents* web_contents, - const gfx::Rect& anchor_in_root_view) override; + void ShowValidationMessage(content::WebContents* web_contents, + const gfx::Rect& anchor_in_root_view, + const base::string16& main_text, + const base::string16& sub_text) override; + void HideValidationMessage(content::WebContents* web_contents) override; + void MoveValidationMessage(content::WebContents* web_contents, + const gfx::Rect& anchor_in_root_view) override; protected: base::android::ScopedJavaLocalRef<jobject> GetJavaDelegate(JNIEnv* env) const;
diff --git a/components/wifi_sync/DEPS b/components/wifi_sync/DEPS index 441abe4..54fb2831 100644 --- a/components/wifi_sync/DEPS +++ b/components/wifi_sync/DEPS
@@ -5,6 +5,7 @@ "+components/keyed_service/content", "+components/keyed_service/core", "+components/onc", + "+content/public/browser", "+sync/api", "+sync/internal_api/public/attachments", "+sync/protocol",
diff --git a/components/wifi_sync/wifi_credential_syncable_service_factory.cc b/components/wifi_sync/wifi_credential_syncable_service_factory.cc index cf3b460..708336e 100644 --- a/components/wifi_sync/wifi_credential_syncable_service_factory.cc +++ b/components/wifi_sync/wifi_credential_syncable_service_factory.cc
@@ -4,12 +4,17 @@ #include "components/wifi_sync/wifi_credential_syncable_service_factory.h" +#include <string> + #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/wifi_sync/wifi_config_delegate.h" #include "components/wifi_sync/wifi_credential_syncable_service.h" +#include "content/public/browser/browser_context.h" #if defined(OS_CHROMEOS) +#include "base/files/file_path.h" #include "chromeos/login/login_state.h" #include "chromeos/network/network_handler.h" #include "components/wifi_sync/wifi_config_delegate_chromeos.h" @@ -19,26 +24,28 @@ namespace { -scoped_ptr<WifiConfigDelegate> BuildConfigDelegate( - content::BrowserContext* context) { #if defined(OS_CHROMEOS) - const chromeos::LoginState* login_state = chromeos::LoginState::Get(); - DCHECK(login_state->IsUserLoggedIn()); - DCHECK(!login_state->primary_user_hash().empty()); - // TODO(quiche): Verify that |context| is the primary user's context. - - // Note: NetworkHandler is a singleton that is managed by - // ChromeBrowserMainPartsChromeos, and destroyed after all - // KeyedService instances are destroyed. - chromeos::NetworkHandler* network_handler = chromeos::NetworkHandler::Get(); - return make_scoped_ptr(new WifiConfigDelegateChromeOs( - login_state->primary_user_hash(), - network_handler->managed_network_configuration_handler())); -#else - NOTREACHED(); - return nullptr; -#endif +// Returns a string identifying a ChromeOS network settings profile, +// by that profile's UserHash property. This value may be communicated +// to the ChromeOS connection manager ("Shill"), but must not be +// exposed to any untrusted code (e.g., via web APIs). +std::string GetUserHash(content::BrowserContext* context, + bool use_login_state) { + if (use_login_state) { + const chromeos::LoginState* login_state = chromeos::LoginState::Get(); + DCHECK(login_state->IsUserLoggedIn()); + DCHECK(!login_state->primary_user_hash().empty()); + // TODO(quiche): Verify that |context| is the primary user's context. + return login_state->primary_user_hash(); + } else { + // In WiFi credential sync tests, LoginState is not + // available. Instead, those tests set their Shill profiles' + // UserHashes based on the corresponding BrowserContexts' storage + // paths. + return context->GetPath().BaseName().value(); + } } +#endif } // namespace @@ -71,7 +78,27 @@ content::BrowserContext* context) const { // TODO(quiche): Figure out if this behaves properly for multi-profile. // crbug.com/430681. - return new WifiCredentialSyncableService(BuildConfigDelegate(context)); +#if defined(OS_CHROMEOS) + return new WifiCredentialSyncableService( + BuildWifiConfigDelegateChromeOs(context)); +#else + NOTREACHED(); + return nullptr; +#endif } +#if defined(OS_CHROMEOS) +scoped_ptr<WifiConfigDelegate> +WifiCredentialSyncableServiceFactory::BuildWifiConfigDelegateChromeOs( + content::BrowserContext* context) const { + // Note: NetworkHandler is a singleton that is managed by + // ChromeBrowserMainPartsChromeos, and destroyed after all + // KeyedService instances are destroyed. + chromeos::NetworkHandler* network_handler = chromeos::NetworkHandler::Get(); + return make_scoped_ptr(new WifiConfigDelegateChromeOs( + GetUserHash(context, !ignore_login_state_for_test_), + network_handler->managed_network_configuration_handler())); +} +#endif + } // namespace wifi_sync
diff --git a/components/wifi_sync/wifi_credential_syncable_service_factory.h b/components/wifi_sync/wifi_credential_syncable_service_factory.h index be1dae5..be5b6c50 100644 --- a/components/wifi_sync/wifi_credential_syncable_service_factory.h +++ b/components/wifi_sync/wifi_credential_syncable_service_factory.h
@@ -6,6 +6,7 @@ #define COMPONENTS_WIFI_SYNC_WIFI_CREDENTIAL_SYNCABLE_SERVICE_FACTORY_H_ #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" @@ -15,6 +16,7 @@ namespace wifi_sync { +class WifiConfigDelegate; class WifiCredentialSyncableService; // Singleton that owns all WifiCredentialSyncableServices and @@ -29,12 +31,15 @@ static WifiCredentialSyncableService* GetForBrowserContext( content::BrowserContext* browser_context); - // Returns the singleton instance. As this class has no public - // instance methods, this function is not generally useful for - // external callers. This function is public only so that the - // Singleton template can reference it. + // Returns the singleton instance. static WifiCredentialSyncableServiceFactory* GetInstance(); +#if defined(OS_CHROMEOS) + void set_ignore_login_state_for_test(bool new_value) { + ignore_login_state_for_test_ = new_value; + } +#endif + private: friend struct DefaultSingletonTraits<WifiCredentialSyncableServiceFactory>; @@ -45,6 +50,22 @@ KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override; +#if defined(OS_CHROMEOS) + // Returns a scoped pointer to a WifiConfigDelegate, which can be + // used to configure the ChromeOS Wi-Fi settings associated with + // |context|. + scoped_ptr<WifiConfigDelegate> BuildWifiConfigDelegateChromeOs( + content::BrowserContext* context) const; +#endif + +#if defined(OS_CHROMEOS) + // Whether or not we should use LoginState to associate a new + // SyncableService with a Shill profile. Should be set to true in + // sync integration tests, where it is not possible to control + // LoginState at the time SyncableServices are constructed. + bool ignore_login_state_for_test_ = false; +#endif + DISALLOW_COPY_AND_ASSIGN(WifiCredentialSyncableServiceFactory); };
diff --git a/content/app/android/child_process_service.cc b/content/app/android/child_process_service.cc index 93c622ef..b25a779 100644 --- a/content/app/android/child_process_service.cc +++ b/content/app/android/child_process_service.cc
@@ -44,16 +44,15 @@ SurfaceTexturePeer::InitInstance(this); GpuSurfaceLookup::InitInstance(this); } - virtual ~SurfaceTextureManagerImpl() { + ~SurfaceTextureManagerImpl() override { SurfaceTexturePeer::InitInstance(NULL); GpuSurfaceLookup::InitInstance(NULL); } // Overridden from SurfaceTextureManager: - virtual void RegisterSurfaceTexture( - int surface_texture_id, - int client_id, - gfx::SurfaceTexture* surface_texture) override { + void RegisterSurfaceTexture(int surface_texture_id, + int client_id, + gfx::SurfaceTexture* surface_texture) override { JNIEnv* env = base::android::AttachCurrentThread(); Java_ChildProcessService_createSurfaceTextureSurface( env, @@ -62,13 +61,13 @@ client_id, surface_texture->j_surface_texture().obj()); } - virtual void UnregisterSurfaceTexture(int surface_texture_id, - int client_id) override { + void UnregisterSurfaceTexture(int surface_texture_id, + int client_id) override { JNIEnv* env = base::android::AttachCurrentThread(); Java_ChildProcessService_destroySurfaceTextureSurface( env, service_.obj(), surface_texture_id, client_id); } - virtual gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( + gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( int surface_texture_id) override { JNIEnv* env = base::android::AttachCurrentThread(); gfx::ScopedJavaSurface surface( @@ -89,7 +88,7 @@ } // Overridden from SurfaceTexturePeer: - virtual void EstablishSurfaceTexturePeer( + void EstablishSurfaceTexturePeer( base::ProcessHandle pid, scoped_refptr<gfx::SurfaceTexture> surface_texture, int primary_id, @@ -105,7 +104,7 @@ } // Overridden from GpuSurfaceLookup: - virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) override { + gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) override { JNIEnv* env = base::android::AttachCurrentThread(); gfx::ScopedJavaSurface surface( content::Java_ChildProcessService_getViewSurface(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 8bebd15d..b715d248 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -40,6 +40,7 @@ "//ui/accessibility", "//ui/accessibility:ax_gen", "//ui/base", + "//ui/base/ime", "//ui/events", "//ui/events:gesture_detection", "//ui/gfx",
diff --git a/content/browser/DEPS b/content/browser/DEPS index ed55e7b..e864145e 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -51,8 +51,6 @@ "+third_party/WebKit/public/platform/WebIDBTypes.h", "+third_party/WebKit/public/platform/WebReferrerPolicy.h", "+third_party/WebKit/public/platform/WebLockOrientationError.h", - "+third_party/WebKit/public/platform/WebNotificationPermission.h", - "+third_party/WebKit/public/platform/WebPushPermissionStatus.h", "+third_party/WebKit/public/platform/WebScreenOrientationLockType.h", "+third_party/WebKit/public/platform/WebScreenOrientationType.h", "+third_party/WebKit/public/platform/WebScreenInfo.h", @@ -62,6 +60,8 @@ "+third_party/WebKit/public/platform/WebServiceWorkerResponseType.h", "+third_party/WebKit/public/platform/WebServiceWorkerState.h", "+third_party/WebKit/public/platform/WebString.h", + "+third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h", + "+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h", "+third_party/WebKit/public/web/mac/WebScrollbarTheme.h", "+third_party/WebKit/public/web/WebAXEnums.h", "+third_party/WebKit/public/web/WebCompositionUnderline.h", @@ -72,7 +72,6 @@ "+third_party/WebKit/public/web/WebFindOptions.h", "+third_party/WebKit/public/web/WebInputEvent.h", "+third_party/WebKit/public/web/WebMediaPlayerAction.h", - "+third_party/WebKit/public/web/WebNotificationPresenter.h", "+third_party/WebKit/public/web/WebPageSerializerClient.h", "+third_party/WebKit/public/web/WebPluginAction.h", "+third_party/WebKit/public/web/WebPopupType.h",
diff --git a/content/browser/accessibility/accessibility_event_recorder_win.cc b/content/browser/accessibility/accessibility_event_recorder_win.cc index 2425b03..8bbc890e 100644 --- a/content/browser/accessibility/accessibility_event_recorder_win.cc +++ b/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -95,6 +95,11 @@ DWORD event_thread, DWORD event_time); + // Wrapper around AccessibleObjectFromWindow because the function call + // inexplicably flakes sometimes on build/trybots. + HRESULT AccessibleObjectFromWindowWrapper( + HWND hwnd, DWORD dwId, REFIID riid, void **ppvObject); + HWINEVENTHOOK win_event_hook_handle_; static AccessibilityEventRecorderWin* instance_; }; @@ -138,7 +143,6 @@ GetCurrentProcessId(), 0, // Hook all threads WINEVENT_INCONTEXT); - LOG(INFO) << "SetWinEventHook handle: " << win_event_hook_handle_; CHECK(win_event_hook_handle_); } @@ -155,18 +159,8 @@ LONG child_id, DWORD event_thread, DWORD event_time) { - // http://crbug.com/440579 TODO(dmazzoni): remove most logging in this file, - // or change to VLOG(1), once flakiness on CrWinClang testers is fixed. - LOG(INFO) << "OnWinEventHook handle=" << handle - << " event=" << event - << " hwnd=" << hwnd - << " obj_id=" << obj_id - << " child_id=" << child_id - << " event_thread=" << event_thread - << " event_time=" << event_time; - base::win::ScopedComPtr<IAccessible> browser_accessible; - HRESULT hr = AccessibleObjectFromWindow( + HRESULT hr = AccessibleObjectFromWindowWrapper( hwnd, obj_id, IID_IAccessible, @@ -175,10 +169,7 @@ // Note: our event hook will pick up some superfluous events we // don't care about, so it's safe to just ignore these failures. // Same below for other HRESULT checks. - LOG(INFO) << "Ignoring result " << hr << " from AccessibleObjectFromWindow"; - TCHAR name[MAX_PATH]; - GetClassName(hwnd, name, _countof(name)); - LOG(INFO) << "Hwnd " << hwnd << " class is " << name; + VLOG(1) << "Ignoring result " << hr << " from AccessibleObjectFromWindow"; return; } @@ -186,21 +177,21 @@ base::win::ScopedComPtr<IDispatch> dispatch; hr = browser_accessible->get_accChild(childid_variant, dispatch.Receive()); if (!SUCCEEDED(hr) || !dispatch) { - LOG(INFO) << "Ignoring result " << hr << " and result " << dispatch - << " from get_accChild"; + VLOG(1) << "Ignoring result " << hr << " and result " << dispatch + << " from get_accChild"; return; } base::win::ScopedComPtr<IAccessible> iaccessible; hr = dispatch.QueryInterface(iaccessible.Receive()); if (!SUCCEEDED(hr)) { - LOG(INFO) << "Ignoring result " << hr << " from QueryInterface"; + VLOG(1) << "Ignoring result " << hr << " from QueryInterface"; return; } std::string event_str = AccessibilityEventToStringUTF8(event); if (event_str.empty()) { - LOG(INFO) << "Ignoring event " << event; + VLOG(1) << "Ignoring event " << event; return; } @@ -244,9 +235,27 @@ } } - LOG(INFO) << "Got event log: " << log; - event_logs_.push_back(log); } +HRESULT AccessibilityEventRecorderWin::AccessibleObjectFromWindowWrapper( + HWND hwnd, DWORD dw_id, REFIID riid, void** ppv_object) { + HRESULT hr = ::AccessibleObjectFromWindow(hwnd, dw_id, riid, ppv_object); + if (SUCCEEDED(hr)) + return hr; + + // The above call to ::AccessibleObjectFromWindow fails for unknown + // reasons every once in a while on the bots. Work around it by grabbing + // the object directly from the BrowserAccessibilityManager. + HWND accessibility_hwnd = + manager_->delegate()->AccessibilityGetAcceleratedWidget(); + if (accessibility_hwnd != hwnd) + return E_FAIL; + + IAccessible* obj = manager_->GetRoot()->ToBrowserAccessibilityWin(); + obj->AddRef(); + *ppv_object = obj; + return S_OK; +} + } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 6049901..34a82257 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -79,6 +79,7 @@ factory_(factory), tree_(new ui::AXSerializableTree()), focus_(NULL), + user_is_navigating_away_(false), osk_state_(OSK_ALLOWED) { tree_->SetDelegate(this); } @@ -91,6 +92,7 @@ factory_(factory), tree_(new ui::AXSerializableTree()), focus_(NULL), + user_is_navigating_away_(false), osk_state_(OSK_ALLOWED) { tree_->SetDelegate(this); Initialize(initial_tree); @@ -152,6 +154,22 @@ NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetFromAXNode(focus_)); } +void BrowserAccessibilityManager::UserIsNavigatingAway() { + user_is_navigating_away_ = true; +} + +void BrowserAccessibilityManager::UserIsReloading() { + user_is_navigating_away_ = true; +} + +void BrowserAccessibilityManager::NavigationSucceeded() { + user_is_navigating_away_ = false; +} + +void BrowserAccessibilityManager::NavigationFailed() { + user_is_navigating_away_ = false; +} + void BrowserAccessibilityManager::GotMouseDown() { osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT; NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index e59a1ed..f60bd02 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -146,6 +146,12 @@ // view lost focus. virtual void OnWindowBlurred(); + // Notify the accessibility manager about page navigation. + void UserIsNavigatingAway(); + virtual void UserIsReloading(); + void NavigationSucceeded(); + void NavigationFailed(); + // Called to notify the accessibility manager that a mouse down event // occurred in the tab. void GotMouseDown(); @@ -304,6 +310,9 @@ // A mapping from a node id to its wrapper of type BrowserAccessibility. base::hash_map<int32, BrowserAccessibility*> id_wrapper_map_; + // True if the user has initiated a navigation to another page. + bool user_is_navigating_away_; + // The on-screen keyboard state. OnScreenKeyboardState osk_state_;
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index ae4f089..79d9361 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -179,6 +179,10 @@ BrowserAccessibilityManager::OnWindowFocused(); } +void BrowserAccessibilityManagerWin::UserIsReloading() { + MaybeCallNotifyWinEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot()); +} + void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( ui::AXEvent event_type, BrowserAccessibility* node) { @@ -188,6 +192,11 @@ return; } + // Don't fire events when this document might be stale as the user has + // started navigating to a new document. + if (user_is_navigating_away_) + return; + // Inline text boxes are an internal implementation detail, we don't // expose them to Windows. if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index 7f0039e..24c0b77e 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -41,8 +41,9 @@ virtual void OnNodeCreated(ui::AXNode* node) override; // BrowserAccessibilityManager methods - virtual void OnWindowFocused() override; - virtual void NotifyAccessibilityEvent( + void OnWindowFocused() override; + void UserIsReloading() override; + void NotifyAccessibilityEvent( ui::AXEvent event_type, BrowserAccessibility* node) override; // Track this object and post a VISIBLE_DATA_CHANGED notification when
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 6f83a6f..928f9074 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -745,8 +745,9 @@ RunHtmlTest(FILE_PATH_LITERAL("iframe.html")); } +// Flaky. See http://crbug.com/224659. IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, - AccessibilityIframeCoordinates) { + DISABLED_AccessibilityIframeCoordinates) { RunHtmlTest(FILE_PATH_LITERAL("iframe-coordinates.html")); }
diff --git a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc index 1893e0d8..bf9c189 100644 --- a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc +++ b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -77,13 +77,10 @@ GURL http_url(test_server()->GetURL("files/title1.html")); NavigateFrameToURL(child, http_url); - // These must stay in scope with replace_host. - GURL::Replacements replace_host; - std::string foo_com("foo.com"); - // Load cross-site page into iframe. + GURL::Replacements replace_host; GURL cross_site_url(test_server()->GetURL("files/title2.html")); - replace_host.SetHostStr(foo_com); + replace_host.SetHostStr("foo.com"); cross_site_url = cross_site_url.ReplaceComponents(replace_host); NavigateFrameToURL(root->child_at(0), cross_site_url);
diff --git a/content/browser/android/browser_surface_texture_manager.h b/content/browser/android/browser_surface_texture_manager.h index 7776d30e..959d2705 100644 --- a/content/browser/android/browser_surface_texture_manager.h +++ b/content/browser/android/browser_surface_texture_manager.h
@@ -15,20 +15,18 @@ public SurfaceTexturePeer { public: BrowserSurfaceTextureManager(); - virtual ~BrowserSurfaceTextureManager(); + ~BrowserSurfaceTextureManager() override; // Overridden from SurfaceTextureManager: - virtual void RegisterSurfaceTexture( - int surface_texture_id, - int client_id, - gfx::SurfaceTexture* surface_texture) override; - virtual void UnregisterSurfaceTexture(int surface_texture_id, - int client_id) override; - virtual gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( + void RegisterSurfaceTexture(int surface_texture_id, + int client_id, + gfx::SurfaceTexture* surface_texture) override; + void UnregisterSurfaceTexture(int surface_texture_id, int client_id) override; + gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( int surface_texture_id) override; // Overridden from SurfaceTexturePeer: - virtual void EstablishSurfaceTexturePeer( + void EstablishSurfaceTexturePeer( base::ProcessHandle render_process_handle, scoped_refptr<gfx::SurfaceTexture> surface_texture, int render_frame_id,
diff --git a/content/browser/android/composited_touch_handle_drawable.h b/content/browser/android/composited_touch_handle_drawable.h index 849f7b5..28c6910 100644 --- a/content/browser/android/composited_touch_handle_drawable.h +++ b/content/browser/android/composited_touch_handle_drawable.h
@@ -18,14 +18,14 @@ CompositedTouchHandleDrawable(cc::Layer* root_layer, float dpi_scale, jobject context); - virtual ~CompositedTouchHandleDrawable(); + ~CompositedTouchHandleDrawable() override; // ui::TouchHandleDrawable implementation. - virtual void SetEnabled(bool enabled) override; - virtual void SetOrientation(ui::TouchHandleOrientation orientation) override; - virtual void SetAlpha(float alpha) override; - virtual void SetFocus(const gfx::PointF& position) override; - virtual gfx::RectF GetVisibleBounds() const override; + void SetEnabled(bool enabled) override; + void SetOrientation(ui::TouchHandleOrientation orientation) override; + void SetAlpha(float alpha) override; + void SetFocus(const gfx::PointF& position) override; + gfx::RectF GetVisibleBounds() const override; static bool RegisterHandleViewResources(JNIEnv* env);
diff --git a/content/browser/android/content_settings.h b/content/browser/android/content_settings.h index 79dd1da..bbf492b 100644 --- a/content/browser/android/content_settings.h +++ b/content/browser/android/content_settings.h
@@ -23,10 +23,10 @@ private: // Self-deletes when the underlying WebContents is destroyed. - virtual ~ContentSettings(); + ~ContentSettings() override; // WebContentsObserver overrides: - virtual void WebContentsDestroyed() override; + void WebContentsDestroyed() override; // The Java counterpart to this class. JavaObjectWeakGlobalRef content_settings_;
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 5fd29f12..4cbc111 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc
@@ -171,7 +171,7 @@ : content_view_core_(content_view_core) { } - virtual ~ContentViewUserData() { + ~ContentViewUserData() override { // TODO(joth): When chrome has finished removing the TabContents class (see // crbug.com/107201) consider inverting relationship, so ContentViewCore // would own WebContents. That effectively implies making the WebContents
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 053e0e7..691a659 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h
@@ -47,20 +47,20 @@ jobject java_bridge_retained_object_set); // ContentViewCore implementation. - virtual base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; - virtual WebContents* GetWebContents() const override; - virtual ui::ViewAndroid* GetViewAndroid() const override; - virtual ui::WindowAndroid* GetWindowAndroid() const override; - virtual const scoped_refptr<cc::Layer>& GetLayer() const override; - virtual void ShowPastePopup(int x, int y) override; - virtual void GetScaledContentBitmap( + base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; + WebContents* GetWebContents() const override; + ui::ViewAndroid* GetViewAndroid() const override; + ui::WindowAndroid* GetWindowAndroid() const override; + const scoped_refptr<cc::Layer>& GetLayer() const override; + void ShowPastePopup(int x, int y) override; + void GetScaledContentBitmap( float scale, SkColorType color_type, gfx::Rect src_subrect, ReadbackRequestCallback& result_callback) override; - virtual float GetDpiScale() const override; - virtual void PauseOrResumeGeolocation(bool should_pause) override; - virtual void RequestTextSurroundingSelection( + float GetDpiScale() const override; + void PauseOrResumeGeolocation(bool should_pause) override; + void RequestTextSurroundingSelection( int max_length, const base::Callback<void(const base::string16& content, int start_offset, @@ -285,13 +285,13 @@ class ContentViewUserData; friend class ContentViewUserData; - virtual ~ContentViewCoreImpl(); + ~ContentViewCoreImpl() override; // WebContentsObserver implementation. - virtual void RenderViewReady() override; - virtual void RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host) override; - virtual void WebContentsDestroyed() override; + void RenderViewReady() override; + void RenderViewHostChanged(RenderViewHost* old_host, + RenderViewHost* new_host) override; + void WebContentsDestroyed() override; // -------------------------------------------------------------------------- // Other private methods and data
diff --git a/content/browser/android/content_view_render_view.h b/content/browser/android/content_view_render_view.h index 0b09b38..c79936d 100644 --- a/content/browser/android/content_view_render_view.h +++ b/content/browser/android/content_view_render_view.h
@@ -47,11 +47,11 @@ jlong GetUIResourceProvider(JNIEnv* env, jobject obj); // CompositorClient implementation - virtual void Layout() override; - virtual void OnSwapBuffersCompleted(int pending_swap_buffers) override; + void Layout() override; + void OnSwapBuffersCompleted(int pending_swap_buffers) override; private: - virtual ~ContentViewRenderView(); + ~ContentViewRenderView() override; void InitCompositor();
diff --git a/content/browser/android/content_view_statics.cc b/content/browser/android/content_view_statics.cc index 1c4e903..e0f26a0 100644 --- a/content/browser/android/content_view_statics.cc +++ b/content/browser/android/content_view_statics.cc
@@ -40,14 +40,13 @@ // If the process crashes, stop watching the corresponding RenderProcessHost // and ensure it doesn't get over-resumed. - virtual void RenderProcessExited(content::RenderProcessHost* host, - base::TerminationStatus status, - int exit_code) override { + void RenderProcessExited(content::RenderProcessHost* host, + base::TerminationStatus status, + int exit_code) override { StopWatching(host); } - virtual void RenderProcessHostDestroyed( - content::RenderProcessHost* host) override { + void RenderProcessHostDestroyed(content::RenderProcessHost* host) override { StopWatching(host); }
diff --git a/content/browser/android/download_controller_android_impl.h b/content/browser/android/download_controller_android_impl.h index 7bc71bf7..227ff5f 100644 --- a/content/browser/android/download_controller_android_impl.h +++ b/content/browser/android/download_controller_android_impl.h
@@ -73,20 +73,22 @@ struct JavaObject; friend struct DefaultSingletonTraits<DownloadControllerAndroidImpl>; DownloadControllerAndroidImpl(); - virtual ~DownloadControllerAndroidImpl(); + ~DownloadControllerAndroidImpl() override; // DownloadControllerAndroid implementation. - virtual void CreateGETDownload(int render_process_id, int render_view_id, - int request_id) override; - virtual void OnDownloadStarted(DownloadItem* download_item) override; - virtual void StartContextMenuDownload( - const ContextMenuParams& params, WebContents* web_contents, - bool is_link) override; - virtual void DangerousDownloadValidated( - WebContents* web_contents, int download_id, bool accept) override; + void CreateGETDownload(int render_process_id, + int render_view_id, + int request_id) override; + void OnDownloadStarted(DownloadItem* download_item) override; + void StartContextMenuDownload(const ContextMenuParams& params, + WebContents* web_contents, + bool is_link) override; + void DangerousDownloadValidated(WebContents* web_contents, + int download_id, + bool accept) override; // DownloadItem::Observer interface. - virtual void OnDownloadUpdated(DownloadItem* item) override; + void OnDownloadUpdated(DownloadItem* item) override; typedef base::Callback<void(const DownloadInfoAndroid&)> GetDownloadInfoCB;
diff --git a/content/browser/android/edge_effect.h b/content/browser/android/edge_effect.h index 7b0e2e4..888c28e 100644 --- a/content/browser/android/edge_effect.h +++ b/content/browser/android/edge_effect.h
@@ -26,21 +26,21 @@ public: explicit EdgeEffect(ui::ResourceManager* resource_manager, float device_scale_factor); - virtual ~EdgeEffect(); + ~EdgeEffect() override; - virtual void Pull(base::TimeTicks current_time, - float delta_distance, - float displacement) override; - virtual void Absorb(base::TimeTicks current_time, float velocity) override; - virtual bool Update(base::TimeTicks current_time) override; - virtual void Release(base::TimeTicks current_time) override; + void Pull(base::TimeTicks current_time, + float delta_distance, + float displacement) override; + void Absorb(base::TimeTicks current_time, float velocity) override; + bool Update(base::TimeTicks current_time) override; + void Release(base::TimeTicks current_time) override; - virtual void Finish() override; - virtual bool IsFinished() const override; + void Finish() override; + bool IsFinished() const override; - virtual void ApplyToLayers(const gfx::SizeF& size, - const gfx::Transform& transform) override; - virtual void SetParent(cc::Layer* parent) override; + void ApplyToLayers(const gfx::SizeF& size, + const gfx::Transform& transform) override; + void SetParent(cc::Layer* parent) override; // Thread-safe trigger to load resources. static void PreloadResources(ui::ResourceManager* resource_manager);
diff --git a/content/browser/android/edge_effect_l.h b/content/browser/android/edge_effect_l.h index 00064c2..4cf6d1f1 100644 --- a/content/browser/android/edge_effect_l.h +++ b/content/browser/android/edge_effect_l.h
@@ -29,21 +29,21 @@ class EdgeEffectL : public EdgeEffectBase { public: explicit EdgeEffectL(ui::ResourceManager* resource_manager); - virtual ~EdgeEffectL(); + ~EdgeEffectL() override; - virtual void Pull(base::TimeTicks current_time, - float delta_distance, - float displacement) override; - virtual void Absorb(base::TimeTicks current_time, float velocity) override; - virtual bool Update(base::TimeTicks current_time) override; - virtual void Release(base::TimeTicks current_time) override; + void Pull(base::TimeTicks current_time, + float delta_distance, + float displacement) override; + void Absorb(base::TimeTicks current_time, float velocity) override; + bool Update(base::TimeTicks current_time) override; + void Release(base::TimeTicks current_time) override; - virtual void Finish() override; - virtual bool IsFinished() const override; + void Finish() override; + bool IsFinished() const override; - virtual void ApplyToLayers(const gfx::SizeF& size, - const gfx::Transform& transform) override; - virtual void SetParent(cc::Layer* parent) override; + void ApplyToLayers(const gfx::SizeF& size, + const gfx::Transform& transform) override; + void SetParent(cc::Layer* parent) override; // Thread-safe trigger to load resources. static void PreloadResources(ui::ResourceManager* resource_manager);
diff --git a/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h b/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h index dd62360f..1d8935e 100644 --- a/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h +++ b/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h
@@ -18,7 +18,7 @@ : public cc::BeginFrameSourceMixIn { public: explicit SynchronousCompositorExternalBeginFrameSource(int routing_id); - virtual ~SynchronousCompositorExternalBeginFrameSource(); + ~SynchronousCompositorExternalBeginFrameSource() override; void BeginFrame();
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc index e3148ec..1e779ce6 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -4,6 +4,7 @@ #include "content/browser/android/in_process/synchronous_compositor_factory_impl.h" +#include "base/command_line.h" #include "base/observer_list.h" #include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h" #include "content/browser/android/in_process/synchronous_compositor_impl.h" @@ -13,6 +14,7 @@ #include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h" #include "gpu/command_buffer/client/gl_in_process_context.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "ui/gl/android/surface_texture.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_surface_stub.h" @@ -64,7 +66,8 @@ scoped_ptr<gpu::GLInProcessContext> CreateContext( scoped_refptr<gpu::InProcessCommandBuffer::Service> service, - const gpu::GLInProcessContextSharedMemoryLimits& mem_limits) { + const gpu::GLInProcessContextSharedMemoryLimits& mem_limits, + bool is_offscreen) { const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; gpu::gles2::ContextCreationAttribHelper in_process_attribs; WebGraphicsContext3DImpl::ConvertAttributes( @@ -74,7 +77,7 @@ scoped_ptr<gpu::GLInProcessContext> context(gpu::GLInProcessContext::Create( service, NULL /* surface */, - false /* is_offscreen */, + is_offscreen, gfx::kNullAcceleratedWidget, gfx::Size(1, 1), NULL /* share_context */, @@ -124,21 +127,20 @@ context_provider_->BindToCurrentThread(); } - virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( + scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( uint32 stream_id) override { return gl_in_process_context_->GetSurfaceTexture(stream_id); } - virtual gpu::gles2::GLES2Interface* ContextGL() override { + gpu::gles2::GLES2Interface* ContextGL() override { return context_provider_->ContextGL(); } - virtual void AddObserver(StreamTextureFactoryContextObserver* obs) override { + void AddObserver(StreamTextureFactoryContextObserver* obs) override { observer_list_.AddObserver(obs); } - virtual void RemoveObserver( - StreamTextureFactoryContextObserver* obs) override { + void RemoveObserver(StreamTextureFactoryContextObserver* obs) override { observer_list_.RemoveObserver(obs); } @@ -150,7 +152,7 @@ private: friend class base::RefCountedThreadSafe<VideoContextProvider>; - virtual ~VideoContextProvider() {} + ~VideoContextProvider() override {} scoped_refptr<cc::ContextProvider> context_provider_; gpu::GLInProcessContext* gl_in_process_context_; @@ -219,7 +221,7 @@ // pipeline is only one frame deep. mem_limits.mapped_memory_reclaim_limit = 6 * 1024 * 1024; return webkit::gpu::ContextProviderInProcess::Create( - WrapContext(CreateContext(service_, mem_limits)), + WrapContext(CreateContext(nullptr, mem_limits, true)), "Child-Compositor"); } @@ -288,9 +290,10 @@ if (!video_context_provider_.get()) { DCHECK(service_.get()); - video_context_provider_ = new VideoContextProvider( - CreateContext(service_, - gpu::GLInProcessContextSharedMemoryLimits())); + // This needs to run in on-screen |service_| context due to SurfaceTexture + // limitations. + video_context_provider_ = new VideoContextProvider(CreateContext( + service_, gpu::GLInProcessContextSharedMemoryLimits(), false)); } return video_context_provider_; }
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h index 169381c..d141a7fc 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -25,28 +25,27 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { public: SynchronousCompositorFactoryImpl(); - virtual ~SynchronousCompositorFactoryImpl(); + ~SynchronousCompositorFactoryImpl() override; // SynchronousCompositorFactory - virtual scoped_refptr<base::MessageLoopProxy> GetCompositorMessageLoop() - override; - virtual bool RecordFullLayer() override; - virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( + scoped_refptr<base::MessageLoopProxy> GetCompositorMessageLoop() override; + bool RecordFullLayer() override; + scoped_ptr<cc::OutputSurface> CreateOutputSurface( int routing_id, scoped_refptr<content::FrameSwapMessageQueue> frame_swap_message_queue) override; - virtual InputHandlerManagerClient* GetInputHandlerManagerClient() override; - virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource( + InputHandlerManagerClient* GetInputHandlerManagerClient() override; + scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource( int routing_id) override; - virtual scoped_refptr<cc_blink::ContextProviderWebContext> + scoped_refptr<cc_blink::ContextProviderWebContext> CreateOffscreenContextProvider( const blink::WebGraphicsContext3D::Attributes& attributes, const std::string& debug_name) override; - virtual scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory( + scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory( int view_id) override; - virtual gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl* - CreateOffscreenGraphicsContext3D( - const blink::WebGraphicsContext3D::Attributes& attributes) override; + gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl* + CreateOffscreenGraphicsContext3D( + const blink::WebGraphicsContext3D::Attributes& attributes) override; SynchronousInputEventFilter* synchronous_input_event_filter() { return &synchronous_input_event_filter_;
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h index d42aeb8e..d6cacf0d 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -59,31 +59,29 @@ void NeedsBeginFramesChanged() const; // SynchronousCompositor - virtual bool InitializeHwDraw() override; - virtual void ReleaseHwDraw() override; - virtual scoped_ptr<cc::CompositorFrame> DemandDrawHw( + bool InitializeHwDraw() override; + void ReleaseHwDraw() override; + scoped_ptr<cc::CompositorFrame> DemandDrawHw( gfx::Size surface_size, const gfx::Transform& transform, gfx::Rect viewport, gfx::Rect clip, gfx::Rect viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority) override; - virtual bool DemandDrawSw(SkCanvas* canvas) override; - virtual void ReturnResources( - const cc::CompositorFrameAck& frame_ack) override; - virtual void SetMemoryPolicy(size_t bytes_limit) override; - virtual void DidChangeRootLayerScrollOffset() override; + bool DemandDrawSw(SkCanvas* canvas) override; + void ReturnResources(const cc::CompositorFrameAck& frame_ack) override; + void SetMemoryPolicy(size_t bytes_limit) override; + void DidChangeRootLayerScrollOffset() override; // LayerScrollOffsetDelegate - virtual gfx::ScrollOffset GetTotalScrollOffset() override; - virtual void UpdateRootLayerState( - const gfx::ScrollOffset& total_scroll_offset, - const gfx::ScrollOffset& max_scroll_offset, - const gfx::SizeF& scrollable_size, - float page_scale_factor, - float min_page_scale_factor, - float max_page_scale_factor) override; - virtual bool IsExternalFlingActive() const override; + gfx::ScrollOffset GetTotalScrollOffset() override; + void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset, + const gfx::ScrollOffset& max_scroll_offset, + const gfx::SizeF& scrollable_size, + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) override; + bool IsExternalFlingActive() const override; void SetInputHandler(cc::InputHandler* input_handler); void DidOverscroll(const DidOverscrollParams& params); @@ -93,7 +91,7 @@ friend class WebContentsUserData<SynchronousCompositorImpl>; friend class SynchronousCompositor; explicit SynchronousCompositorImpl(WebContents* contents); - virtual ~SynchronousCompositorImpl(); + ~SynchronousCompositorImpl() override; void SetClient(SynchronousCompositorClient* compositor_client); void UpdateFrameMetaData(const cc::CompositorFrameMetadata& frame_info);
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc index 5ccc91b7..149e1ea 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -38,11 +38,10 @@ SoftwareDevice(SynchronousCompositorOutputSurface* surface) : surface_(surface) { } - virtual void Resize(const gfx::Size& pixel_size, - float scale_factor) override { + void Resize(const gfx::Size& pixel_size, float scale_factor) override { // Intentional no-op: canvas size is controlled by the embedder. } - virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { if (!surface_->current_sw_canvas_) { NOTREACHED() << "BeginPaint with no canvas set"; return &null_canvas_; @@ -51,9 +50,8 @@ << "Mutliple calls to BeginPaint per frame"; return surface_->current_sw_canvas_; } - virtual void EndPaint(cc::SoftwareFrameData* frame_data) override { - } - virtual void CopyToPixels(const gfx::Rect& rect, void* pixels) override { + void EndPaint(cc::SoftwareFrameData* frame_data) override {} + void CopyToPixels(const gfx::Rect& rect, void* pixels) override { NOTIMPLEMENTED(); }
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h index 5262b7e..6e039124 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.h +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -50,12 +50,12 @@ explicit SynchronousCompositorOutputSurface( int routing_id, scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue); - virtual ~SynchronousCompositorOutputSurface(); + ~SynchronousCompositorOutputSurface() override; // OutputSurface. - virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) override; - virtual void Reshape(const gfx::Size& size, float scale_factor) override; - virtual void SwapBuffers(cc::CompositorFrame* frame) override; + bool BindToClient(cc::OutputSurfaceClient* surface_client) override; + void Reshape(const gfx::Size& size, float scale_factor) override; + void SwapBuffers(cc::CompositorFrame* frame) override; void SetBeginFrameSource( SynchronousCompositorExternalBeginFrameSource* begin_frame_source);
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.h b/content/browser/android/in_process/synchronous_input_event_filter.h index 8d420860..607b9a9 100644 --- a/content/browser/android/in_process/synchronous_input_event_filter.h +++ b/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -26,19 +26,19 @@ class SynchronousInputEventFilter : public InputHandlerManagerClient { public: SynchronousInputEventFilter(); - virtual ~SynchronousInputEventFilter(); + ~SynchronousInputEventFilter() override; InputEventAckState HandleInputEvent(int routing_id, const blink::WebInputEvent& input_event); // InputHandlerManagerClient implementation. - virtual void SetBoundHandler(const Handler& handler) override; - virtual void DidAddInputHandler(int routing_id, - cc::InputHandler* input_handler) override; - virtual void DidRemoveInputHandler(int routing_id) override; - virtual void DidOverscroll(int routing_id, - const DidOverscrollParams& params) override; - virtual void DidStopFlinging(int routing_id) override; + void SetBoundHandler(const Handler& handler) override; + void DidAddInputHandler(int routing_id, + cc::InputHandler* input_handler) override; + void DidRemoveInputHandler(int routing_id) override; + void DidOverscroll(int routing_id, + const DidOverscrollParams& params) override; + void DidStopFlinging(int routing_id) override; private: void SetBoundHandlerOnUIThread(const Handler& handler);
diff --git a/content/browser/android/interstitial_page_delegate_android.h b/content/browser/android/interstitial_page_delegate_android.h index 5121be1..bd28d38 100644 --- a/content/browser/android/interstitial_page_delegate_android.h +++ b/content/browser/android/interstitial_page_delegate_android.h
@@ -26,7 +26,7 @@ InterstitialPageDelegateAndroid(JNIEnv* env, jobject obj, const std::string& html_content); - virtual ~InterstitialPageDelegateAndroid(); + ~InterstitialPageDelegateAndroid() override; void set_interstitial_page(InterstitialPage* page) { page_ = page; } @@ -35,10 +35,10 @@ void DontProceed(JNIEnv* env, jobject obj); // Implementation of InterstitialPageDelegate - virtual std::string GetHTMLContents() override; - virtual void OnProceed() override; - virtual void OnDontProceed() override; - virtual void CommandReceived(const std::string& command) override; + std::string GetHTMLContents() override; + void OnProceed() override; + void OnDontProceed() override; + void CommandReceived(const std::string& command) override; static bool RegisterInterstitialPageDelegateAndroid(JNIEnv* env);
diff --git a/content/browser/android/java/gin_java_bound_object_delegate.h b/content/browser/android/java/gin_java_bound_object_delegate.h index 49ff4bb..cdee8a6 100644 --- a/content/browser/android/java/gin_java_bound_object_delegate.h +++ b/content/browser/android/java/gin_java_bound_object_delegate.h
@@ -15,17 +15,15 @@ : public GinJavaMethodInvocationHelper::ObjectDelegate { public: GinJavaBoundObjectDelegate(scoped_refptr<GinJavaBoundObject> object); - virtual ~GinJavaBoundObjectDelegate(); + ~GinJavaBoundObjectDelegate() override; - virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef( + base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) override; + base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef( JNIEnv* env) override; - virtual base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef( - JNIEnv* env) override; - virtual const JavaMethod* FindMethod(const std::string& method_name, - size_t num_parameters) override; - virtual bool IsObjectGetClassMethod(const JavaMethod* method) override; - virtual const base::android::JavaRef<jclass>& GetSafeAnnotationClass() - override; + const JavaMethod* FindMethod(const std::string& method_name, + size_t num_parameters) override; + bool IsObjectGetClassMethod(const JavaMethod* method) override; + const base::android::JavaRef<jclass>& GetSafeAnnotationClass() override; private: scoped_refptr<GinJavaBoundObject> object_;
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc index 93fc0c4..048fd5f 100644 --- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc +++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -38,9 +38,7 @@ JavaBridgeThread() : base::android::JavaHandlerThread("JavaBridge") { Start(); } - virtual ~JavaBridgeThread() { - Stop(); - } + ~JavaBridgeThread() override { Stop(); } static bool CurrentlyOn(); };
diff --git a/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc b/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc index ccd50835..fcda3cd 100644 --- a/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc +++ b/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
@@ -18,29 +18,27 @@ public: NullObjectDelegate() {} - virtual ~NullObjectDelegate() {} + ~NullObjectDelegate() override {} - virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef( - JNIEnv* env) override { + base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) override { return base::android::ScopedJavaLocalRef<jobject>(); } - virtual base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef( + base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef( JNIEnv* env) override { return base::android::ScopedJavaLocalRef<jclass>(); } - virtual const JavaMethod* FindMethod(const std::string& method_name, - size_t num_parameters) override { + const JavaMethod* FindMethod(const std::string& method_name, + size_t num_parameters) override { return NULL; } - virtual bool IsObjectGetClassMethod(const JavaMethod* method) override { + bool IsObjectGetClassMethod(const JavaMethod* method) override { return false; } - virtual const base::android::JavaRef<jclass>& GetSafeAnnotationClass() - override { + const base::android::JavaRef<jclass>& GetSafeAnnotationClass() override { return safe_annotation_class_; } @@ -55,9 +53,9 @@ public: NullDispatcherDelegate() {} - virtual ~NullDispatcherDelegate() {} + ~NullDispatcherDelegate() override {} - virtual JavaObjectWeakGlobalRef GetObjectWeakRef( + JavaObjectWeakGlobalRef GetObjectWeakRef( GinJavaBoundObject::ObjectID object_id) override { return JavaObjectWeakGlobalRef(); } @@ -77,9 +75,9 @@ public: CountingDispatcherDelegate() {} - virtual ~CountingDispatcherDelegate() {} + ~CountingDispatcherDelegate() override {} - virtual JavaObjectWeakGlobalRef GetObjectWeakRef( + JavaObjectWeakGlobalRef GetObjectWeakRef( GinJavaBoundObject::ObjectID object_id) override { counters_[object_id]++; return JavaObjectWeakGlobalRef(); @@ -176,16 +174,15 @@ method_.reset(new JavaMethod(method_obj)); } - virtual ~ObjectIsGoneObjectDelegate() {} + ~ObjectIsGoneObjectDelegate() override {} - virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef( - JNIEnv* env) override { + base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) override { get_local_ref_called_ = true; return NullObjectDelegate::GetLocalRef(env); } - virtual const JavaMethod* FindMethod(const std::string& method_name, - size_t num_parameters) override { + const JavaMethod* FindMethod(const std::string& method_name, + size_t num_parameters) override { return method_.get(); } @@ -230,16 +227,15 @@ public: MethodNotFoundObjectDelegate() : find_method_called_(false) {} - virtual ~MethodNotFoundObjectDelegate() {} + ~MethodNotFoundObjectDelegate() override {} - virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef( - JNIEnv* env) override { + base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) override { return base::android::ScopedJavaLocalRef<jobject>( env, static_cast<jobject>(env->FindClass("java/lang/String"))); } - virtual const JavaMethod* FindMethod(const std::string& method_name, - size_t num_parameters) override { + const JavaMethod* FindMethod(const std::string& method_name, + size_t num_parameters) override { find_method_called_ = true; return NULL; } @@ -282,15 +278,15 @@ public: GetClassObjectDelegate() : get_class_called_(false) {} - virtual ~GetClassObjectDelegate() {} + ~GetClassObjectDelegate() override {} - virtual const JavaMethod* FindMethod(const std::string& method_name, - size_t num_parameters) override { + const JavaMethod* FindMethod(const std::string& method_name, + size_t num_parameters) override { find_method_called_ = true; return kFakeGetClass; } - virtual bool IsObjectGetClassMethod(const JavaMethod* method) override { + bool IsObjectGetClassMethod(const JavaMethod* method) override { get_class_called_ = true; return kFakeGetClass == method; }
diff --git a/content/browser/android/java/jni_helper_unittest.cc b/content/browser/android/java/jni_helper_unittest.cc index 01b5ecf..d12f460 100644 --- a/content/browser/android/java/jni_helper_unittest.cc +++ b/content/browser/android/java/jni_helper_unittest.cc
@@ -38,7 +38,7 @@ class JNIAndroidTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { JNIEnv* env = base::android::AttachCurrentThread(); g_previous_functions = env->functions; hooked_functions = *g_previous_functions; @@ -46,7 +46,7 @@ hooked_functions.GetMethodID = &GetMethodIDWrapper; } - virtual void TearDown() { + void TearDown() override { JNIEnv* env = base::android::AttachCurrentThread(); env->functions = g_previous_functions; Reset();
diff --git a/content/browser/android/overscroll_controller_android.h b/content/browser/android/overscroll_controller_android.h index f50a15d..e7a5196 100644 --- a/content/browser/android/overscroll_controller_android.h +++ b/content/browser/android/overscroll_controller_android.h
@@ -39,7 +39,7 @@ OverscrollControllerAndroid(WebContents* web_contents, ui::WindowAndroidCompositor* compositor, float dpi_scale); - virtual ~OverscrollControllerAndroid(); + ~OverscrollControllerAndroid() override; // Returns true if |event| is consumed by an overscroll effect, in which // case it should cease propagation.
diff --git a/content/browser/android/popup_touch_handle_drawable.h b/content/browser/android/popup_touch_handle_drawable.h index e7f46ca7..5b5c334e 100644 --- a/content/browser/android/popup_touch_handle_drawable.h +++ b/content/browser/android/popup_touch_handle_drawable.h
@@ -16,14 +16,14 @@ public: PopupTouchHandleDrawable(base::android::ScopedJavaLocalRef<jobject> drawable, float dpi_scale); - virtual ~PopupTouchHandleDrawable(); + ~PopupTouchHandleDrawable() override; // ui::TouchHandleDrawable implementation. - virtual void SetEnabled(bool enabled) override; - virtual void SetOrientation(ui::TouchHandleOrientation orientation) override; - virtual void SetAlpha(float alpha) override; - virtual void SetFocus(const gfx::PointF& position) override; - virtual gfx::RectF GetVisibleBounds() const override; + void SetEnabled(bool enabled) override; + void SetOrientation(ui::TouchHandleOrientation orientation) override; + void SetAlpha(float alpha) override; + void SetFocus(const gfx::PointF& position) override; + gfx::RectF GetVisibleBounds() const override; static bool RegisterPopupTouchHandleDrawable(JNIEnv* env);
diff --git a/content/browser/android/web_contents_observer_android.h b/content/browser/android/web_contents_observer_android.h index 918443b..3f5d1110 100644 --- a/content/browser/android/web_contents_observer_android.h +++ b/content/browser/android/web_contents_observer_android.h
@@ -27,7 +27,7 @@ WebContentsObserverAndroid(JNIEnv* env, jobject obj, WebContents* web_contents); - virtual ~WebContentsObserverAndroid(); + ~WebContentsObserverAndroid() override; void Destroy(JNIEnv* env, jobject obj);
diff --git a/content/browser/appcache/appcache_url_request_job.cc b/content/browser/appcache/appcache_url_request_job.cc index e253f4a..6436c65 100644 --- a/content/browser/appcache/appcache_url_request_job.cc +++ b/content/browser/appcache/appcache_url_request_job.cc
@@ -382,6 +382,11 @@ } net::LoadState AppCacheURLRequestJob::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 AppCacheURLRequestJob::GetLoadState")); if (!has_been_started()) return net::LOAD_STATE_IDLE; if (!has_delivery_orders())
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 5e5df848..93cbcd3 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -119,7 +119,7 @@ #if defined(OS_POSIX) && !defined(OS_MACOSX) #include "content/browser/renderer_host/render_sandbox_host_linux.h" #include "content/browser/zygote_host/zygote_host_impl_linux.h" -#include "sandbox/linux/suid/client/setuid_sandbox_client.h" +#include "sandbox/linux/suid/client/setuid_sandbox_host.h" #endif #if defined(ENABLE_PLUGINS) @@ -148,20 +148,20 @@ TRACE_EVENT0("startup", "SetupSandbox"); base::FilePath sandbox_binary; - scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client( - sandbox::SetuidSandboxClient::Create()); + scoped_ptr<sandbox::SetuidSandboxHost> setuid_sandbox_host( + sandbox::SetuidSandboxHost::Create()); const bool want_setuid_sandbox = !parsed_command_line.HasSwitch(switches::kNoSandbox) && !parsed_command_line.HasSwitch(switches::kDisableSetuidSandbox) && - !setuid_sandbox_client->IsDisabledViaEnvironment(); + !setuid_sandbox_host->IsDisabledViaEnvironment(); static const char no_suid_error[] = "Running without the SUID sandbox! See " "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment " "for more information on developing with the sandbox on."; if (want_setuid_sandbox) { - sandbox_binary = setuid_sandbox_client->GetSandboxBinaryPath(); + sandbox_binary = setuid_sandbox_host->GetSandboxBinaryPath(); if (sandbox_binary.empty()) { // This needs to be fatal. Talk to security@chromium.org if you feel // otherwise. @@ -1077,8 +1077,7 @@ } #endif #elif defined(OS_ANDROID) - // TODO(crbug.com/439322): This should be set to |true|. - established_gpu_channel = false; + established_gpu_channel = true; BrowserGpuChannelHostFactory::Initialize(established_gpu_channel); #endif
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 661c1c5..176c4ba0 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -23,9 +23,16 @@ #if defined(OS_CHROMEOS) class MemoryPressureObserverChromeOS; #endif -namespace debug { +namespace trace_event { class TraceMemoryController; class TraceEventSystemStatsMonitor; +} // namespace trace_event + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TraceEventSystemStatsMonitor; +using ::base::trace_event::TraceMemoryController; } // namespace debug } // namespace base
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 8159b0d..5313268a 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -174,6 +174,12 @@ options)); } +bool BrowserPluginEmbedder::StopFinding(StopFindAction action) { + return GetBrowserPluginGuestManager()->ForEachGuest( + GetWebContents(), + base::Bind(&BrowserPluginEmbedder::StopFindingInGuest, action)); +} + // static bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool* mouse_unlocked, WebContents* guest) { @@ -200,4 +206,15 @@ return false; } +bool BrowserPluginEmbedder::StopFindingInGuest(StopFindAction action, + WebContents* guest) { + if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest() + ->StopFinding(action)) { + // There can only ever currently be one browser plugin that handles find so + // we can break the iteration at this point. + return true; + } + return false; +} + } // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h index e826982..b4cade6 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.h +++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -75,6 +75,7 @@ bool Find(int request_id, const base::string16& search_text, const blink::WebFindOptions& options); + bool StopFinding(StopFindAction action); private: explicit BrowserPluginEmbedder(WebContentsImpl* web_contents); @@ -92,6 +93,8 @@ const base::string16& search_text, const blink::WebFindOptions& options, WebContents* guest); + static bool StopFindingInGuest(StopFindAction action, WebContents* guest); + // Message handlers. void OnAttach(int instance_id, const BrowserPluginHostMsg_Attach_Params& params);
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 3c412a0..0950ee8 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -287,14 +287,6 @@ GetWebContents()->GetRenderViewHost()->GetWebkitPreferences(); prefs.navigate_on_drag_drop = false; GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs); - - // Enable input method for guest if it's enabled for the embedder. - if (static_cast<RenderViewHostImpl*>( - owner_web_contents_->GetRenderViewHost())->input_method_active()) { - RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( - GetWebContents()->GetRenderViewHost()); - guest_rvh->SetInputMethodActive(true); - } } BrowserPluginGuest::~BrowserPluginGuest() { @@ -384,6 +376,10 @@ return delegate_->Find(request_id, search_text, options); } +bool BrowserPluginGuest::StopFinding(StopFindAction action) { + return delegate_->StopFinding(action); +} + WebContentsImpl* BrowserPluginGuest::GetWebContents() const { return static_cast<WebContentsImpl*>(web_contents()); } @@ -640,6 +636,14 @@ has_render_view_ = true; + // Enable input method for guest if it's enabled for the embedder. + if (static_cast<RenderViewHostImpl*>( + owner_web_contents_->GetRenderViewHost())->input_method_active()) { + RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( + GetWebContents()->GetRenderViewHost()); + guest_rvh->SetInputMethodActive(true); + } + RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Attached")); }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index fd859e7..0352c3b 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -219,6 +219,7 @@ bool Find(int request_id, const base::string16& search_text, const blink::WebFindOptions& options); + bool StopFinding(StopFindAction action); private: class EmbedderVisibilityObserver;
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index cc42565..b9f65d5c 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -74,16 +74,7 @@ callback_factory_(this) { output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy( &output_surface_map_); -#if defined(OS_CHROMEOS) - bool use_thread = !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUIDisableThreadedCompositing); -#else - bool use_thread = false; -#endif - if (use_thread) { - compositor_thread_.reset(new base::Thread("Browser Compositor")); - compositor_thread_->Start(); - } + if (UseSurfacesEnabled()) surface_manager_ = make_scoped_ptr(new cc::SurfaceManager); } @@ -249,7 +240,7 @@ if (!context_provider.get()) { if (compositor_thread_.get()) { LOG(FATAL) << "Failed to create UI context, but can't use software" - " compositing with browser threaded compositing. Aborting."; + " compositing with browser threaded compositing. Aborting."; } scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface(
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc index c2d19b13..10b549b 100644 --- a/content/browser/compositor/reflector_impl.cc +++ b/content/browser/compositor/reflector_impl.cc
@@ -21,12 +21,16 @@ int surface_id) : impl_unsafe_(output_surface_map), main_unsafe_(mirrored_compositor, mirroring_layer), - impl_message_loop_(compositor_thread_loop), main_message_loop_(base::MessageLoopProxy::current()), surface_id_(surface_id) { GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper(); MainThreadData& main = GetMain(); main.mailbox = new OwnedMailbox(helper); + if (!compositor_thread_loop) { + impl_message_loop_ = main_message_loop_; + } else { + impl_message_loop_ = compositor_thread_loop; + } impl_message_loop_->PostTask( FROM_HERE, base::Bind(
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index 7483ae6..2ae28a6 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -94,10 +94,18 @@ mirroring_layer_.reset(new ui::Layer()); gfx::Size size = output_surface_->SurfaceSize(); mirroring_layer_->SetBounds(gfx::Rect(size.width(), size.height())); + } + void SetUpReflector(bool threaded) { int32 surface_id = 1; - reflector_ = new ReflectorImpl(compositor_.get(), mirroring_layer_.get(), - &surface_map_, proxy_.get(), surface_id); + + if (threaded) { + reflector_ = new ReflectorImpl(compositor_.get(), mirroring_layer_.get(), + &surface_map_, proxy_.get(), surface_id); + } else { + reflector_ = new ReflectorImpl(compositor_.get(), mirroring_layer_.get(), + &surface_map_, NULL, surface_id); + } } void TearDown() override { @@ -133,6 +141,8 @@ namespace { TEST_F(ReflectorImplTest, CheckNormalOutputSurface) { + bool threaded = true; + SetUpReflector(threaded); output_surface_->SetFlip(false); Init(); UpdateTexture(); @@ -144,6 +154,31 @@ } TEST_F(ReflectorImplTest, CheckInvertedOutputSurface) { + bool threaded = true; + SetUpReflector(threaded); + output_surface_->SetFlip(true); + Init(); + UpdateTexture(); + EXPECT_FALSE(mirroring_layer_->TextureFlipped()); + EXPECT_EQ(SkRegion(kSkSubRect), mirroring_layer_->damaged_region()); +} + +TEST_F(ReflectorImplTest, CheckNormalOutputSurface_SingleThread) { + bool threaded = false; + SetUpReflector(threaded); + output_surface_->SetFlip(false); + Init(); + UpdateTexture(); + EXPECT_TRUE(mirroring_layer_->TextureFlipped()); + EXPECT_EQ(SkRegion(SkIRect::MakeXYWH( + 0, output_surface_->SurfaceSize().height() - kSubRect.height(), + kSubRect.width(), kSubRect.height())), + mirroring_layer_->damaged_region()); +} + +TEST_F(ReflectorImplTest, CheckInvertedOutputSurface_SingleThread) { + bool threaded = false; + SetUpReflector(threaded); output_surface_->SetFlip(true); Init(); UpdateTexture();
diff --git a/content/browser/cross_site_transfer_browsertest.cc b/content/browser/cross_site_transfer_browsertest.cc index 67793e3f..3911545 100644 --- a/content/browser/cross_site_transfer_browsertest.cc +++ b/content/browser/cross_site_transfer_browsertest.cc
@@ -251,11 +251,6 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); - // These must all stay in scope with replace_host. - GURL::Replacements replace_host; - std::string a_com("A.com"); - std::string b_com("B.com"); - // Navigate to a starting URL, so there is a history entry to replace. GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); NavigateToURL(shell(), url1); @@ -269,8 +264,9 @@ // cross-site, so the renderer will send it to the browser via OpenURL to give // to a new process. It will then be transferred into yet another process due // to the call above. + GURL::Replacements replace_host; GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); - replace_host.SetHostStr(a_com); + replace_host.SetHostStr("A.com"); url2 = url2.ReplaceComponents(replace_host); // Used to make sure the request for url2 succeeds, and there was only one of // them. @@ -289,7 +285,7 @@ // replacement). This will still perform a double process-swap as above, via // OpenURL and then transfer. GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); - replace_host.SetHostStr(b_com); + replace_host.SetHostStr("B.com"); url3 = url3.ReplaceComponents(replace_host); // Used to make sure the request for url3 succeeds, and there was only one of // them. @@ -361,11 +357,6 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); - // These must all stay in scope with replace_host. - GURL::Replacements replace_host; - std::string a_com("A.com"); - std::string b_com("B.com"); - // Navigate to a starting URL, so there is a history entry to replace. GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); NavigateToURL(shell(), url1); @@ -375,12 +366,13 @@ // and second in response to the server redirect to B.com. The second swap is // also renderer-initiated via OpenURL because decidePolicyForNavigation is // currently applied on redirects. + GURL::Replacements replace_host; GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2"); - replace_host.SetHostStr(b_com); + replace_host.SetHostStr("B.com"); url2b = url2b.ReplaceComponents(replace_host); GURL url2a = test_server()->GetURL( "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false)); - replace_host.SetHostStr(a_com); + replace_host.SetHostStr("A.com"); url2a = url2a.ReplaceComponents(replace_host); NavigateToURLContentInitiated(shell(), url2a, true, true); @@ -392,11 +384,11 @@ // Now repeat without replacement. GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3"); - replace_host.SetHostStr(b_com); + replace_host.SetHostStr("B.com"); url3b = url3b.ReplaceComponents(replace_host); GURL url3a = test_server()->GetURL( "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false)); - replace_host.SetHostStr(a_com); + replace_host.SetHostStr("A.com"); url3a = url3a.ReplaceComponents(replace_host); NavigateToURLContentInitiated(shell(), url3a, false, true); @@ -417,11 +409,6 @@ host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(test_server()->Start()); - // These must all stay in scope with replace_host. - GURL::Replacements replace_host; - std::string a_com("A.com"); - std::string b_com("B.com"); - // Navigate to a starting URL, so there is a history entry to replace. GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); NavigateToURL(shell(), url1); @@ -437,8 +424,9 @@ // cross-site, so the renderer will send it to the browser via OpenURL to give // to a new process. It will then be transferred into yet another process due // to the call above. + GURL::Replacements replace_host; GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); - replace_host.SetHostStr(a_com); + replace_host.SetHostStr("A.com"); url2 = url2.ReplaceComponents(replace_host); // Used to make sure the second request is cancelled, and there is only one // request for url2.
diff --git a/content/browser/device_sensors/sensor_manager_chromeos.cc b/content/browser/device_sensors/sensor_manager_chromeos.cc index 2952ab63..899002e 100644 --- a/content/browser/device_sensors/sensor_manager_chromeos.cc +++ b/content/browser/device_sensors/sensor_manager_chromeos.cc
@@ -4,6 +4,8 @@ #include "content/browser/device_sensors/sensor_manager_chromeos.h" +#include <math.h> + #include "base/logging.h" #include "chromeos/accelerometer/accelerometer_reader.h" #include "chromeos/accelerometer/accelerometer_types.h"
diff --git a/content/browser/dom_storage/dom_storage_context_impl.cc b/content/browser/dom_storage/dom_storage_context_impl.cc index db9681c..0e07dab 100644 --- a/content/browser/dom_storage/dom_storage_context_impl.cc +++ b/content/browser/dom_storage/dom_storage_context_impl.cc
@@ -4,6 +4,8 @@ #include "content/browser/dom_storage/dom_storage_context_impl.h" +#include <stdlib.h> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_enumerator.h" @@ -26,6 +28,10 @@ static const int kSessionStoraceScavengingSeconds = 60; +// Offset the session storage namespace ids generated by different contexts +// to help identify when an id from one is mistakenly used in another. +static int g_session_id_offset_sequence = 1; + DOMStorageContextImpl::DOMStorageContextImpl( const base::FilePath& localstorage_directory, const base::FilePath& sessionstorage_directory, @@ -34,6 +40,7 @@ : localstorage_directory_(localstorage_directory), sessionstorage_directory_(sessionstorage_directory), task_runner_(task_runner), + session_id_offset_(abs((g_session_id_offset_sequence++ % 10)) * 1000), is_shutdown_(false), force_keep_session_state_(false), special_storage_policy_(special_storage_policy), @@ -227,6 +234,10 @@ OnDOMStorageAreaCleared(area, page_url)); } +int64 DOMStorageContextImpl::AllocateSessionId() { + return session_id_sequence_.GetNext() + session_id_offset_; +} + std::string DOMStorageContextImpl::AllocatePersistentSessionId() { std::string guid = base::GenerateGUID(); std::replace(guid.begin(), guid.end(), '-', '_');
diff --git a/content/browser/dom_storage/dom_storage_context_impl.h b/content/browser/dom_storage/dom_storage_context_impl.h index 4470df5..de848dd 100644 --- a/content/browser/dom_storage/dom_storage_context_impl.h +++ b/content/browser/dom_storage/dom_storage_context_impl.h
@@ -147,10 +147,7 @@ const GURL& page_url); // May be called on any thread. - int64 AllocateSessionId() { - return session_id_sequence_.GetNext(); - } - + int64 AllocateSessionId(); std::string AllocatePersistentSessionId(); // Must be called on the background thread. @@ -207,7 +204,10 @@ // We use a 32 bit identifier for per tab storage sessions. // At a tab per second, this range is large enough for 68 years. + // The offset is to more quickly detect the error condition where + // an id related to one context is mistakenly used in another. base::AtomicSequenceNumber session_id_sequence_; + const int session_id_offset_; bool is_shutdown_; bool force_keep_session_state_;
diff --git a/content/browser/dom_storage/dom_storage_context_impl_unittest.cc b/content/browser/dom_storage/dom_storage_context_impl_unittest.cc index 7d6cd0d..9ea4602 100644 --- a/content/browser/dom_storage/dom_storage_context_impl_unittest.cc +++ b/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
@@ -63,6 +63,8 @@ EXPECT_EQ(origin, infos[0].origin); } + int session_id_offset() { return context_->session_id_offset_; } + protected: base::MessageLoop message_loop_; base::ScopedTempDir temp_dir_; @@ -80,7 +82,7 @@ EXPECT_EQ(base::FilePath(), context_->sessionstorage_directory()); EXPECT_EQ(storage_policy_.get(), context_->special_storage_policy_.get()); context_->DeleteLocalStorage(GURL("http://chromium.org/")); - const int kFirstSessionStorageNamespaceId = 1; + const int kFirstSessionStorageNamespaceId = 1 + session_id_offset(); EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)); EXPECT_FALSE(context_->GetStorageNamespace(kFirstSessionStorageNamespaceId)); EXPECT_EQ(kFirstSessionStorageNamespaceId, context_->AllocateSessionId()); @@ -162,7 +164,7 @@ } TEST_F(DOMStorageContextImplTest, PersistentIds) { - const int kFirstSessionStorageNamespaceId = 1; + const int kFirstSessionStorageNamespaceId = 1 + session_id_offset(); const std::string kPersistentId = "persistent"; context_->CreateSessionNamespace(kFirstSessionStorageNamespaceId, kPersistentId); @@ -175,7 +177,7 @@ EXPECT_EQ(kPersistentId, area->persistent_namespace_id_); // Verify that the persistent IDs are handled correctly when cloning. - const int kClonedSessionStorageNamespaceId = 2; + const int kClonedSessionStorageNamespaceId = 2 + session_id_offset(); const std::string kClonedPersistentId = "cloned"; context_->CloneSessionNamespace(kFirstSessionStorageNamespaceId, kClonedSessionStorageNamespaceId, @@ -200,7 +202,7 @@ ASSERT_EQ(temp_dir_.path(), context_->sessionstorage_directory()); // Write data. - const int kSessionStorageNamespaceId = 1; + const int kSessionStorageNamespaceId = 1 + session_id_offset(); const std::string kPersistentId = "persistent"; context_->CreateSessionNamespace(kSessionStorageNamespaceId, kPersistentId);
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index af15b99..183ccde1 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc
@@ -43,19 +43,6 @@ return true; } -// Iterate over the FrameTree to reset any node affected by the loss of the -// given RenderViewHost's process. -bool ResetNodesForNewProcess(RenderViewHost* render_view_host, - FrameTreeNode* node) { - if (render_view_host == node->current_frame_host()->render_view_host()) { - // Ensure that if the frame host is reused for a new RenderFrame, it will - // set up the Mojo connection with that frame. - node->current_frame_host()->InvalidateMojoConnection(); - node->ResetForNewProcess(); - } - return true; -} - bool CreateProxyForSiteInstance(const scoped_refptr<SiteInstance>& instance, FrameTreeNode* node) { // If a new frame is created in the current SiteInstance, other frames in @@ -227,16 +214,6 @@ focused_frame_tree_node_id_ = -1; } -void FrameTree::RenderProcessGone(RenderViewHost* render_view_host) { - // Walk the full tree looking for nodes that may be affected. Once a frame - // crashes, all of its child FrameTreeNodes go away. - // Note that the helper function may call ResetForNewProcess on a node, which - // clears its children before we iterate over them. That's ok, because - // ForEach does not add a node's children to the queue until after visiting - // the node itself. - ForEach(base::Bind(&ResetNodesForNewProcess, render_view_host)); -} - RenderFrameHostImpl* FrameTree::GetMainFrame() const { return root_->current_frame_host(); } @@ -302,8 +279,7 @@ void FrameTree::RegisterRenderFrameHost( RenderFrameHostImpl* render_frame_host) { - SiteInstance* site_instance = - render_frame_host->render_view_host()->GetSiteInstance(); + SiteInstance* site_instance = render_frame_host->GetSiteInstance(); RenderViewHostMap::iterator iter = render_view_host_map_.find(site_instance->GetId()); CHECK(iter != render_view_host_map_.end()); @@ -313,8 +289,7 @@ void FrameTree::UnregisterRenderFrameHost( RenderFrameHostImpl* render_frame_host) { - SiteInstance* site_instance = - render_frame_host->render_view_host()->GetSiteInstance(); + SiteInstance* site_instance = render_frame_host->GetSiteInstance(); int32 site_instance_id = site_instance->GetId(); RenderViewHostMap::iterator iter = render_view_host_map_.find(site_instance_id);
diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h index b312265..5f0c7aa 100644 --- a/content/browser/frame_host/frame_tree.h +++ b/content/browser/frame_host/frame_tree.h
@@ -91,13 +91,6 @@ // TODO(creis): Look into how we can remove the need for this method. void ResetForMainFrameSwap(); - // Update the frame tree after a process exits. Any nodes currently using the - // given |render_view_host| will lose all their children. - // TODO(creis): This should take a RenderProcessHost once RenderFrameHost - // knows its process. Until then, we would just be asking the RenderViewHost - // for its process, so we'll skip that step. - void RenderProcessGone(RenderViewHost* render_view_host); - // Convenience accessor for the main frame's RenderFrameHostImpl. RenderFrameHostImpl* GetMainFrame() const;
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 6c75717..6d654aaa 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -88,9 +88,6 @@ void FrameTreeNode::ResetForNewProcess() { current_url_ = GURL(); - // The RenderFrame no longer exists and will need to be created again. - current_frame_host()->SetRenderFrameCreated(false); - // The children may not have been cleared if a cross-process navigation // commits before the old process cleans everything up. Make sure the child // nodes get deleted before swapping to a new process.
diff --git a/content/browser/frame_host/frame_tree_unittest.cc b/content/browser/frame_host/frame_tree_unittest.cc index 5f32459..6ee69fc 100644 --- a/content/browser/frame_host/frame_tree_unittest.cc +++ b/content/browser/frame_host/frame_tree_unittest.cc
@@ -11,7 +11,7 @@ #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/view_messages.h" +#include "content/common/frame_messages.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" @@ -229,7 +229,7 @@ EXPECT_EQ("RenderFrameCreated(23) -> 1: [22: [], 23: []]", activity.GetLog()); // Crash the renderer - test_rvh()->OnMessageReceived(ViewHostMsg_RenderProcessGone( + main_rfh()->OnMessageReceived(FrameHostMsg_RenderProcessGone( 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); EXPECT_EQ( "RenderFrameDeleted(22) -> 1: []\n"
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index d9bdc38c..ed3c374 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -13,6 +13,7 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" @@ -88,6 +89,57 @@ controller.GetLastCommittedEntry()->GetURL()); } +namespace { + +int RendererHistoryLength(Shell* shell) { + int value = 0; + EXPECT_TRUE(ExecuteScriptAndExtractInt( + shell->web_contents(), + "domAutomationController.send(history.length)", + &value)); + return value; +} + +// Similar to the ones from content_browser_test_utils. +bool NavigateToURLAndReplace(Shell* shell, const GURL& url) { + WebContents* web_contents = shell->web_contents(); + WaitForLoadStop(web_contents); + TestNavigationObserver same_tab_observer(web_contents, 1); + NavigationController::LoadURLParams params(url); + params.should_replace_current_entry = true; + web_contents->GetController().LoadURLWithParams(params); + web_contents->Focus(); + same_tab_observer.Wait(); + if (!IsLastCommittedEntryOfPageType(web_contents, PAGE_TYPE_NORMAL)) + return false; + return web_contents->GetLastCommittedURL() == url; +} + +} // namespace + +// When loading a new page to replace an old page in the history list, make sure +// that the browser and renderer agree, and that both get it right. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + CorrectLengthWithCurrentItemReplacement) { + NavigationController& controller = + shell()->web_contents()->GetController(); + + EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,page1"))); + EXPECT_EQ(1, controller.GetEntryCount()); + EXPECT_EQ(1, RendererHistoryLength(shell())); + + EXPECT_TRUE(NavigateToURLAndReplace(shell(), GURL("data:text/html,page2"))); + EXPECT_EQ(1, controller.GetEntryCount()); + EXPECT_EQ(1, RendererHistoryLength(shell())); + + // Note that there's no way to access the renderer's notion of the history + // offset via JavaScript. Checking just the history length, though, is enough; + // if the replacement failed, there would be a new history entry and thus an + // incorrect length. +} + +namespace { + struct FrameNavigateParamsCapturer : public WebContentsObserver { public: explicit FrameNavigateParamsCapturer(FrameTreeNode* node) @@ -135,6 +187,8 @@ scoped_refptr<MessageLoopRunner> message_loop_runner_; }; +} // namespace + // Verify that the distinction between manual and auto subframes is properly set // for subframe navigations. TODO(avi): It's rather bogus that the same info is // in two different enums; http://crbug.com/453555.
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 7820fca..aa16932 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -15,7 +15,9 @@ #include "content/browser/frame_host/navigation_controller_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_entry_screenshot_manager.h" +#include "content/browser/frame_host/navigation_request.h" #include "content/browser/frame_host/navigator.h" +#include "content/browser/frame_host/navigator_impl.h" #include "content/browser/site_instance_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" @@ -213,22 +215,30 @@ return static_cast<NavigationControllerImpl&>(controller()); } - const IPC::Message* GetLastNavigationRequest() { + bool HasNavigationRequest() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)) { - return process()->sink().GetFirstMessageMatching( - FrameMsg_RequestNavigation::ID); + FrameTreeNode* root = contents()->GetFrameTree()->root(); + NavigationRequest* navigation_request = static_cast<NavigatorImpl*>( + root->navigator())->GetNavigationRequestForNodeForTesting(root); + return navigation_request != nullptr; } - return process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID); + return process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID) + != nullptr; } - const GURL GetNavigationURLFromIPC(const IPC::Message* message) { + const GURL GetLastNavigationURL() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)) { - Tuple<CommonNavigationParams, RequestNavigationParams> nav_params; - FrameMsg_RequestNavigation::Read(message, &nav_params); - return get<0>(nav_params).url; + FrameTreeNode* root = contents()->GetFrameTree()->root(); + NavigationRequest* navigation_request = static_cast<NavigatorImpl*>( + root->navigator())->GetNavigationRequestForNodeForTesting(root); + CHECK(navigation_request); + return navigation_request->common_params().url; } + const IPC::Message* message = + process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID); + CHECK(message); Tuple<FrameMsg_Navigate_Params> nav_params; FrameMsg_Navigate::Read(message, &nav_params); return get<0>(nav_params).common_params.url; @@ -309,6 +319,7 @@ urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i)); } + main_test_rfh()->PrepareForCommit(urls[0]); main_test_rfh()->SendNavigate(0, urls[0]); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -318,6 +329,7 @@ EXPECT_FALSE(controller.CanGoToOffset(1)); for (int i = 1; i <= 4; ++i) { + main_test_rfh()->PrepareForCommit(urls[i]); main_test_rfh()->SendNavigate(i, urls[i]); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -353,6 +365,7 @@ url_index += offset; // Check that the GoToOffset will land on the expected page. EXPECT_EQ(urls[url_index], controller.GetPendingEntry()->GetVirtualURL()); + main_test_rfh()->PrepareForCommit(urls[url_index]); main_test_rfh()->SendNavigate(url_index, urls[url_index]); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -480,6 +493,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -490,8 +504,8 @@ // Simulate the beforeunload ack for the cross-site transition, and then the // commit. - main_test_rfh()->SendBeforeUnloadACK(true); - main_test_rfh()->SendNavigate(1, url2); + main_test_rfh()->PrepareForCommit(url2); + contents()->GetPendingMainFrame()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -615,6 +629,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -626,6 +641,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -665,6 +681,7 @@ params.is_post = true; params.post_id = 123; params.page_state = PageState::CreateForTesting(url1, false, 0, 0); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigateWithParams(¶ms); // The post data should be visible. @@ -675,6 +692,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); // We should not have produced a new session history entry. @@ -765,6 +783,7 @@ const GURL kExistingURL1("http://eh"); controller.LoadURL( kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(kExistingURL1); main_test_rfh()->SendNavigate(0, kExistingURL1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -778,6 +797,7 @@ // After the beforeunload but before it commits, do a new navigation. main_test_rfh()->PrepareForCommit(kExistingURL2); const GURL kNewURL("http://see"); + main_test_rfh()->PrepareForCommit(kNewURL); contents()->GetMainFrame()->SendNavigate(3, kNewURL); // There should no longer be any pending entry, and the third navigation we @@ -801,6 +821,7 @@ const GURL kExistingURL1("http://foo/eh"); controller.LoadURL( kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(kExistingURL1); main_test_rfh()->SendNavigate(0, kExistingURL1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -808,6 +829,7 @@ const GURL kExistingURL2("http://foo/bee"); controller.LoadURL( kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(kExistingURL2); main_test_rfh()->SendNavigate(1, kExistingURL2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -821,6 +843,7 @@ // Before that commits, do a new navigation. const GURL kNewURL("http://foo/see"); + main_test_rfh()->PrepareForCommit(kNewURL); main_test_rfh()->SendNavigate(3, kNewURL); // There should no longer be any pending entry, and the third navigation we @@ -873,6 +896,7 @@ // Before that commits, do a new navigation. const GURL kNewURL("http://foo/bee"); + foo_rfh->PrepareForCommit(kNewURL); foo_rfh->SendNavigate(3, kNewURL); // There should no longer be any pending entry, and the third navigation we @@ -898,6 +922,7 @@ const GURL kExistingURL1("http://foo/eh"); controller.LoadURL( kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(kExistingURL1); main_test_rfh()->SendNavigate(0, kExistingURL1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -905,6 +930,7 @@ const GURL kExistingURL2("http://foo/bee"); controller.LoadURL( kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(kExistingURL2); main_test_rfh()->SendNavigate(1, kExistingURL2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -918,6 +944,7 @@ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); // Before that commits, a back navigation from the renderer commits. + main_test_rfh()->PrepareForCommit(kExistingURL1); main_test_rfh()->SendNavigate(0, kExistingURL1); // There should no longer be any pending entry, and the back navigation we @@ -957,6 +984,7 @@ // Before that commits, a document.write and location.reload can cause the // renderer to send a FrameNavigate with page_id -1. + main_test_rfh()->PrepareForCommit(kExistingURL); main_test_rfh()->SendNavigate(-1, kExistingURL); // This should clear the pending entry and notify of a navigation state @@ -1140,7 +1168,7 @@ // Going back, the first entry should still appear unprivileged. controller.GoBack(); - new_rfh->SendBeforeUnloadACK(true); + new_rfh->PrepareForCommit(url1); orig_rfh->SendNavigate(0, url1); EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( @@ -1157,6 +1185,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1181,6 +1210,7 @@ // See http://crbug.com/96041. EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1210,6 +1240,7 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1217,6 +1248,7 @@ controller.Reload(true); EXPECT_EQ(0U, notifications.size()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1276,6 +1308,7 @@ controller.LoadURL( original_url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); + main_test_rfh()->PrepareForCommit(final_url); main_test_rfh()->SendNavigateWithOriginalRequestURL( 0, final_url, original_url); EXPECT_EQ(1U, navigation_entry_committed_counter_); @@ -1308,6 +1341,7 @@ EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); // Send that the navigation has proceeded; say it got redirected again. + main_test_rfh()->PrepareForCommit(final_url); main_test_rfh()->SendNavigate(0, final_url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1469,12 +1503,14 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; controller.LoadURL( url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1491,6 +1527,7 @@ EXPECT_FALSE(controller.CanGoBack()); EXPECT_TRUE(controller.CanGoForward()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1548,11 +1585,15 @@ const GURL kUrl3("http://foo/3"); // First navigate three places so we have some back history. + main_test_rfh()->PrepareForCommit(kUrl1); main_test_rfh()->SendNavigate(0, kUrl1); + main_test_rfh()->PrepareForCommit(kUrl2); main_test_rfh()->SendNavigate(1, kUrl2); + main_test_rfh()->PrepareForCommit(kUrl3); main_test_rfh()->SendNavigate(2, kUrl3); // With nothing pending, say we get a navigation to the second entry. + main_test_rfh()->PrepareForCommit(kUrl2); main_test_rfh()->SendNavigate(1, kUrl2); // We know all the entries have the same site instance, so we can just grab @@ -1569,6 +1610,7 @@ // Now go forward to the last item again and say it was committed. controller.GoForward(); + main_test_rfh()->PrepareForCommit(kUrl3); main_test_rfh()->SendNavigate(2, kUrl3); // Now start going back one to the second page. It will be pending. @@ -1578,6 +1620,7 @@ // Not synthesize a totally new back event to the first page. This will not // match the pending one. + main_test_rfh()->PrepareForCommit(kUrl1); main_test_rfh()->SendNavigate(0, kUrl1); // The committed navigation should clear the pending entry. @@ -1597,15 +1640,18 @@ const GURL url1("http://foo1"); const GURL url2("http://foo2"); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; controller.GoBack(); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1630,6 +1676,7 @@ EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(), controller.GetEntryAtIndex(1)->GetTimestamp()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1662,14 +1709,17 @@ const GURL url2("http://foo2"); const GURL url3("http://foo3"); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; controller.GoBack(); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1686,6 +1736,7 @@ EXPECT_TRUE(controller.CanGoBack()); EXPECT_FALSE(controller.CanGoForward()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -2347,6 +2398,7 @@ GURL url(base::StringPrintf("http://www.a.com/%d", url_index)); controller.LoadURL( url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url); main_test_rfh()->SendNavigate(url_index, url); } @@ -2359,6 +2411,7 @@ GURL url(base::StringPrintf("http://www.a.com/%d", url_index)); controller.LoadURL( url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url); main_test_rfh()->SendNavigate(url_index, url); url_index++; @@ -2377,6 +2430,7 @@ url = GURL(base::StringPrintf("http:////www.a.com/%d", url_index)); controller.LoadURL( url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url); main_test_rfh()->SendNavigate(url_index, url); url_index++; } @@ -2553,6 +2607,7 @@ const GURL url1("http://foo"); controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); // Now navigate somewhere with an interstitial. @@ -2564,6 +2619,7 @@ // At this point the interstitial will be displayed and the load will still // be pending. If the user continues, the load will commit. + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); // The page should be a normal page again. @@ -2584,18 +2640,23 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); controller.LoadURL( url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); controller.LoadURL( url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(2, url3); controller.LoadURL( url4, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url4); main_test_rfh()->SendNavigate(3, url4); controller.LoadURL( url5, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url5); main_test_rfh()->SendNavigate(4, url5); // Try to remove the last entry. Will fail because it is the current entry. @@ -2610,6 +2671,7 @@ EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2)); // Now commit and delete the last entry. + main_test_rfh()->PrepareForCommit(url4); main_test_rfh()->SendNavigate(3, url4); EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); EXPECT_EQ(4, controller.GetEntryCount()); @@ -2640,12 +2702,15 @@ controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(0, url1); controller.LoadURL( url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); controller.LoadURL( url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(2, url3); // Go back, but don't commit yet. Check that we can't delete the current @@ -2664,6 +2729,7 @@ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); // Now commit and ensure we land on the right entry. + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(2, controller.GetEntryCount()); EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); @@ -2686,9 +2752,11 @@ controller.LoadURL( url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url0); main_test_rfh()->SendNavigate(0, url0); controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(1, url1); notifications.Reset(); @@ -2715,6 +2783,7 @@ // Navigate. controller.LoadURL( url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(2, url2); // We should have navigated, transient entry should be gone. @@ -2726,6 +2795,7 @@ transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(3, url3); // Transient entry should be gone. EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); @@ -2738,6 +2808,7 @@ transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url4); main_test_rfh()->SendNavigate(4, url4); EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); EXPECT_EQ(controller.GetEntryCount(), 5); @@ -2753,6 +2824,7 @@ // Transient entry should be gone. EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); EXPECT_EQ(controller.GetEntryCount(), 5); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(3, url3); // Add a transient and go to an entry before the current one. @@ -2766,6 +2838,7 @@ EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); // Visible entry does not update for history navigations until commit. EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(1, url1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); @@ -2780,6 +2853,7 @@ // land on url2 (which is visible after the commit). EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL()); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url2); main_test_rfh()->SendNavigate(2, url2); EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); @@ -2794,6 +2868,7 @@ EXPECT_FALSE(controller.GetTransientEntry()); EXPECT_EQ(url3, controller.GetPendingEntry()->GetURL()); EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(3, url3); EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); @@ -2802,6 +2877,7 @@ transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url3_ref); main_test_rfh()->SendNavigate(3, url3_ref); // Transient entry should be gone. EXPECT_FALSE(controller.GetTransientEntry()); @@ -2826,6 +2902,7 @@ // Load |url0|, and start a pending navigation to |url1|. controller.LoadURL( url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + main_test_rfh()->PrepareForCommit(url0); main_test_rfh()->SendNavigate(0, url0); controller.LoadURL( url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); @@ -2848,6 +2925,7 @@ EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); // Load of |transient_url| completes. + main_test_rfh()->PrepareForCommit(transient_url); main_test_rfh()->SendNavigate(1, transient_url); ASSERT_EQ(controller.GetEntryCount(), 2); EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); @@ -2931,6 +3009,7 @@ url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(url0, controller.GetPendingEntry()->GetURL()); EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL()); + main_test_rfh()->PrepareForCommit(url0); main_test_rfh()->SendNavigate(0, url0); // For link clicks (renderer-initiated navigations), the pending entry should @@ -2946,6 +3025,7 @@ // After commit, both visible should be updated, there should be no pending // entry, and we should no longer treat the entry as renderer-initiated. + main_test_rfh()->PrepareForCommit(url1); main_test_rfh()->SendNavigate(1, url1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); EXPECT_FALSE(controller.GetPendingEntry()); @@ -3983,10 +4063,9 @@ // it unloaded, simulate that. contents()->ProceedWithCrossSiteNavigation(); // Also make sure we told the page to navigate. - const IPC::Message* message = GetLastNavigationRequest(); - ASSERT_TRUE(message != NULL); - GURL nav_url = GetNavigationURLFromIPC(message); + GURL nav_url = GetLastNavigationURL(); EXPECT_EQ(url1, nav_url); + contents()->CommitPendingNavigation(); process()->sink().ClearMessages(); // Now test history.forward() @@ -3995,10 +4074,9 @@ // The actual cross-navigation is suspended until the current RVH tells us // it unloaded, simulate that. contents()->ProceedWithCrossSiteNavigation(); - message = GetLastNavigationRequest(); - ASSERT_TRUE(message != NULL); - nav_url = GetNavigationURLFromIPC(message); + nav_url = GetLastNavigationURL(); EXPECT_EQ(url3, nav_url); + contents()->CommitPendingNavigation(); process()->sink().ClearMessages(); controller.DiscardNonCommittedEntries(); @@ -4006,8 +4084,7 @@ // Make sure an extravagant history.go() doesn't break. contents()->OnGoToEntryAtOffset(120); // Out of bounds. EXPECT_EQ(-1, controller.GetPendingEntryIndex()); - message = GetLastNavigationRequest(); - EXPECT_TRUE(message == NULL); + EXPECT_FALSE(HasNavigationRequest()); } // Test call to PruneAllButLastCommitted for the only entry. @@ -4096,6 +4173,7 @@ EXPECT_EQ(1, controller.GetEntryCount()); // Try to commit the pending entry. + main_test_rfh()->PrepareForCommit(url3); main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(-1, controller.GetPendingEntryIndex()); EXPECT_FALSE(controller.GetPendingEntry());
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index f359f51..8a599b1 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -4,6 +4,7 @@ #include "content/browser/frame_host/navigation_request.h" +#include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_request_info.h" #include "content/browser/frame_host/navigator.h" @@ -12,16 +13,69 @@ #include "content/common/resource_request_body.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/stream_handle.h" +#include "content/public/common/content_client.h" +#include "net/base/load_flags.h" +#include "net/http/http_request_headers.h" #include "net/url_request/redirect_info.h" namespace content { +namespace { + +// Returns the net load flags to use based on the navigation type. +// TODO(clamy): unify the code with what is happening on the renderer side. +int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) { + int load_flags = net::LOAD_NORMAL; + switch (navigation_type) { + case FrameMsg_Navigate_Type::RELOAD: + case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL: + load_flags |= net::LOAD_VALIDATE_CACHE; + break; + case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE: + load_flags |= net::LOAD_BYPASS_CACHE; + break; + case FrameMsg_Navigate_Type::RESTORE: + load_flags |= net::LOAD_PREFERRING_CACHE; + break; + case FrameMsg_Navigate_Type::RESTORE_WITH_POST: + load_flags |= net::LOAD_ONLY_FROM_CACHE; + break; + case FrameMsg_Navigate_Type::NORMAL: + default: + break; + } + return load_flags; +} + +} // namespace + // static -scoped_ptr<NavigationRequest> NavigationRequest::Create( +scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated( FrameTreeNode* frame_tree_node, const NavigationEntryImpl& entry, FrameMsg_Navigate_Type::Value navigation_type, base::TimeTicks navigation_start) { + std::string method = entry.GetHasPostData() ? "POST" : "GET"; + + // Copy existing headers and add necessary headers that may not be present + // in the RequestNavigationParams. + net::HttpRequestHeaders headers; + headers.AddHeadersFromString(entry.extra_headers()); + headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent, + GetContentClient()->GetUserAgent()); + // TODO(clamy): match what blink is doing with accept headers. + headers.SetHeaderIfMissing("Accept", "*/*"); + + // Fill POST data from the browser in the request body. + scoped_refptr<ResourceRequestBody> request_body; + if (entry.GetHasPostData()) { + request_body = new ResourceRequestBody(); + request_body->AppendBytes( + reinterpret_cast<const char *>( + entry.GetBrowserInitiatedPostData()->front()), + entry.GetBrowserInitiatedPostData()->size()); + } + FrameMsg_UILoadMetricsReportType::Value report_type = FrameMsg_UILoadMetricsReportType::NO_REPORT; base::TimeTicks ui_timestamp = base::TimeTicks(); @@ -37,21 +91,47 @@ entry.GetTransitionType(), navigation_type, !entry.IsViewSourceMode(),ui_timestamp, report_type), + BeginNavigationParams(method, headers.ToString(), + LoadFlagFromNavigationType(navigation_type), + false), CommitNavigationParams(entry.GetPageState(), entry.GetIsOverridingUserAgent(), navigation_start), - &entry)); + request_body, true, &entry)); + return navigation_request.Pass(); +} + +// static +scoped_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated( + FrameTreeNode* frame_tree_node, + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body) { + // TODO(clamy): Check if some PageState should be provided here. + // TODO(clamy): See how we should handle override of the user agent when the + // navigation may start in a renderer and commit in another one. + // TODO(clamy): See if the navigation start time should be measured in the + // renderer and sent to the browser instead of being measured here. + scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest( + frame_tree_node, common_params, begin_params, + CommitNavigationParams(PageState(), false, base::TimeTicks::Now()), + body, false, nullptr)); return navigation_request.Pass(); } NavigationRequest::NavigationRequest( FrameTreeNode* frame_tree_node, const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, const CommitNavigationParams& commit_params, + scoped_refptr<ResourceRequestBody> body, + bool browser_initiated, const NavigationEntryImpl* entry) : frame_tree_node_(frame_tree_node), common_params_(common_params), + begin_params_(begin_params), commit_params_(commit_params), + browser_initiated_(browser_initiated), state_(NOT_STARTED), restore_type_(NavigationEntryImpl::RESTORE_NONE), is_view_source_(false), @@ -63,21 +143,28 @@ is_view_source_ = entry->IsViewSourceMode(); bindings_ = entry->bindings(); } + + const GURL& first_party_for_cookies = + frame_tree_node->IsMainFrame() + ? common_params.url + : frame_tree_node->frame_tree()->root()->current_url(); + bool parent_is_main_frame = !frame_tree_node->parent() ? + false : frame_tree_node->parent()->IsMainFrame(); + info_.reset(new NavigationRequestInfo( + common_params, begin_params, first_party_for_cookies, + frame_tree_node->IsMainFrame(), parent_is_main_frame, body)); } NavigationRequest::~NavigationRequest() { } -void NavigationRequest::BeginNavigation( - scoped_ptr<NavigationRequestInfo> info, - scoped_refptr<ResourceRequestBody> request_body) { +void NavigationRequest::BeginNavigation() { DCHECK(!loader_); DCHECK(state_ == NOT_STARTED || state_ == WAITING_FOR_RENDERER_RESPONSE); state_ = STARTED; loader_ = NavigationURLLoader::Create( frame_tree_node_->navigator()->GetController()->GetBrowserContext(), - frame_tree_node_->frame_tree_node_id(), common_params_, info.Pass(), - request_body.get(), this); + frame_tree_node_->frame_tree_node_id(), info_.Pass(), this); // TODO(davidben): Fire (and add as necessary) observer methods such as // DidStartProvisionalLoadForFrame for the navigation.
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 8e1d303..b49d692 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -52,26 +52,29 @@ FAILED, }; - static scoped_ptr<NavigationRequest> Create( - FrameTreeNode* frame_tree_node, - const NavigationEntryImpl& entry, - FrameMsg_Navigate_Type::Value navigation_type, - base::TimeTicks navigation_start); + // Creates a request for a browser-intiated navigation. + static scoped_ptr<NavigationRequest> CreateBrowserInitiated( + FrameTreeNode* frame_tree_node, + const NavigationEntryImpl& entry, + FrameMsg_Navigate_Type::Value navigation_type, + base::TimeTicks navigation_start); - NavigationRequest(FrameTreeNode* frame_tree_node, - const CommonNavigationParams& common_params, - const CommitNavigationParams& commit_params, - const NavigationEntryImpl* navitation_entry); + // Creates a request for a renderer-intiated navigation. + // Note: |body| is sent to the IO thread when calling BeginNavigation, and + // should no longer be manipulated afterwards on the UI thread. + static scoped_ptr<NavigationRequest> CreateRendererInitiated( + FrameTreeNode* frame_tree_node, + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body); ~NavigationRequest() override; - // Called on the UI thread by the RenderFrameHostManager which owns the - // NavigationRequest. Takes ownership of |info|. After calling this function, - // |body| can no longer be manipulated on the UI thread. - void BeginNavigation(scoped_ptr<NavigationRequestInfo> info, - scoped_refptr<ResourceRequestBody> body); - - CommonNavigationParams& common_params() { return common_params_; } + // Called on the UI thread by the Navigator to start the navigation on the IO + // thread. + // TODO(clamy): see if ResourceRequestBody could be un-refcounted to avoid + // threading subtleties. + void BeginNavigation(); const CommonNavigationParams& common_params() const { return common_params_; } @@ -97,12 +100,22 @@ int bindings() const { return bindings_; }; + bool browser_initiated() const { return browser_initiated_ ; } + void SetWaitingForRendererResponse() { DCHECK(state_ == NOT_STARTED); state_ = WAITING_FOR_RENDERER_RESPONSE; } private: + NavigationRequest(FrameTreeNode* frame_tree_node, + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + const CommitNavigationParams& commit_params, + scoped_refptr<ResourceRequestBody> body, + bool browser_initiated, + const NavigationEntryImpl* navitation_entry); + // NavigationURLLoaderDelegate implementation. void OnRequestRedirected( const net::RedirectInfo& redirect_info, @@ -120,10 +133,17 @@ // will be set to the final navigation url, obtained after following all // redirects. CommonNavigationParams common_params_; + const BeginNavigationParams begin_params_; const CommitNavigationParams commit_params_; + const bool browser_initiated_; NavigationState state_; + + // The parameters to send to the IO thread. |loader_| takes ownership of + // |info_| after calling BeginNavigation. + scoped_ptr<NavigationRequestInfo> info_; + scoped_ptr<NavigationURLLoader> loader_; // These next items are used in browser-initiated navigations to store
diff --git a/content/browser/frame_host/navigation_request_info.cc b/content/browser/frame_host/navigation_request_info.cc index 91568ad..76b98c36 100644 --- a/content/browser/frame_host/navigation_request_info.cc +++ b/content/browser/frame_host/navigation_request_info.cc
@@ -4,15 +4,23 @@ #include "content/browser/frame_host/navigation_request_info.h" -#include "content/common/resource_request_body.h" - namespace content { NavigationRequestInfo::NavigationRequestInfo( - const FrameHostMsg_BeginNavigation_Params& params) - : navigation_params(params), - is_main_frame(true), - parent_is_main_frame(false) { + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + const GURL& first_party_for_cookies, + bool is_main_frame, + bool parent_is_main_frame, + scoped_refptr<ResourceRequestBody> request_body) + : common_params(common_params), + begin_params(begin_params), + first_party_for_cookies(first_party_for_cookies), + is_main_frame(is_main_frame), + parent_is_main_frame(parent_is_main_frame), + request_body(request_body) { } +NavigationRequestInfo::~NavigationRequestInfo() {} + } // namespace content
diff --git a/content/browser/frame_host/navigation_request_info.h b/content/browser/frame_host/navigation_request_info.h index 70bb787..2721c3d 100644 --- a/content/browser/frame_host/navigation_request_info.h +++ b/content/browser/frame_host/navigation_request_info.h
@@ -8,31 +8,39 @@ #include <string> #include "base/basictypes.h" +#include "base/memory/ref_counted.h" #include "content/common/content_export.h" -#include "content/common/frame_messages.h" +#include "content/common/navigation_params.h" +#include "content/common/resource_request_body.h" #include "content/public/common/referrer.h" #include "url/gurl.h" namespace content { +class ResourceRequestBody; // A struct to hold the parameters needed to start a navigation request in // ResourceDispatcherHost. It is initialized on the UI thread, and then passed // to the IO thread by a NavigationRequest object. struct CONTENT_EXPORT NavigationRequestInfo { - explicit NavigationRequestInfo( - const FrameHostMsg_BeginNavigation_Params& params); + NavigationRequestInfo(const CommonNavigationParams& common_params, + const BeginNavigationParams& params, + const GURL& first_party_for_cookies, + bool is_main_frame, + bool parent_is_main_frame, + scoped_refptr<ResourceRequestBody> request_body); + ~NavigationRequestInfo(); - const FrameHostMsg_BeginNavigation_Params navigation_params; - - // --------------------------------------------------------------------------- - // The following parameters should be filled in by RenderFrameHostManager - // before the navigation request is sent to the ResourceDispatcherHost. + const CommonNavigationParams common_params; + const BeginNavigationParams begin_params; // Usually the URL of the document in the top-level window, which may be // checked by the third-party cookie blocking policy. - GURL first_party_for_cookies; - bool is_main_frame; - bool parent_is_main_frame; + const GURL first_party_for_cookies; + + const bool is_main_frame; + const bool parent_is_main_frame; + + scoped_refptr<ResourceRequestBody> request_body; }; } // namespace content
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index b561fe72..774b8c5 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc
@@ -5,6 +5,7 @@ #include "content/browser/frame_host/navigator.h" #include "base/time/time.h" +#include "content/common/resource_request_body.h" #include "content/public/browser/stream_handle.h" namespace content { @@ -23,6 +24,13 @@ return base::TimeTicks::Now(); } +void Navigator::OnBeginNavigation( + FrameTreeNode* frame_tree_node, + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body) { +} + void Navigator::CommitNavigation(FrameTreeNode* frame_tree_node, ResourceResponse* response, scoped_ptr<StreamHandle> body) {
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index e56335a..a69dfdf 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -28,7 +28,9 @@ class NavigationRequest; class NavigatorDelegate; class RenderFrameHostImpl; +class ResourceRequestBody; class StreamHandle; +struct BeginNavigationParams; struct CommonNavigationParams; struct ResourceResponse; @@ -116,15 +118,22 @@ bool should_replace_current_entry, bool user_gesture) {} - // PlzNavigate: Used to start a navigation. OnBeginNavigation is called - // directly by RequestNavigation when there is no live renderer. Otherwise, it - // is called following a BeginNavigation IPC from the renderer (which in - // browser-initiated navigation also happens after RequestNavigation has been - // called). + // PlzNavigate + // Called after receiving a BeforeUnloadACK IPC from the renderer. If + // |frame_tree_node| has a NavigationRequest waiting for the renderer + // response, then the request is either started or canceled, depending on the + // value of |proceed|. + virtual void OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, + bool proceed) {} + + // PlzNavigate + // Used to start a new renderer-initiated navigation, following a + // BeginNavigation IPC from the renderer. virtual void OnBeginNavigation( FrameTreeNode* frame_tree_node, - const FrameHostMsg_BeginNavigation_Params& params, - const CommonNavigationParams& common_params) {} + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body); // PlzNavigate // Signal |render_frame_host| that a navigation is ready to commit (the
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 8617d7e6..e4afbe62 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -19,6 +19,7 @@ #include "content/browser/site_instance_impl.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/browser/webui/web_ui_impl.h" +#include "content/common/frame_messages.h" #include "content/common/navigation_params.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" @@ -37,8 +38,6 @@ #include "content/public/common/resource_response.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" -#include "net/base/load_flags.h" -#include "net/http/http_request_headers.h" namespace content { @@ -70,65 +69,6 @@ return FrameMsg_Navigate_Type::NORMAL; } -// PlzNavigate -// Returns the net load flags to use based on the navigation type. -// TODO(clamy): unify the code with what is happening on the renderer side. -int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) { - int load_flags = net::LOAD_NORMAL; - switch (navigation_type) { - case FrameMsg_Navigate_Type::RELOAD: - case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL: - load_flags |= net::LOAD_VALIDATE_CACHE; - break; - case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE: - load_flags |= net::LOAD_BYPASS_CACHE; - break; - case FrameMsg_Navigate_Type::RESTORE: - load_flags |= net::LOAD_PREFERRING_CACHE; - break; - case FrameMsg_Navigate_Type::RESTORE_WITH_POST: - load_flags |= net::LOAD_ONLY_FROM_CACHE; - break; - case FrameMsg_Navigate_Type::NORMAL: - default: - break; - } - return load_flags; -} - -// PlzNavigate -// Generates a default FrameHostMsg_BeginNavigation_Params to be used when there -// is no live renderer. -FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation( - const RequestNavigationParams& request_params, - FrameMsg_Navigate_Type::Value navigation_type) { - FrameHostMsg_BeginNavigation_Params begin_navigation_params; - begin_navigation_params.method = request_params.is_post ? "POST" : "GET"; - begin_navigation_params.load_flags = - LoadFlagFromNavigationType(navigation_type); - - // Copy existing headers and add necessary headers that may not be present - // in the RequestNavigationParams. - net::HttpRequestHeaders headers; - headers.AddHeadersFromString(request_params.extra_headers); - headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent, - GetContentClient()->GetUserAgent()); - headers.SetHeaderIfMissing("Accept", "*/*"); - begin_navigation_params.headers = headers.ToString(); - - // Fill POST data from the browser in the request body. - if (request_params.is_post) { - begin_navigation_params.request_body = new ResourceRequestBody(); - begin_navigation_params.request_body->AppendBytes( - reinterpret_cast<const char *>( - &request_params.browser_initiated_post_data.front()), - request_params.browser_initiated_post_data.size()); - } - - begin_navigation_params.has_user_gesture = false; - return begin_navigation_params; -} - RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSitePerProcess)) @@ -155,12 +95,17 @@ entry.GetURL(), entry.GetReferrer(), entry.GetTransitionType(), GetNavigationType(controller->GetBrowserContext(), entry, reload_type), !entry.IsViewSourceMode(), ui_timestamp, report_type); - params->request_params = RequestNavigationParams( - entry.GetHasPostData(), - entry.extra_headers(), - entry.GetBrowserInitiatedPostData()); params->commit_params = CommitNavigationParams( entry.GetPageState(), entry.GetIsOverridingUserAgent(), navigation_start); + params->is_post = entry.GetHasPostData(); + params->extra_headers = entry.extra_headers(); + if (entry.GetBrowserInitiatedPostData()) { + params->browser_initiated_post_data.assign( + entry.GetBrowserInitiatedPostData()->front(), + entry.GetBrowserInitiatedPostData()->front() + + entry.GetBrowserInitiatedPostData()->size()); + } + if (!entry.GetBaseURLForDataURL().is_empty()) { params->base_url_for_data_url = entry.GetBaseURLForDataURL(); params->history_url_for_data_url = entry.GetVirtualURL(); @@ -264,9 +209,7 @@ true /* is_renderer_initiated */, std::string(), controller_->GetBrowserContext())); - entry->set_site_instance( - static_cast<SiteInstanceImpl*>( - render_frame_host->render_view_host()->GetSiteInstance())); + entry->set_site_instance(render_frame_host->GetSiteInstance()); // TODO(creis): If there's a pending entry already, find a safe way to // update it instead of replacing it and copying over things like this. if (pending_entry) { @@ -405,10 +348,11 @@ switches::kEnableBrowserSideNavigation)) { navigation_data_.reset(new NavigationMetricsData( navigation_start, entry.GetURL(), entry.restore_type())); - return RequestNavigation(render_frame_host->frame_tree_node(), - entry, - reload_type, - navigation_start); + RequestNavigation(render_frame_host->frame_tree_node(), + entry, + reload_type, + navigation_start); + return true; } RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); @@ -552,8 +496,7 @@ // assigning a site is not necessary for this URL. In that case, the // SiteInstance can still be considered unused until a navigation to a real // page. - SiteInstanceImpl* site_instance = - static_cast<SiteInstanceImpl*>(render_frame_host->GetSiteInstance()); + SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); if (!site_instance->HasSite() && ShouldAssignSiteForURL(params.url)) { site_instance->SetSite(params.url); @@ -731,10 +674,8 @@ } // PlzNavigate -void NavigatorImpl::OnBeginNavigation( - FrameTreeNode* frame_tree_node, - const FrameHostMsg_BeginNavigation_Params& params, - const CommonNavigationParams& common_params) { +void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, + bool proceed) { CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); DCHECK(frame_tree_node); @@ -742,46 +683,44 @@ NavigationRequest* navigation_request = navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); - if (!navigation_request) { - // This is a renderer initiated navigation, so generate a new - // NavigationRequest and store it in the map. - // TODO(clamy): Check if some PageState should be provided here. - // TODO(clamy): See how we should handle override of the user agent when the - // navigation may start in a renderer and commit in another one. - // TODO(clamy): See if the navigation start time should be measured in the - // renderer and sent to the browser instead of being measured here. - scoped_ptr<NavigationRequest> scoped_request(new NavigationRequest( - frame_tree_node, common_params, - CommitNavigationParams(PageState(), false, base::TimeTicks::Now()), - nullptr)); - navigation_request = scoped_request.get(); - navigation_request_map_.set( - frame_tree_node->frame_tree_node_id(), scoped_request.Pass()); + // The NavigationRequest may have been canceled while the renderer was + // executing the BeforeUnload event. + if (!navigation_request) + return; - if (frame_tree_node->IsMainFrame()) - navigation_data_.reset(); - } - DCHECK(navigation_request); + DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, + navigation_request->state()); - // Update the referrer with the one received from the renderer. - navigation_request->common_params().referrer = common_params.referrer; + if (proceed) + BeginNavigation(frame_tree_node); + else + CancelNavigation(frame_tree_node); +} - scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params)); +// PlzNavigate +void NavigatorImpl::OnBeginNavigation( + FrameTreeNode* frame_tree_node, + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body) { + CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)); + DCHECK(frame_tree_node); - info->first_party_for_cookies = - frame_tree_node->IsMainFrame() - ? navigation_request->common_params().url - : frame_tree_node->frame_tree()->root()->current_url(); - info->is_main_frame = frame_tree_node->IsMainFrame(); - info->parent_is_main_frame = !frame_tree_node->parent() ? - false : frame_tree_node->parent()->IsMainFrame(); + // This is a renderer-initiated navigation, so generate a new + // NavigationRequest and store it in the map. + // TODO(clamy): Renderer-initiated navigations should not always cancel the + // current one. + scoped_ptr<NavigationRequest> navigation_request = + NavigationRequest::CreateRendererInitiated( + frame_tree_node, common_params, begin_params, body); + navigation_request_map_.set( + frame_tree_node->frame_tree_node_id(), navigation_request.Pass()); - // First start the request on the IO thread. - navigation_request->BeginNavigation(info.Pass(), params.request_body); + if (frame_tree_node->IsMainFrame()) + navigation_data_.reset(); - // Then notify the RenderFrameHostManager so it can speculatively create a - // RenderFrameHost (and potentially a new renderer process) in parallel. - frame_tree_node->render_manager()->BeginNavigation(*navigation_request); + BeginNavigation(frame_tree_node); } // PlzNavigate @@ -884,7 +823,7 @@ } // PlzNavigate -bool NavigatorImpl::RequestNavigation( +void NavigatorImpl::RequestNavigation( FrameTreeNode* frame_tree_node, const NavigationEntryImpl& entry, NavigationController::ReloadType reload_type, @@ -895,33 +834,39 @@ int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); - scoped_ptr<NavigationRequest> navigation_request = NavigationRequest::Create( - frame_tree_node, entry, navigation_type, navigation_start); - RequestNavigationParams request_params(entry.GetHasPostData(), - entry.extra_headers(), - entry.GetBrowserInitiatedPostData()); + scoped_ptr<NavigationRequest> navigation_request = + NavigationRequest::CreateBrowserInitiated( + frame_tree_node, entry, navigation_type, navigation_start); // TODO(clamy): Check if navigations are blocked and if so store the // parameters. // If there is an ongoing request, replace it. navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); - if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) { - NavigationRequest* request_to_send = - navigation_request_map_.get(frame_tree_node_id); - frame_tree_node->current_frame_host()->Send(new FrameMsg_RequestNavigation( - frame_tree_node->current_frame_host()->GetRoutingID(), - request_to_send->common_params(), request_params)); - request_to_send->SetWaitingForRendererResponse(); - return true; - } + // Have the current renderer execute its beforeUnload event if needed. If it + // is not needed (eg. the renderer is not live), BeginNavigation should get + // called. + NavigationRequest* request_to_send = + navigation_request_map_.get(frame_tree_node_id); + request_to_send->SetWaitingForRendererResponse(); + frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); +} - // The navigation request is sent directly to the IO thread. - OnBeginNavigation( - frame_tree_node, - MakeDefaultBeginNavigation(request_params, navigation_type), - navigation_request_map_.get(frame_tree_node_id)->common_params()); - return true; +void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { + NavigationRequest* navigation_request = + navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); + + // A browser-initiated navigation could have been cancelled while it was + // waiting for the BeforeUnload event to execute. + if (!navigation_request) + return; + + // First start the request on the IO thread. + navigation_request->BeginNavigation(); + + // Then notify the RenderFrameHostManager so it can speculatively create a + // RenderFrameHost (and potentially a new renderer process) in parallel. + frame_tree_node->render_manager()->BeginNavigation(*navigation_request); } void NavigatorImpl::RecordNavigationMetrics(
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index c372e7e..7d4622d 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -70,9 +70,11 @@ const GlobalRequestID& transferred_global_request_id, bool should_replace_current_entry, bool user_gesture) override; + void OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, bool proceed) override; void OnBeginNavigation(FrameTreeNode* frame_tree_node, - const FrameHostMsg_BeginNavigation_Params& params, - const CommonNavigationParams& common_params) override; + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body) override; void CommitNavigation(FrameTreeNode* frame_tree_node, ResourceResponse* response, scoped_ptr<StreamHandle> body) override; @@ -109,14 +111,18 @@ RenderFrameHostImpl* render_frame_host, const GURL& url); - // PlzNavigate: sends a RequestNavigation IPC to the renderer to ask it to - // navigate. If no live renderer is present, then the navigation request will - // be sent directly to the ResourceDispatcherHost. - bool RequestNavigation(FrameTreeNode* frame_tree_node, + // PlzNavigate: if needed, sends a BeforeUnload IPC to the renderer to ask it + // to execute the beforeUnload event. Otherwise, the navigation request will + // be started. + void RequestNavigation(FrameTreeNode* frame_tree_node, const NavigationEntryImpl& entry, NavigationController::ReloadType reload_type, base::TimeTicks navigation_start); + // PlzNavigate: sends the NavigationRequest for |frame_tree_node| to the + // network stack so that it can start. + void BeginNavigation(FrameTreeNode* frame_tree_node); + void RecordNavigationMetrics( const LoadCommittedDetails& details, const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index 33d23ab..2de47f8 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -14,6 +14,7 @@ #include "content/browser/frame_host/render_frame_host_manager.h" #include "content/browser/site_instance_impl.h" #include "content/browser/streams/stream.h" +#include "content/common/frame_messages.h" #include "content/common/navigation_params.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/content_switches.h" @@ -132,10 +133,7 @@ // Add a subframe. FrameTreeNode* root_node = contents()->GetFrameTree()->root(); - TestRenderFrameHost* subframe_rfh = - static_cast<TestRenderFrameHost*>(contents()->GetFrameTree()->AddFrame( - root_node, root_node->current_frame_host()->GetProcess()->GetID(), 14, - "Child")); + TestRenderFrameHost* subframe_rfh = main_test_rfh()->AppendChild("Child"); ASSERT_TRUE(subframe_rfh); FrameTreeNode* subframe_node = subframe_rfh->frame_tree_node(); @@ -148,7 +146,7 @@ GetLoaderForNavigationRequest(subframe_request); ASSERT_TRUE(subframe_request); EXPECT_EQ(kUrl2, subframe_request->common_params().url); - EXPECT_EQ(kUrl2, subframe_loader->common_params().url); + EXPECT_EQ(kUrl2, subframe_loader->request_info()->common_params.url); // First party for cookies url should be that of the main frame. EXPECT_EQ(kUrl1, subframe_loader->request_info()->first_party_for_cookies); EXPECT_FALSE(subframe_loader->request_info()->is_main_frame); @@ -174,7 +172,7 @@ GetLoaderForNavigationRequest(main_request); ASSERT_TRUE(main_request); EXPECT_EQ(kUrl3, main_request->common_params().url); - EXPECT_EQ(kUrl3, main_loader->common_params().url); + EXPECT_EQ(kUrl3, main_loader->request_info()->common_params.url); EXPECT_EQ(kUrl3, main_loader->request_info()->first_party_for_cookies); EXPECT_TRUE(main_loader->request_info()->is_main_frame); EXPECT_FALSE(main_loader->request_info()->parent_is_main_frame); @@ -453,13 +451,13 @@ SendRequestNavigationWithParameters( node, kUrl, Referrer(), ui::PAGE_TRANSITION_LINK, NavigationController::RELOAD); - main_test_rfh()->SendBeginNavigationWithURL(kUrl); // A NavigationRequest should have been generated. NavigationRequest* main_request = GetNavigationRequestForFrameTreeNode(node); ASSERT_TRUE(main_request != NULL); EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD, main_request->common_params().navigation_type); + main_test_rfh()->PrepareForCommit(kUrl); EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); main_test_rfh()->SendNavigate(0, kUrl); @@ -469,12 +467,12 @@ SendRequestNavigationWithParameters( node, kUrl, Referrer(), ui::PAGE_TRANSITION_LINK, NavigationController::RELOAD_IGNORING_CACHE); - main_test_rfh()->SendBeginNavigationWithURL(kUrl); // A NavigationRequest should have been generated. main_request = GetNavigationRequestForFrameTreeNode(node); ASSERT_TRUE(main_request != NULL); EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE, main_request->common_params().navigation_type); + main_test_rfh()->PrepareForCommit(kUrl); EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 420275f0..641793ea 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -10,6 +10,7 @@ #include "base/lazy_instance.h" #include "base/metrics/histogram.h" #include "base/metrics/user_metrics_action.h" +#include "base/process/kill.h" #include "base/time/time.h" #include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/browser_accessibility_manager.h" @@ -143,8 +144,11 @@ routing_id_(routing_id), render_frame_created_(false), navigations_suspended_(false), + has_beforeunload_handlers_(false), + has_unload_handlers_(false), + override_sudden_termination_status_(false), is_waiting_for_beforeunload_ack_(false), - unload_ack_is_for_cross_site_transition_(false), + unload_ack_is_for_navigation_(false), accessibility_reset_token_(0), accessibility_reset_count_(0), no_create_browser_accessibility_manager_for_testing_(false), @@ -198,6 +202,10 @@ // the dtor has run. swapout_event_monitor_timeout_.reset(); + for (const auto& iter: flush_visual_state_callbacks_) { + iter.second.Run(false); + } + if (render_widget_host_) render_widget_host_->Cleanup(); } @@ -343,10 +351,16 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_DocumentOnLoadCompleted, OnDocumentOnLoadCompleted) IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnload_ACK, OnBeforeUnloadACK) + IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnloadHandlersPresent, + OnBeforeUnloadHandlersPresent) + IPC_MESSAGE_HANDLER(FrameHostMsg_UnloadHandlersPresent, + OnUnloadHandlersPresent) IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) IPC_MESSAGE_HANDLER(FrameHostMsg_JavaScriptExecuteResponse, OnJavaScriptExecuteResponse) + IPC_MESSAGE_HANDLER(FrameHostMsg_FlushVisualStateResponse, + OnFlushVisualStateResponse) IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_RunJavaScriptMessage, OnRunJavaScriptMessage) IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_RunBeforeUnloadConfirm, @@ -367,6 +381,9 @@ IPC_MESSAGE_HANDLER(AccessibilityHostMsg_FindInPageResult, OnAccessibilityFindInPageResult) IPC_MESSAGE_HANDLER(FrameHostMsg_ToggleFullscreen, OnToggleFullscreen) + // The following message is synthetic and doesn't come from RenderFrame, but + // from RenderProcessHost. + IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) #if defined(OS_MACOSX) || defined(OS_ANDROID) IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup) IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup) @@ -736,7 +753,7 @@ // old page will soon be stopped. Instead, treat this as a beforeunload ack // to allow the pending navigation to continue. if (is_waiting_for_beforeunload_ack_ && - unload_ack_is_for_cross_site_transition_ && + unload_ack_is_for_navigation_ && ui::PageTransitionIsMainFrame(validated_params.transition)) { base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_; OnBeforeUnloadACK(true, approx_renderer_start_time, base::TimeTicks::Now()); @@ -978,9 +995,17 @@ render_view_host_->StopHangMonitorTimeout(); send_before_unload_start_time_ = base::TimeTicks(); - frame_tree_node_->render_manager()->OnBeforeUnloadACK( - unload_ack_is_for_cross_site_transition_, proceed, - before_unload_end_time); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)) { + // TODO(clamy): see if before_unload_end_time should be transmitted to the + // Navigator. + frame_tree_node_->navigator()->OnBeforeUnloadACK( + frame_tree_node_, proceed); + } else { + frame_tree_node_->render_manager()->OnBeforeUnloadACK( + unload_ack_is_for_navigation_, proceed, + before_unload_end_time); + } // If canceled, notify the delegate to cancel its pending navigation entry. if (!proceed) @@ -1001,10 +1026,46 @@ rfh_state_ == STATE_PENDING_SWAP_OUT; } +bool RenderFrameHostImpl::SuddenTerminationAllowed() const { + return override_sudden_termination_status_ || + (!has_beforeunload_handlers_ && !has_unload_handlers_); +} + void RenderFrameHostImpl::OnSwapOutACK() { OnSwappedOut(); } +void RenderFrameHostImpl::OnRenderProcessGone(int status, int exit_code) { + if (frame_tree_node_->IsMainFrame()) { + // Keep the termination status so we can get at it later when we + // need to know why it died. + render_view_host_->render_view_termination_status_ = + static_cast<base::TerminationStatus>(status); + } + + SetRenderFrameCreated(false); + InvalidateMojoConnection(); + + // Reset frame tree state associated with this process. This must happen + // before RenderViewTerminated because observers expect the subframes of any + // affected frames to be cleared first. + // Note: When a RenderFrameHost is swapped out there is a different one + // which is the current host. In this case, the FrameTreeNode state must + // not be reset. + if (!is_swapped_out()) + frame_tree_node_->ResetForNewProcess(); + + if (frame_tree_node_->IsMainFrame()) { + // RenderViewHost/RenderWidgetHost needs to reset some stuff. + render_view_host_->RendererExited( + render_view_host_->render_view_termination_status_, exit_code); + + render_view_host_->delegate_->RenderViewTerminated( + render_view_host_, static_cast<base::TerminationStatus>(status), + exit_code); + } +} + void RenderFrameHostImpl::OnSwappedOut() { // Ignore spurious swap out ack. if (rfh_state_ != STATE_PENDING_SWAP_OUT) @@ -1057,6 +1118,16 @@ } } +void RenderFrameHostImpl::OnFlushVisualStateResponse(uint64 id) { + auto it = flush_visual_state_callbacks_.find(id); + if (it != flush_visual_state_callbacks_.end()) { + it->second.Run(true); + flush_visual_state_callbacks_.erase(it); + } else { + NOTREACHED() << "Received script response for unknown request"; + } +} + void RenderFrameHostImpl::OnRunJavaScriptMessage( const base::string16& message, const base::string16& default_prompt, @@ -1129,12 +1200,13 @@ } void RenderFrameHostImpl::OnBeginNavigation( - const FrameHostMsg_BeginNavigation_Params& params, - const CommonNavigationParams& common_params) { + const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body) { CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); frame_tree_node()->navigator()->OnBeginNavigation( - frame_tree_node(), params, common_params); + frame_tree_node(), common_params, begin_params, body); } void RenderFrameHostImpl::OnAccessibilityEvents( @@ -1265,6 +1337,14 @@ render_view_host_->WasResized(); } +void RenderFrameHostImpl::OnBeforeUnloadHandlersPresent(bool present) { + has_beforeunload_handlers_ = present; +} + +void RenderFrameHostImpl::OnUnloadHandlersPresent(bool present) { + has_unload_handlers_ = present; +} + #if defined(OS_MACOSX) || defined(OS_ANDROID) void RenderFrameHostImpl::OnShowPopup( const FrameHostMsg_ShowPopup_Params& params) { @@ -1463,13 +1543,19 @@ Send(new FrameMsg_Stop(routing_id_)); } -void RenderFrameHostImpl::DispatchBeforeUnload(bool for_cross_site_transition) { +void RenderFrameHostImpl::DispatchBeforeUnload(bool for_navigation) { // TODO(creis): Support beforeunload on subframes. For now just pretend that // the handler ran and allowed the navigation to proceed. if (GetParent() || !IsRenderFrameLive()) { // We don't have a live renderer, so just skip running beforeunload. - frame_tree_node_->render_manager()->OnBeforeUnloadACK( - for_cross_site_transition, true, base::TimeTicks::Now()); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)) { + frame_tree_node_->navigator()->OnBeforeUnloadACK( + frame_tree_node_, true); + } else { + frame_tree_node_->render_manager()->OnBeforeUnloadACK( + for_navigation, true, base::TimeTicks::Now()); + } return; } TRACE_EVENT_ASYNC_BEGIN0( @@ -1485,13 +1571,13 @@ // (if there was a cross-site "close" request pending when the user clicked // the close button). We want to keep the "for cross site" flag only if // both the old and the new ones are also for cross site. - unload_ack_is_for_cross_site_transition_ = - unload_ack_is_for_cross_site_transition_ && for_cross_site_transition; + unload_ack_is_for_navigation_ = + unload_ack_is_for_navigation_ && for_navigation; } else { // Start the hang monitor in case the renderer hangs in the beforeunload // handler. is_waiting_for_beforeunload_ack_ = true; - unload_ack_is_for_cross_site_transition_ = for_cross_site_transition; + unload_ack_is_for_navigation_ = for_navigation; // Increment the in-flight event count, to ensure that input events won't // cancel the timeout timer. render_view_host_->increment_in_flight_event_count(); @@ -1693,6 +1779,14 @@ } } +void RenderFrameHostImpl::FlushVisualState( + const FlushVisualStateResultCallback& callback) { + static uint64 next_id = 1; + uint64 key = next_id++; + Send(new FrameMsg_FlushVisualStateRequest(routing_id_, key)); + flush_visual_state_callbacks_.insert(std::make_pair(key, callback)); +} + #if defined(OS_WIN) void RenderFrameHostImpl::SetParentNativeViewAccessible(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index e7f1de5..6775bd7 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -63,8 +63,10 @@ class RenderWidgetHostDelegate; class RenderWidgetHostImpl; class RenderWidgetHostView; +class ResourceRequestBody; class StreamHandle; class TimeoutMonitor; +struct BeginNavigationParams; struct CommitNavigationParams; struct CommonNavigationParams; struct ContextMenuParams; @@ -138,6 +140,8 @@ RenderViewHost* GetRenderViewHost() override; ServiceRegistry* GetServiceRegistry() override; blink::WebPageVisibilityState GetVisibilityState() override; + void FlushVisualState( + const FlushVisualStateResultCallback& callback) override; // IPC::Sender bool Send(IPC::Message* msg) override; @@ -266,6 +270,18 @@ // Whether the RFH is waiting for an unload ACK from the renderer. bool IsWaitingForUnloadACK() const; + // Whether sudden termination is allowed for this frame. This is true if there + // are no BeforeUnload handlers or no Unload handlers registered for the + // frame, or it was overriden by the browser to be always true. + bool SuddenTerminationAllowed() const; + + // Called by the browser to override (or not) the sudden termination status of + // the frame. When overriden, sudden termination is always allowed, even if + // it would otherwise be prevented. + void set_override_sudden_termination_status(bool enabled) { + override_sudden_termination_status_ = enabled; + } + // Called when either the SwapOut request has been acknowledged or has timed // out. void OnSwappedOut(); @@ -325,10 +341,11 @@ // RenderFrameHost. void CancelSuspendedNavigations(); - // Runs the beforeunload handler for this frame. |for_cross_site_transition| - // indicates whether this call is for the current frame during a cross-process + // Runs the beforeunload handler for this frame. |for_navigation| indicates + // whether this call is for the current frame during a cross-process // navigation. False means we're closing the entire tab. - void DispatchBeforeUnload(bool for_cross_site_transition); + // PlzNavigate: this call happens on all browser-initiated navigations. + void DispatchBeforeUnload(bool for_navigation); // Set the frame's opener to null in the renderer process in response to an // action in another renderer process. @@ -459,8 +476,10 @@ const base::TimeTicks& renderer_before_unload_start_time, const base::TimeTicks& renderer_before_unload_end_time); void OnSwapOutACK(); + void OnRenderProcessGone(int status, int error_code); void OnContextMenu(const ContextMenuParams& params); void OnJavaScriptExecuteResponse(int id, const base::ListValue& result); + void OnFlushVisualStateResponse(uint64 id); void OnRunJavaScriptMessage(const base::string16& message, const base::string16& default_prompt, const GURL& frame_url, @@ -479,8 +498,9 @@ void OnUpdateTitle(const base::string16& title, blink::WebTextDirection title_direction); void OnUpdateEncoding(const std::string& encoding); - void OnBeginNavigation(const FrameHostMsg_BeginNavigation_Params& params, - const CommonNavigationParams& common_params); + void OnBeginNavigation(const CommonNavigationParams& common_params, + const BeginNavigationParams& begin_params, + scoped_refptr<ResourceRequestBody> body); void OnAccessibilityEvents( const std::vector<AccessibilityHostMsg_EventParams>& params, int reset_token); @@ -489,6 +509,8 @@ void OnAccessibilityFindInPageResult( const AccessibilityHostMsg_FindInPageResultParams& params); void OnToggleFullscreen(bool enter_fullscreen); + void OnBeforeUnloadHandlersPresent(bool present); + void OnUnloadHandlersPresent(bool present); #if defined(OS_MACOSX) || defined(OS_ANDROID) void OnShowPopup(const FrameHostMsg_ShowPopup_Params& params); @@ -577,6 +599,8 @@ // The mapping of pending JavaScript calls created by // ExecuteJavaScript and their corresponding callbacks. std::map<int, JavaScriptResultCallback> javascript_callbacks_; + std::map<uint64, FlushVisualStateResultCallback> + flush_visual_state_callbacks_; // RenderFrameHosts that need management of the rendering and input events // for their frame subtrees require RenderWidgetHosts. This typically @@ -612,6 +636,17 @@ // When the last BeforeUnload message was sent. base::TimeTicks send_before_unload_start_time_; + // Used to track whether sudden termination is allowed for this frame. + // has_beforeunload_handlers_ and has_unload_handlers_ are also used to avoid + // asking the renderer process to run BeforeUnload or Unload during + // navigation. The browser can set override_sudden_termination_status_ to + // true, in which case sudden termination will be allowed. This is used when a + // renderer executing BeforeUnload or Unload is unresponsive. All other values + // are modified based on IPCs received from the renderer. + bool has_beforeunload_handlers_; + bool has_unload_handlers_; + bool override_sudden_termination_status_; + // Set to true when there is a pending FrameMsg_ShouldClose message. This // ensures we don't spam the renderer with multiple beforeunload requests. // When either this value or IsWaitingForUnloadACK is true, the value of @@ -624,8 +659,10 @@ // Valid only when is_waiting_for_beforeunload_ack_ or // IsWaitingForUnloadACK is true. This tells us if the unload request // is for closing the entire tab ( = false), or only this RenderFrameHost in - // the case of a cross-site transition ( = true). - bool unload_ack_is_for_cross_site_transition_; + // the case of a navigation ( = true). Currently only cross-site navigations + // require a beforeUnload/unload ACK. + // PlzNavigate: all navigations require a beforeUnload ACK. + bool unload_ack_is_for_navigation_; // Used to swap out or shut down this RFH when the unload event is taking too // long to execute, depending on the number of active frames in the
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 4a9034b5..0cd3b53 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -715,6 +715,22 @@ // --site-per-process is enabled. CleanUpNavigation(); navigation_rfh = render_frame_host_.get(); + + // As SiteInstances are the same, check if the WebUI should be reused. + const NavigationEntry* current_navigation_entry = + delegate_->GetLastCommittedNavigationEntryForRenderManager(); + bool should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, + request.common_params().url); + if (!should_reuse_web_ui_) { + speculative_web_ui_ = CreateWebUI(request.common_params().url, + request.bindings()); + // Make sure the current RenderViewHost has the right bindings. + if (speculative_web_ui() && + !render_frame_host_->GetProcess()->IsIsolatedGuest()) { + render_frame_host_->render_view_host()->AllowBindings( + speculative_web_ui()->GetBindings()); + } + } } else { // If the SiteInstance for the final URL doesn't match the one from the // speculatively created RenderFrameHost, create a new RenderFrameHost using @@ -763,6 +779,10 @@ // PlzNavigate void RenderFrameHostManager::CleanUpNavigation() { + CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)); + speculative_web_ui_.reset(); + should_reuse_web_ui_ = false; if (speculative_render_frame_host_) DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); } @@ -772,8 +792,6 @@ RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); - speculative_web_ui_.reset(); - should_reuse_web_ui_ = false; speculative_render_frame_host_->GetProcess()->RemovePendingView(); return speculative_render_frame_host_.Pass(); } @@ -844,6 +862,12 @@ } bool RenderFrameHostManager::ShouldTransitionCrossSite() { + // True for --site-per-process, which overrides both kSingleProcess and + // kProcessPerTab. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSitePerProcess)) + return true; + // False in the single-process mode, as it makes RVHs to accumulate // in swapped_out_hosts_. // True if we are using process-per-site-instance (default) or @@ -1264,15 +1288,12 @@ int bindings) { CHECK(new_instance); CHECK_NE(old_instance, new_instance); + CHECK(!should_reuse_web_ui_); - const NavigationEntry* current_navigation_entry = - delegate_->GetLastCommittedNavigationEntryForRenderManager(); - // Note: |should_reuse_web_ui_| and |speculative_web_ui_| must be initialized - // before trying to create the |speculative_render_frame_host_|. Otherwise the - // WebUI won't be properly initialized. - bool should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url); - if (!should_reuse_web_ui_) - speculative_web_ui_ = CreateWebUI(url, bindings); + // Note: |speculative_web_ui_| must be initialized before starting the + // |speculative_render_frame_host_| creation steps otherwise the WebUI + // won't be properly initialized. + speculative_web_ui_ = CreateWebUI(url, bindings); int create_render_frame_flags = 0; int opener_route_id = @@ -1288,7 +1309,6 @@ opener_route_id, create_render_frame_flags, nullptr); if (!speculative_render_frame_host_) { - should_reuse_web_ui_ = false; speculative_web_ui_.reset(); return false; } @@ -1721,6 +1741,8 @@ const NavigationEntry* current_entry = delegate_->GetLastCommittedNavigationEntryForRenderManager(); + DCHECK(!cross_navigation_pending_); + if (new_instance.get() != current_instance) { TRACE_EVENT_INSTANT2( "navigation", @@ -1730,7 +1752,6 @@ "new_instance id", new_instance->GetId()); // New SiteInstance: create a pending RFH to navigate. - DCHECK(!cross_navigation_pending_); // This will possibly create (set to nullptr) a Web UI object for the // pending page. We'll use this later to give the page special access. This @@ -1799,7 +1820,6 @@ } // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. - DCHECK(!cross_navigation_pending_); // It's possible to swap out the current RFH and then decide to navigate in it // anyway (e.g., a cross-process navigation that redirects back to the
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 59b4d77..15338be2 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -237,7 +237,7 @@ // PlzNavigate // Returns the speculative WebUI for the navigation (a newly created one or // the current one if it should be reused). If none is set returns nullptr. - WebUIImpl* speculative_web_ui_for_testing() const { + WebUIImpl* speculative_web_ui() const { return should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); }
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 52d99af..34e48e5 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -381,9 +381,9 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)) { scoped_ptr<NavigationRequest> navigation_request = - NavigationRequest::Create(manager->frame_tree_node_, entry, - FrameMsg_Navigate_Type::NORMAL, - base::TimeTicks::Now()); + NavigationRequest::CreateBrowserInitiated( + manager->frame_tree_node_, entry, FrameMsg_Navigate_Type::NORMAL, + base::TimeTicks::Now()); return manager->GetFrameHostForNavigation(*navigation_request); } return manager->Navigate(entry); @@ -973,7 +973,7 @@ // used yet. UpdateStateForNavigate() took the short cut path. if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)) { - EXPECT_FALSE(manager->speculative_web_ui_for_testing()); + EXPECT_FALSE(manager->speculative_web_ui()); } else { EXPECT_FALSE(manager->pending_web_ui()); } @@ -1033,6 +1033,7 @@ // RenderWidgetHost::Init when opening a new tab from a link. manager2->current_host()->CreateRenderView( base::string16(), -1, MSG_ROUTING_NONE, -1, false); + EXPECT_TRUE(manager2->current_host()->IsRenderViewLive()); const GURL kUrl2("chrome://foo/bar"); NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, @@ -1044,6 +1045,12 @@ // No cross-process transition happens because we are already in the right // SiteInstance. We should grant bindings immediately. EXPECT_EQ(host2, manager2->current_frame_host()); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)) { + EXPECT_TRUE(manager2->speculative_web_ui()); + } else { + EXPECT_TRUE(manager2->pending_web_ui()); + } EXPECT_TRUE( host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.cc b/content/browser/indexed_db/leveldb/leveldb_database.cc index fa62e1c..51a8aea 100644 --- a/content/browser/indexed_db/leveldb/leveldb_database.cc +++ b/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -103,7 +103,7 @@ options.create_if_missing = true; options.paranoid_checks = true; options.filter_policy = filter_policy->get(); - options.reuse_logs = false; + options.reuse_logs = true; options.compression = leveldb::kSnappyCompression; // For info about the troubles we've run into with this parameter, see:
diff --git a/content/browser/loader/navigation_url_loader.cc b/content/browser/loader/navigation_url_loader.cc index 350ffc2..4565c94 100644 --- a/content/browser/loader/navigation_url_loader.cc +++ b/content/browser/loader/navigation_url_loader.cc
@@ -15,18 +15,14 @@ scoped_ptr<NavigationURLLoader> NavigationURLLoader::Create( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate) { if (g_factory) { return g_factory->CreateLoader(browser_context, frame_tree_node_id, - common_params, request_info.Pass(), - request_body, delegate); + request_info.Pass(), delegate); } return scoped_ptr<NavigationURLLoader>(new NavigationURLLoaderImpl( - browser_context, frame_tree_node_id, common_params, request_info.Pass(), - request_body, delegate)); + browser_context, frame_tree_node_id, request_info.Pass(), delegate)); } void NavigationURLLoader::SetFactoryForTesting(
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h index 7713e73..1043c68 100644 --- a/content/browser/loader/navigation_url_loader.h +++ b/content/browser/loader/navigation_url_loader.h
@@ -15,7 +15,6 @@ class BrowserContext; class NavigationURLLoaderDelegate; class NavigationURLLoaderFactory; -class ResourceRequestBody; struct CommonNavigationParams; struct NavigationRequestInfo; @@ -36,9 +35,7 @@ static scoped_ptr<NavigationURLLoader> Create( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate); // For testing purposes; sets the factory for use in testing.
diff --git a/content/browser/loader/navigation_url_loader_factory.h b/content/browser/loader/navigation_url_loader_factory.h index ddb4fe1d..afa8fed 100644 --- a/content/browser/loader/navigation_url_loader_factory.h +++ b/content/browser/loader/navigation_url_loader_factory.h
@@ -18,9 +18,7 @@ virtual scoped_ptr<NavigationURLLoader> CreateLoader( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate) = 0; protected:
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 949d630..658c4dc 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -18,9 +18,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate) : delegate_(delegate), weak_factory_(this) { @@ -31,8 +29,7 @@ BrowserThread::IO, FROM_HERE, base::Bind(&NavigationURLLoaderImplCore::Start, base::Unretained(core_), browser_context->GetResourceContext(), frame_tree_node_id, - common_params, base::Passed(&request_info), - make_scoped_refptr(request_body))); + base::Passed(&request_info))); } NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 7dba1185..2182f09a 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -27,9 +27,7 @@ // The caller is responsible for ensuring that |delegate| outlives the loader. NavigationURLLoaderImpl(BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate); ~NavigationURLLoaderImpl() override;
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc index c8e681e..cf968ce8 100644 --- a/content/browser/loader/navigation_url_loader_impl_core.cc +++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -38,9 +38,7 @@ void NavigationURLLoaderImplCore::Start( ResourceContext* resource_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, - scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body) { + scoped_ptr<NavigationRequestInfo> request_info) { DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( @@ -50,8 +48,7 @@ ResourceDispatcherHostImpl::Get()->BeginNavigationRequest( resource_context, frame_tree_node_id, - common_params, *request_info, request_body, - this); + *request_info, this); } void NavigationURLLoaderImplCore::FollowRedirect() {
diff --git a/content/browser/loader/navigation_url_loader_impl_core.h b/content/browser/loader/navigation_url_loader_impl_core.h index f31d3cc..a1e15cb 100644 --- a/content/browser/loader/navigation_url_loader_impl_core.h +++ b/content/browser/loader/navigation_url_loader_impl_core.h
@@ -41,9 +41,7 @@ // Starts the request. void Start(ResourceContext* resource_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, - scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body); + scoped_ptr<NavigationRequestInfo> request_info); // Follows the current pending redirect. void FollowRedirect();
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index 745afe82..3f899f3 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -24,6 +24,7 @@ #include "content/public/common/resource_response.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/url_request/redirect_info.h" @@ -176,18 +177,16 @@ scoped_ptr<NavigationURLLoader> MakeTestLoader( const GURL& url, NavigationURLLoaderDelegate* delegate) { - FrameHostMsg_BeginNavigation_Params begin_params; + BeginNavigationParams begin_params( + "GET", std::string(), net::LOAD_NORMAL, false); CommonNavigationParams common_params; - begin_params.method = "GET"; common_params.url = url; scoped_ptr<NavigationRequestInfo> request_info( - new NavigationRequestInfo(begin_params)); - request_info->first_party_for_cookies = url; - request_info->is_main_frame = true; + new NavigationRequestInfo(common_params, begin_params, url, true, false, + scoped_refptr<ResourceRequestBody>())); return NavigationURLLoader::Create( - browser_context_.get(), 0, - common_params, request_info.Pass(), nullptr, delegate); + browser_context_.get(), 0, request_info.Pass(), delegate); } // Helper function for fetching the body of a URL to a string.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index ddb8a09..5d63cfa 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -21,6 +21,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/metrics/sparse_histogram.h" +#include "base/profiler/scoped_tracker.h" #include "base/stl_util.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "content/browser/appcache/appcache_interceptor.h" @@ -976,6 +977,10 @@ int routing_id, int request_id, const ResourceHostMsg_Request& request_data) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::OnRequestResource")); // When logging time-to-network only care about main frame and non-transfer // navigations. if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME && @@ -1091,6 +1096,10 @@ const ResourceHostMsg_Request& request_data, IPC::Message* sync_result, // only valid for sync int route_id) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest1")); int process_type = filter_->process_type(); int child_id = filter_->child_id(); @@ -1111,6 +1120,11 @@ // If the request that's coming in is being transferred from another process, // we want to reuse and resume the old loader rather than start a new one. { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest2")); LoaderMap::iterator it = pending_loaders_.find( GlobalRequestID(request_data.transferred_request_child_id, request_data.transferred_request_request_id)); @@ -1131,6 +1145,10 @@ } } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest3")); ResourceContext* resource_context = NULL; net::URLRequestContext* request_context = NULL; filter_->GetContexts(request_data, &resource_context, &request_context); @@ -1153,6 +1171,10 @@ return; } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest4")); // Construct the request. net::CookieStore* cookie_store = GetContentClient()->browser()->OverrideCookieStoreForRenderProcess( @@ -1179,6 +1201,10 @@ headers.AddHeadersFromString(request_data.headers); new_request->SetExtraRequestHeaders(headers); + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile5( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest5")); storage::BlobStorageContext* blob_context = GetBlobStorageContext(filter_->blob_storage_context()); // Resolve elements from request_body and prepare upload data. @@ -1202,6 +1228,10 @@ .get())); } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile6( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest6")); bool allow_download = request_data.allow_download && IsResourceTypeFrame(request_data.resource_type); bool do_not_prompt_for_login = request_data.do_not_prompt_for_login; @@ -1277,6 +1307,10 @@ new_request->url())); } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile7( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequest7")); // Initialize the service worker handler for the request. We don't use // ServiceWorker for synchronous loads to avoid renderer deadlocks. ServiceWorkerRequestHandler::InitializeHandler( @@ -1848,9 +1882,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( ResourceContext* resource_context, int64 frame_tree_node_id, - const CommonNavigationParams& params, const NavigationRequestInfo& info, - scoped_refptr<ResourceRequestBody> request_body, NavigationURLLoaderImplCore* loader) { // PlzNavigate: BeginNavigationRequest currently should only be used for the // browser-side navigations project. @@ -1865,8 +1897,8 @@ // needs to be checked relative to the child that /requested/ the // navigation. It's where file upload checks, etc., come in. (delegate_ && !delegate_->ShouldBeginRequest( - info.navigation_params.method, - params.url, + info.begin_params.method, + info.common_params.url, resource_type, resource_context))) { loader->NotifyRequestFailed(net::ERR_ABORTED); @@ -1876,14 +1908,15 @@ // Save the URL on the stack to help catch URLRequests which outlive their // URLRequestContexts. See https://crbug.com/90971 char url_buf[128]; - base::strlcpy(url_buf, params.url.spec().c_str(), arraysize(url_buf)); + base::strlcpy( + url_buf, info.common_params.url.spec().c_str(), arraysize(url_buf)); base::debug::Alias(url_buf); CHECK(ContainsKey(active_resource_contexts_, resource_context)); const net::URLRequestContext* request_context = resource_context->GetRequestContext(); - int load_flags = info.navigation_params.load_flags; + int load_flags = info.begin_params.load_flags; load_flags |= net::LOAD_VERIFY_EV_CERT; if (info.is_main_frame) { load_flags |= net::LOAD_MAIN_FRAME; @@ -1905,10 +1938,10 @@ // prerender. There may not be a renderer process yet, so we need to use the // ResourceContext or something. scoped_ptr<net::URLRequest> new_request; - new_request = request_context->CreateRequest(params.url, net::HIGHEST, - nullptr, nullptr); + new_request = request_context->CreateRequest( + info.common_params.url, net::HIGHEST, nullptr, nullptr); - new_request->set_method(info.navigation_params.method); + new_request->set_method(info.begin_params.method); new_request->set_first_party_for_cookies( info.first_party_for_cookies); if (info.is_main_frame) { @@ -1916,26 +1949,26 @@ net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); } - SetReferrerForRequest(new_request.get(), params.referrer); + SetReferrerForRequest(new_request.get(), info.common_params.referrer); net::HttpRequestHeaders headers; - headers.AddHeadersFromString(info.navigation_params.headers); + headers.AddHeadersFromString(info.begin_params.headers); new_request->SetExtraRequestHeaders(headers); new_request->SetLoadFlags(load_flags); // Resolve elements from request_body and prepare upload data. - if (info.navigation_params.request_body.get()) { + if (info.request_body.get()) { storage::BlobStorageContext* blob_context = GetBlobStorageContext( GetChromeBlobStorageContextForResourceContext(resource_context)); AttachRequestBodyBlobDataHandles( - info.navigation_params.request_body.get(), + info.request_body.get(), blob_context); // TODO(davidben): The FileSystemContext is null here. In the case where // another renderer requested this navigation, this should be the same // FileSystemContext passed into ShouldServiceRequest. new_request->set_upload(UploadDataStreamBuilder::Build( - info.navigation_params.request_body.get(), + info.request_body.get(), blob_context, nullptr, // file_system_context BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) @@ -1960,18 +1993,18 @@ info.parent_is_main_frame, -1, // request_data.parent_render_frame_id, resource_type, - params.transition, + info.common_params.transition, // should_replace_current_entry. This was only maintained at layer for // request transfers and isn't needed for browser-side navigations. false, false, // is download false, // is stream - params.allow_download, - info.navigation_params.has_user_gesture, + info.common_params.allow_download, + info.begin_params.has_user_gesture, true, // enable_load_timing false, // enable_upload_progress false, // do_not_prompt_for_login - params.referrer.policy, + info.common_params.referrer.policy, // TODO(davidben): This is only used for prerenders. Replace // is_showing with something for that. Or maybe it just comes from the // same mechanism as the cookie one. @@ -2031,6 +2064,10 @@ void ResourceDispatcherHostImpl::BeginRequestInternal( scoped_ptr<net::URLRequest> request, scoped_ptr<ResourceHandler> handler) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456331 ResourceDispatcherHostImpl::BeginRequestInternal")); DCHECK(!request->is_pending()); ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request.get()); @@ -2152,6 +2189,11 @@ } // namespace void ResourceDispatcherHostImpl::UpdateLoadStates() { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ResourceDispatcherHostImpl::UpdateLoadStates")); // Populate this map with load state changes, and then send them on to the UI // thread where they can be passed along to the respective RVHs. LoadInfoMap info_map;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index 34d02a3..0a77da38 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -263,9 +263,7 @@ // loader to attach to the leaf resource handler. void BeginNavigationRequest(ResourceContext* resource_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, const NavigationRequestInfo& info, - scoped_refptr<ResourceRequestBody> request_body, NavigationURLLoaderImplCore* loader); private:
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index b462a68..f1157bda 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -146,6 +146,11 @@ } void ResourceLoader::ReportUploadProgress() { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ResourceLoader::ReportUploadProgress")); if (waiting_for_upload_progress_ack_) return; // Send one progress event at a time.
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index b31d26a..75b08dc 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -284,8 +284,10 @@ // If a page has a manifest and the page is navigated to a page without a // manifest, the page's manifest should be updated. IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) { + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); { - GURL test_url = GetTestUrl("manifest", "dummy-manifest.html"); + GURL test_url = + embedded_test_server()->GetURL("/manifest/dummy-manifest.html"); TestNavigationObserver navigation_observer(shell()->web_contents(), 1); shell()->LoadURL(test_url); @@ -297,7 +299,8 @@ } { - GURL test_url = GetTestUrl("manifest", "no-manifest.html"); + GURL test_url = + embedded_test_server()->GetURL("/manifest/no-manifest.html"); TestNavigationObserver navigation_observer(shell()->web_contents(), 1); shell()->LoadURL(test_url);
diff --git a/content/browser/media/cdm/browser_cdm_manager.cc b/content/browser/media/cdm/browser_cdm_manager.cc index 358f42f..72da3079 100644 --- a/content/browser/media/cdm/browser_cdm_manager.cc +++ b/content/browser/media/cdm/browser_cdm_manager.cc
@@ -184,7 +184,8 @@ return handled; } -media::BrowserCdm* BrowserCdmManager::GetCdm(int render_frame_id, int cdm_id) { +media::BrowserCdm* BrowserCdmManager::GetCdm(int render_frame_id, + int cdm_id) const { DCHECK(task_runner_->RunsTasksOnCurrentThread()); return cdm_map_.get(GetId(render_frame_id, cdm_id)); }
diff --git a/content/browser/media/cdm/browser_cdm_manager.h b/content/browser/media/cdm/browser_cdm_manager.h index 9872306..e7c87c9b 100644 --- a/content/browser/media/cdm/browser_cdm_manager.h +++ b/content/browser/media/cdm/browser_cdm_manager.h
@@ -50,7 +50,7 @@ const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override; - media::BrowserCdm* GetCdm(int render_frame_id, int cdm_id); + media::BrowserCdm* GetCdm(int render_frame_id, int cdm_id) const; // Notifies that the render frame has been deleted so that all CDMs belongs // to this render frame needs to be destroyed as well. This is needed because
diff --git a/content/browser/media/media_canplaytype_browsertest.cc b/content/browser/media/media_canplaytype_browsertest.cc index 8dd11e75..f0f83af 100644 --- a/content/browser/media/media_canplaytype_browsertest.cc +++ b/content/browser/media/media_canplaytype_browsertest.cc
@@ -31,12 +31,12 @@ const char kOggVideoProbably[] = "probably"; const char kOggVideoMaybe[] = "maybe"; const char kTheoraProbably[] = "probably"; -const char kOpusProbably[] = "probably"; +const char kOggOpusProbably[] = "probably"; #else const char kOggVideoProbably[] = ""; const char kOggVideoMaybe[] = ""; const char kTheoraProbably[] = ""; -const char kOpusProbably[] = ""; +const char kOggOpusProbably[] = ""; #endif // !OS_ANDROID namespace content { @@ -261,13 +261,18 @@ } IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_webm) { - // On Android, VP9 is supported only on KitKat and above (API level 19). + // On Android, VP9 is supported only on KitKat and above (API level 19) and + // Opus is supported only on Lollipop and above (API level 21). std::string VP9Probably = "probably"; std::string VP9AndOpusProbably = "probably"; + std::string OpusProbably = "probably"; #if defined(OS_ANDROID) - VP9AndOpusProbably = ""; if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) VP9Probably = ""; + if (base::android::BuildInfo::GetInstance()->sdk_int() < 21) { + OpusProbably = ""; + VP9AndOpusProbably = ""; + } #endif EXPECT_EQ(kMaybe, CanPlay("'video/webm'")); @@ -275,8 +280,8 @@ EXPECT_EQ(kProbably, CanPlay("'video/webm; codecs=\"vp8.0\"'")); EXPECT_EQ(kProbably, CanPlay("'video/webm; codecs=\"vp8, vorbis\"'")); EXPECT_EQ(kProbably, CanPlay("'video/webm; codecs=\"vp8.0, vorbis\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'video/webm; codecs=\"vp8, opus\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'video/webm; codecs=\"vp8.0, opus\"'")); + EXPECT_EQ(OpusProbably, CanPlay("'video/webm; codecs=\"vp8, opus\"'")); + EXPECT_EQ(OpusProbably, CanPlay("'video/webm; codecs=\"vp8.0, opus\"'")); EXPECT_EQ(VP9Probably, CanPlay("'video/webm; codecs=\"vp9\"'")); EXPECT_EQ(VP9Probably, CanPlay("'video/webm; codecs=\"vp9.0\"'")); @@ -293,8 +298,8 @@ EXPECT_EQ(kMaybe, CanPlay("'audio/webm'")); EXPECT_EQ(kProbably, CanPlay("'audio/webm; codecs=\"vorbis\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'audio/webm; codecs=\"opus\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'audio/webm; codecs=\"opus, vorbis\"'")); + EXPECT_EQ(OpusProbably, CanPlay("'audio/webm; codecs=\"opus\"'")); + EXPECT_EQ(OpusProbably, CanPlay("'audio/webm; codecs=\"opus, vorbis\"'")); EXPECT_EQ(kNot, CanPlay("'audio/webm; codecs=\"vp8\"'")); EXPECT_EQ(kNot, CanPlay("'audio/webm; codecs=\"vp8.0\"'")); @@ -327,8 +332,8 @@ EXPECT_EQ(kMaybe, CanPlay("'audio/ogg'")); EXPECT_EQ(kProbably, CanPlay("'audio/ogg; codecs=\"vorbis\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'audio/ogg; codecs=\"opus\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'audio/ogg; codecs=\"vorbis, opus\"'")); + EXPECT_EQ(kOggOpusProbably, CanPlay("'audio/ogg; codecs=\"opus\"'")); + EXPECT_EQ(kOggOpusProbably, CanPlay("'audio/ogg; codecs=\"vorbis, opus\"'")); EXPECT_EQ(kNot, CanPlay("'audio/ogg; codecs=\"theora\"'")); EXPECT_EQ(kNot, CanPlay("'audio/ogg; codecs=\"theora, opus\"'")); @@ -339,12 +344,12 @@ EXPECT_EQ(kMaybe, CanPlay("'application/ogg'")); EXPECT_EQ(kProbably, CanPlay("'application/ogg; codecs=\"vorbis\"'")); EXPECT_EQ(kTheoraProbably, CanPlay("'application/ogg; codecs=\"theora\"'")); - EXPECT_EQ(kOpusProbably, CanPlay("'application/ogg; codecs=\"opus\"'")); + EXPECT_EQ(kOggOpusProbably, CanPlay("'application/ogg; codecs=\"opus\"'")); EXPECT_EQ(kTheoraProbably, CanPlay("'application/ogg; codecs=\"theora, vorbis\"'")); EXPECT_EQ(kTheoraProbably, CanPlay("'application/ogg; codecs=\"theora, opus\"'")); - EXPECT_EQ(kOpusProbably, + EXPECT_EQ(kOggOpusProbably, CanPlay("'application/ogg; codecs=\"opus, vorbis\"'")); TestOGGUnacceptableCombinations("application/ogg");
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc index e2a5ede..b5a93516 100644 --- a/content/browser/media/media_internals.cc +++ b/content/browser/media/media_internals.cc
@@ -42,6 +42,7 @@ { media::AudioParameters::ECHO_CANCELLER, "ECHO_CANCELLER" }, { media::AudioParameters::DUCKING, "DUCKING" }, { media::AudioParameters::KEYBOARD_MIC, "KEYBOARD_MIC" }, + { media::AudioParameters::HOTWORD, "HOTWORD" }, }; std::string ret; @@ -63,6 +64,22 @@ return ret; } +std::string FormatToString(media::AudioParameters::Format format) { + switch (format) { + case media::AudioParameters::AUDIO_PCM_LINEAR: + return "pcm_linear"; + case media::AudioParameters::AUDIO_PCM_LOW_LATENCY: + return "pcm_low_latency"; + case media::AudioParameters::AUDIO_FAKE: + return "fake"; + case media::AudioParameters::AUDIO_LAST_FORMAT: + break; + } + + NOTREACHED(); + return "unknown"; +} + const char kAudioLogStatusKey[] = "status"; const char kAudioLogUpdateFunction[] = "media.updateAudioComponent"; @@ -117,6 +134,7 @@ dict.SetString(kAudioLogStatusKey, "created"); dict.SetString("device_id", device_id); + dict.SetString("device_type", FormatToString(params.format())); dict.SetInteger("frames_per_buffer", params.frames_per_buffer()); dict.SetInteger("sample_rate", params.sample_rate()); dict.SetInteger("channels", params.channels());
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc index cb2f98ea..b642380e 100644 --- a/content/browser/net/sqlite_persistent_cookie_store.cc +++ b/content/browser/net/sqlite_persistent_cookie_store.cc
@@ -21,6 +21,7 @@ #include "base/memory/scoped_ptr.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" +#include "base/profiler/scoped_tracker.h" #include "base/sequenced_task_runner.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -507,6 +508,11 @@ void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground( const LoadedCallback& loaded_callback, bool load_success) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456373 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456373 SQLitePersistentCookieStore::Backend::" + "CompleteLoadForKeyInForeground")); DCHECK(client_task_runner_->RunsTasksOnCurrentThread()); Notify(loaded_callback, load_success);
diff --git a/content/browser/notifications/notification_message_filter.h b/content/browser/notifications/notification_message_filter.h index 95c06ba..a22ab49 100644 --- a/content/browser/notifications/notification_message_filter.h +++ b/content/browser/notifications/notification_message_filter.h
@@ -9,7 +9,7 @@ #include "base/callback_forward.h" #include "content/public/browser/browser_message_filter.h" -#include "third_party/WebKit/public/platform/WebNotificationPermission.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h" class GURL; class SkBitmap;
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc index bec7730..ab3b96a 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.cc +++ b/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -19,7 +19,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/push_messaging_service.h" #include "content/public/common/child_process_host.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" namespace content { namespace {
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index dbcdc66..ce81267 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -67,8 +67,8 @@ void DidBeginMainFrame() override {} void BeginMainFrame(const cc::BeginFrameArgs& args) override {} void Layout() override; - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {}
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc index 9c5d610..f680448 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.cc +++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -124,10 +124,6 @@ CHILDID_SELF); } - // http://crbug.com/440579 TODO(dmazzoni): remove this logging when - // flakiness is fixed. - LOG(INFO) << "LegacyRenderWidgetHostHWND::Init hwnd=" << hwnd(); - return !!SUCCEEDED(hr); } @@ -151,15 +147,6 @@ // because it sometimes gets sign-extended incorrectly (but not always). DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param)); - // http://crbug.com/440579 TODO(dmazzoni): remove this logging when - // flakiness is fixed. - LOG(INFO) << "LegacyRenderWidgetHostHWND::OnGetObject" - << " message=" << message - << " w_param=" << w_param - << " l_param=" << l_param - << " obj_id=" << obj_id - << " host_=" << host_; - if (kIdScreenReaderHoneyPot == obj_id) { // When an MSAA client has responded to our fake event on this id, // enable screen reader support. @@ -172,18 +159,14 @@ RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( host_->GetRenderWidgetHost()); - if (!rwhi) { - LOG(WARNING) << "No RWHI"; + if (!rwhi) return static_cast<LRESULT>(0L); - } BrowserAccessibilityManagerWin* manager = static_cast<BrowserAccessibilityManagerWin*>( rwhi->GetRootBrowserAccessibilityManager()); - if (!manager) { - LOG(WARNING) << "No manager"; + if (!manager) return static_cast<LRESULT>(0L); - } base::win::ScopedComPtr<IAccessible> root( manager->GetRoot()->ToBrowserAccessibilityWin());
diff --git a/content/browser/renderer_host/render_process_host_browsertest.cc b/content/browser/renderer_host/render_process_host_browsertest.cc index 18a187af..e63e8107 100644 --- a/content/browser/renderer_host/render_process_host_browsertest.cc +++ b/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -103,8 +103,7 @@ // Navigate to a different page. GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); GURL another_url = embedded_test_server()->GetURL("/simple_page.html"); another_url = another_url.ReplaceComponents(replace_host); NavigateToURL(CreateBrowser(), another_url);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3223ecb..83039295 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -107,6 +107,7 @@ #include "content/common/child_process_host_impl.h" #include "content/common/child_process_messages.h" #include "content/common/content_switches_internal.h" +#include "content/common/frame_messages.h" #include "content/common/gpu/gpu_memory_buffer_factory.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/mojo/mojo_messages.h" @@ -970,6 +971,14 @@ } } +#if defined(ENABLE_BROWSER_CDMS) +media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id, + int cdm_id) const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return browser_cdm_manager_->GetCdm(render_frame_id, cdm_id); +} +#endif + void RenderProcessHostImpl::AddRoute( int32 routing_id, IPC::Listener* listener) { @@ -1191,6 +1200,7 @@ switches::kDisableAcceleratedJpegDecoding, switches::kDisableAcceleratedVideoDecode, switches::kDisableBlinkScheduler, + switches::kDisableBlinkFeatures, switches::kDisableBreakpad, switches::kDisablePreferCompositingToLCDText, switches::kDisableDatabases, @@ -1223,6 +1233,7 @@ switches::kDomAutomationController, switches::kEnableBeginFrameScheduling, switches::kEnableBleedingEdgeRenderingFastPaths, + switches::kEnableBlinkFeatures, switches::kEnableBrowserSideNavigation, switches::kEnablePreferCompositingToLCDText, switches::kEnableCredentialManagerAPI, @@ -1493,7 +1504,7 @@ IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone, OnDumpHandlesDone) IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged, - SuddenTerminationChanged) + OnSuddenTerminationChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, OnUserMetricsRecordAction) IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML) @@ -1658,10 +1669,6 @@ pending_views_--; } -void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) { - sudden_termination_allowed_ = enabled; -} - bool RenderProcessHostImpl::SuddenTerminationAllowed() const { return sudden_termination_allowed_; } @@ -2068,19 +2075,17 @@ #endif RemoveUserData(kSessionStorageHolderKey); - // RenderProcessGone handlers might navigate or perform other actions that - // require a connection. Ensure that there is one before calling them. - mojo_application_host_.reset(new MojoApplicationHost); - IDMap<IPC::Listener>::iterator iter(&listeners_); while (!iter.IsAtEnd()) { iter.GetCurrentValue()->OnMessageReceived( - ViewHostMsg_RenderProcessGone(iter.GetCurrentKey(), - static_cast<int>(status), - exit_code)); + FrameHostMsg_RenderProcessGone(iter.GetCurrentKey(), + static_cast<int>(status), + exit_code)); iter.Advance(); } + mojo_application_host_.reset(new MojoApplicationHost); + // It's possible that one of the calls out to the observers might have caused // this object to be no longer needed. if (delayed_cleanup_needed_) @@ -2170,8 +2175,8 @@ Send(new ChildProcessMsg_Shutdown()); } -void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { - SetSuddenTerminationAllowed(enabled); +void RenderProcessHostImpl::OnSuddenTerminationChanged(bool enabled) { + sudden_termination_allowed_ = enabled; } void RenderProcessHostImpl::OnDumpHandlesDone() {
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 1ed902d..43a40bc9 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -121,7 +121,6 @@ void Cleanup() override; void AddPendingView() override; void RemovePendingView() override; - void SetSuddenTerminationAllowed(bool enabled) override; bool SuddenTerminationAllowed() const override; IPC::ChannelProxy* GetChannel() override; void AddFilter(BrowserMessageFilter* filter) override; @@ -149,6 +148,10 @@ void OnRemoveSubscription(unsigned int target) override; void SendUpdateValueState( unsigned int target, const gpu::ValueState& state) override; +#if defined(ENABLE_BROWSER_CDMS) + media::BrowserCdm* GetBrowserCdm(int render_frame_id, + int cdm_id) const override; +#endif // IPC::Sender via RenderProcessHost. bool Send(IPC::Message* msg) override; @@ -314,7 +317,7 @@ // Control message handlers. void OnShutdownRequest(); void OnDumpHandlesDone(); - void SuddenTerminationChanged(bool enabled); + void OnSuddenTerminationChanged(bool enabled); void OnUserMetricsRecordAction(const std::string& action); void OnSavedPageAsMHTML(int job_id, int64 mhtml_file_size); void OnCloseACK(int old_route_id); @@ -415,12 +418,12 @@ // The observers watching our lifetime. ObserverList<RenderProcessHostObserver> observers_; - // True if the process can be shut down suddenly. If this is true, then we're - // sure that all the RenderViews in the process can be shutdown suddenly. If - // it's false, then specific RenderViews might still be allowed to be shutdown - // suddenly by checking their SuddenTerminationAllowed() flag. This can occur - // if one WebContents has an unload event listener but another WebContents in - // the same process doesn't. + // True if the process can be shut down suddenly. If this is true, then it's + // sure that all the RenderFrames in the process can be shutdown suddenly. If + // it's false, then specific RenderFrames might still be allowed to be + // shutdown suddenly by checking their SuddenTerminationAllowed() flag. This + // can occur when a RenderFrame has an unload/beforeUnload event listener + // registered but another RenderFrame in the same process doesn't. bool sudden_termination_allowed_; // Set to true if we shouldn't send input events. We actually do the
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 2be0fc0..14e1545 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -125,6 +125,19 @@ } #endif +// Enable sudden termination for the current RenderFrameHost of +// |frame_tree_node| if the ID of its SiteInstance is |site_instance_id|. Used +// with FrameTree::ForEach. +bool EnableSuddenTermination(int32 site_instance_id, + FrameTreeNode* frame_tree_node) { + if (frame_tree_node->current_frame_host()->GetSiteInstance()->GetId() + == site_instance_id) { + frame_tree_node->current_frame_host() + ->set_override_sudden_termination_status(true); + } + return true; +} + } // namespace // static @@ -183,7 +196,6 @@ run_modal_reply_msg_(NULL), run_modal_opener_id_(MSG_ROUTING_NONE), is_waiting_for_close_ack_(false), - sudden_termination_allowed_(false), render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING), virtual_keyboard_requested_(false), is_focused_element_editable_(false), @@ -512,12 +524,6 @@ prefs.v8_cache_options = V8_CACHE_OPTIONS_DEFAULT; } - // TODO(marja): Clean up preferences + command line flag after streaming has - // launched in stable. - prefs.v8_script_streaming_enabled = true; - prefs.v8_script_streaming_mode = - V8_SCRIPT_STREAMING_MODE_ONLY_ASYNC_AND_DEFER; - GetContentClient()->browser()->OverrideWebkitPrefs(this, url, &prefs); return prefs; } @@ -555,7 +561,10 @@ StopHangMonitorTimeout(); is_waiting_for_close_ack_ = false; - sudden_termination_allowed_ = true; + // Enable sudden termination for all RenderFrameHosts in the FrameTree. + FrameTree* frame_tree = static_cast<RenderFrameHostImpl*>(GetMainFrame()) + ->frame_tree_node()->frame_tree(); + frame_tree->ForEach(base::Bind(&EnableSuddenTermination, instance_->GetId())); delegate_->Close(this); } @@ -846,11 +855,6 @@ delegate_->LoadStateChanged(url, load_state, upload_position, upload_size); } -bool RenderViewHostImpl::SuddenTerminationAllowed() const { - return sudden_termination_allowed_ || - GetProcess()->SuddenTerminationAllowed(); -} - /////////////////////////////////////////////////////////////////////////////// // RenderViewHostImpl, IPC message handlers: @@ -880,13 +884,13 @@ bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg) + IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnShowView) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget, OnShowFullscreenWidget) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnRunModal) IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL) IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose) @@ -1051,22 +1055,10 @@ } void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) { - // Keep the termination status so we can get at it later when we - // need to know why it died. - render_view_termination_status_ = - static_cast<base::TerminationStatus>(status); - - // Reset frame tree state associated with this process. This must happen - // before RenderViewTerminated because observers expect the subframes of any - // affected frames to be cleared first. - delegate_->GetFrameTree()->RenderProcessGone(this); - - // Our base class RenderWidgetHost needs to reset some stuff. - RendererExited(render_view_termination_status_, exit_code); - - delegate_->RenderViewTerminated(this, - static_cast<base::TerminationStatus>(status), - exit_code); + // Do nothing, otherwise RenderWidgetHostImpl will assume it is not a + // RenderViewHostImpl and destroy itself. + // TODO(nasko): Remove this hack once RenderViewHost and RenderWidgetHost are + // decoupled. } void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 430e34ad..86e8270 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -250,11 +250,6 @@ uint64 upload_position, uint64 upload_size); - bool SuddenTerminationAllowed() const; - void set_sudden_termination_allowed(bool enabled) { - sudden_termination_allowed_ = enabled; - } - // RenderWidgetHost public overrides. void Init() override; void Shutdown() override; @@ -436,9 +431,6 @@ // See http://crbug.com/418265. bool is_waiting_for_close_ack_; - // True if the render view can be shut down suddenly. - bool sudden_termination_allowed_; - // The termination status of the last render view that terminated. base::TerminationStatus render_view_termination_status_;
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc index a3a474f..db2d0fb 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -23,11 +23,6 @@ return false; } -bool RenderWidgetHostDelegate::HandleGestureEvent( - const blink::WebGestureEvent& event) { - return false; -} - BrowserAccessibilityManager* RenderWidgetHostDelegate::GetRootBrowserAccessibilityManager() { return NULL;
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index 2a4bba8..decec4a 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -61,10 +61,6 @@ // Returns true if the |event| was handled. virtual bool PreHandleGestureEvent(const blink::WebGestureEvent& event); - // Callback to inform the browser that the renderer did not process the - // specified gesture event. Returns true if the |event| was handled. - virtual bool HandleGestureEvent(const blink::WebGestureEvent& event); - // Notifies that screen rects were sent to renderer process. virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) {}
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 5272547..4d50c1c 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -48,6 +48,7 @@ #include "content/browser/renderer_host/render_widget_resize_helper.h" #include "content/common/content_constants_internal.h" #include "content/common/cursors/webcursor.h" +#include "content/common/frame_messages.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/host_shared_bitmap_manager.h" #include "content/common/input_messages.h" @@ -445,12 +446,12 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg) + IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) IPC_MESSAGE_HANDLER(InputHostMsg_QueueSyntheticGesture, OnQueueSyntheticGesture) IPC_MESSAGE_HANDLER(InputHostMsg_ImeCancelComposition, OnImeCancelComposition) IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone) IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateScreenRects_ACK, OnUpdateScreenRectsAck) @@ -1867,11 +1868,6 @@ InputEventAckState ack_result) { latency_tracker_.OnInputEventAck(event.event, &event.latency); - if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED) { - if (delegate_->HandleGestureEvent(event.event)) - ack_result = INPUT_EVENT_ACK_STATE_CONSUMED; - } - if (view_) view_->GestureEventAck(event.event, ack_result); }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 7aa1ef1..c249782 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -158,8 +158,7 @@ scoped_refptr<GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); // GLHelper can only be used in asynchronous APIs for postprocessing after // Browser Compositor operations (i.e. readback). - DCHECK(gpu_channel_host.get()) << "Illegal access to GPU channel at startup"; - if (gpu_channel_host->IsLost()) { + if (!gpu_channel_host.get()) { // The Browser Compositor is in charge of reestablishing the channel. return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index b0150f8..2a617d1 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -604,6 +604,7 @@ // Create the view, to transition from Destroyed -> Suspended. if (browser_compositor_state_ == BrowserCompositorDestroyed) { browser_compositor_ = BrowserCompositorMac::Create(); + browser_compositor_->compositor()->SetRootLayer(root_layer_.get()); browser_compositor_->accelerated_widget_mac()->SetNSView(this); browser_compositor_state_ = BrowserCompositorSuspended; } @@ -612,8 +613,6 @@ if (browser_compositor_state_ == BrowserCompositorSuspended) { delegated_frame_host_->SetCompositor(browser_compositor_->compositor()); delegated_frame_host_->WasShown(ui::LatencyInfo()); - browser_compositor_->compositor()->SetRootLayer( - root_layer_.get()); browser_compositor_state_ = BrowserCompositorActive; } } @@ -624,9 +623,6 @@ // Hide the DelegatedFrameHost to transition from Active -> Suspended. if (browser_compositor_state_ == BrowserCompositorActive) { - // Disconnect the root layer, which will prevent the compositor from - // producing more frames. - browser_compositor_->compositor()->SetRootLayer(nullptr); // Marking the DelegatedFrameHost as removed from the window hierarchy is // necessary to remove all connections to its old ui::Compositor. delegated_frame_host_->WasHidden(); @@ -646,6 +642,7 @@ if (browser_compositor_state_ == BrowserCompositorSuspended) { browser_compositor_->accelerated_widget_mac()->ResetNSView(); browser_compositor_->compositor()->SetScaleAndSize(1.0, gfx::Size(0, 0)); + browser_compositor_->compositor()->SetRootLayer(nullptr); BrowserCompositorMac::Recycle(browser_compositor_.Pass()); browser_compositor_state_ = BrowserCompositorDestroyed; } @@ -2274,6 +2271,13 @@ [responderDelegate_ touchesEndedWithEvent:event]; } +- (void)smartMagnifyWithEvent:(NSEvent*)event { + const WebGestureEvent& smartMagnifyEvent = + WebInputEventFactory::gestureEvent(event, self); + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent( + smartMagnifyEvent); +} + // This is invoked only on 10.8 or newer when the user taps a word using // three fingers. - (void)quickLookWithEvent:(NSEvent*)event {
diff --git a/content/browser/renderer_host/web_input_event_aura.cc b/content/browser/renderer_host/web_input_event_aura.cc index 76bdbf13..147e04b4d 100644 --- a/content/browser/renderer_host/web_input_event_aura.cc +++ b/content/browser/renderer_host/web_input_event_aura.cc
@@ -49,6 +49,7 @@ webkit_event.windowsKeyCode = event.GetLocatedWindowsKeyboardCode(); webkit_event.nativeKeyCode = ui::KeycodeConverter::DomCodeToNativeKeycode(event.code()); + webkit_event.domCode = static_cast<int>(event.code()); webkit_event.unmodifiedText[0] = event.GetUnmodifiedText(); webkit_event.text[0] = event.GetText();
diff --git a/content/browser/service_worker/service_worker_cache.cc b/content/browser/service_worker/service_worker_cache.cc index ebbcc93..169ae80 100644 --- a/content/browser/service_worker/service_worker_cache.cc +++ b/content/browser/service_worker/service_worker_cache.cc
@@ -12,6 +12,7 @@ #include "base/profiler/scoped_tracker.h" #include "base/strings/string_util.h" #include "content/browser/service_worker/service_worker_cache.pb.h" +#include "content/browser/service_worker/service_worker_cache_scheduler.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/referrer.h" #include "net/base/io_buffer.h" @@ -462,89 +463,77 @@ put_context->response->blob_uuid); } - pending_operations_.push_back(base::Bind(&ServiceWorkerCache::PutImpl, + if (backend_state_ == BACKEND_UNINITIALIZED) + InitBackend(); + + scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::PutImpl, weak_ptr_factory_.GetWeakPtr(), base::Passed(put_context.Pass()))); - - if (backend_state_ == BACKEND_UNINITIALIZED) { - InitBackend(); - return; - } - - RunOperationIfIdle(); } void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, const ResponseCallback& callback) { - ResponseCallback pending_callback = - base::Bind(&ServiceWorkerCache::PendingResponseCallback, - weak_ptr_factory_.GetWeakPtr(), callback); - pending_operations_.push_back( - base::Bind(&ServiceWorkerCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), - base::Passed(request.Pass()), pending_callback)); - switch (backend_state_) { case BACKEND_UNINITIALIZED: InitBackend(); - return; + break; case BACKEND_CLOSED: - pending_callback.Run(ErrorTypeStorage, - scoped_ptr<ServiceWorkerResponse>(), - scoped_ptr<storage::BlobDataHandle>()); + callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(), + scoped_ptr<storage::BlobDataHandle>()); return; case BACKEND_OPEN: DCHECK(backend_); - RunOperationIfIdle(); - return; + break; } - NOTREACHED(); + + ResponseCallback pending_callback = + base::Bind(&ServiceWorkerCache::PendingResponseCallback, + weak_ptr_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), + base::Passed(request.Pass()), pending_callback)); } void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, const ErrorCallback& callback) { + switch (backend_state_) { + case BACKEND_UNINITIALIZED: + InitBackend(); + break; + case BACKEND_CLOSED: + callback.Run(ErrorTypeStorage); + return; + case BACKEND_OPEN: + DCHECK(backend_); + break; + } ErrorCallback pending_callback = base::Bind(&ServiceWorkerCache::PendingErrorCallback, weak_ptr_factory_.GetWeakPtr(), callback); - pending_operations_.push_back(base::Bind( + scheduler_->ScheduleOperation(base::Bind( &ServiceWorkerCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()), pending_callback)); - - switch (backend_state_) { - case BACKEND_UNINITIALIZED: - InitBackend(); - return; - case BACKEND_CLOSED: - pending_callback.Run(ErrorTypeStorage); - return; - case BACKEND_OPEN: - DCHECK(backend_); - RunOperationIfIdle(); - return; - } - NOTREACHED(); } void ServiceWorkerCache::Keys(const RequestsCallback& callback) { - RequestsCallback pending_callback = - base::Bind(&ServiceWorkerCache::PendingRequestsCallback, - weak_ptr_factory_.GetWeakPtr(), callback); - pending_operations_.push_back(base::Bind(&ServiceWorkerCache::KeysImpl, - weak_ptr_factory_.GetWeakPtr(), - pending_callback)); - switch (backend_state_) { case BACKEND_UNINITIALIZED: InitBackend(); - return; + break; case BACKEND_CLOSED: - pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); + callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); return; case BACKEND_OPEN: DCHECK(backend_); - RunOperationIfIdle(); - return; + break; } - NOTREACHED(); + + RequestsCallback pending_callback = + base::Bind(&ServiceWorkerCache::PendingRequestsCallback, + weak_ptr_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::KeysImpl, + weak_ptr_factory_.GetWeakPtr(), + pending_callback)); } void ServiceWorkerCache::Close(const base::Closure& callback) { @@ -555,10 +544,9 @@ base::Bind(&ServiceWorkerCache::PendingClosure, weak_ptr_factory_.GetWeakPtr(), callback); - pending_operations_.push_back(base::Bind(&ServiceWorkerCache::CloseImpl, + scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::CloseImpl, weak_ptr_factory_.GetWeakPtr(), pending_callback)); - RunOperationIfIdle(); } int64 ServiceWorkerCache::MemoryBackedSize() const { @@ -601,7 +589,7 @@ quota_manager_proxy_(quota_manager_proxy), blob_storage_context_(blob_context), backend_state_(BACKEND_UNINITIALIZED), - operation_running_(false), + scheduler_(new ServiceWorkerCacheScheduler()), initializing_(false), memory_only_(path.empty()), weak_ptr_factory_(this) { @@ -1205,19 +1193,16 @@ void ServiceWorkerCache::InitBackend() { DCHECK(backend_state_ == BACKEND_UNINITIALIZED); - if (initializing_) { - DCHECK(operation_running_); + if (initializing_) return; - } - DCHECK(!operation_running_); // All ops should wait for backend init. + DCHECK(scheduler_->Empty()); initializing_ = true; - // Note that this operation pushes to the front of the queue. - pending_operations_.push_front(base::Bind( + + scheduler_->ScheduleOperation(base::Bind( &ServiceWorkerCache::CreateBackend, weak_ptr_factory_.GetWeakPtr(), base::Bind(&ServiceWorkerCache::InitDone, weak_ptr_factory_.GetWeakPtr()))); - RunOperationIfIdle(); } void ServiceWorkerCache::InitDone(ErrorType error) { @@ -1226,37 +1211,24 @@ backend_state_ == BACKEND_UNINITIALIZED) ? BACKEND_OPEN : BACKEND_CLOSED; - CompleteOperationAndRunNext(); -} - -void ServiceWorkerCache::CompleteOperationAndRunNext() { - DCHECK(!pending_operations_.empty()); - operation_running_ = false; - pending_operations_.pop_front(); - RunOperationIfIdle(); -} - -void ServiceWorkerCache::RunOperationIfIdle() { - DCHECK(!operation_running_ || !pending_operations_.empty()); - - if (!operation_running_ && !pending_operations_.empty()) { - operation_running_ = true; - // TODO(jkarlin): Run multiple operations in parallel where allowed (e.g., - // if they're for different keys then they won't interfere). See - // https://crbug.com/451174. - pending_operations_.front().Run(); - } + scheduler_->CompleteOperationAndRunNext(); } void ServiceWorkerCache::PendingClosure(const base::Closure& callback) { + base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr(); + callback.Run(); - CompleteOperationAndRunNext(); + if (cache) + scheduler_->CompleteOperationAndRunNext(); } void ServiceWorkerCache::PendingErrorCallback(const ErrorCallback& callback, ErrorType error) { + base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr(); + callback.Run(error); - CompleteOperationAndRunNext(); + if (cache) + scheduler_->CompleteOperationAndRunNext(); } void ServiceWorkerCache::PendingResponseCallback( @@ -1264,16 +1236,22 @@ ErrorType error, scoped_ptr<ServiceWorkerResponse> response, scoped_ptr<storage::BlobDataHandle> blob_data_handle) { + base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr(); + callback.Run(error, response.Pass(), blob_data_handle.Pass()); - CompleteOperationAndRunNext(); + if (cache) + scheduler_->CompleteOperationAndRunNext(); } void ServiceWorkerCache::PendingRequestsCallback( const RequestsCallback& callback, ErrorType error, scoped_ptr<Requests> requests) { + base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr(); + callback.Run(error, requests.Pass()); - CompleteOperationAndRunNext(); + if (cache) + scheduler_->CompleteOperationAndRunNext(); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_cache.h b/content/browser/service_worker/service_worker_cache.h index 84e4b6d..a12a324 100644 --- a/content/browser/service_worker/service_worker_cache.h +++ b/content/browser/service_worker/service_worker_cache.h
@@ -30,6 +30,7 @@ namespace content { class ChromeBlobStorageContext; class ServiceWorkerCacheMetadata; +class ServiceWorkerCacheScheduler; class TestServiceWorkerCache; // Represents a ServiceWorker Cache as seen in @@ -182,8 +183,6 @@ void InitBackend(); void InitDone(ErrorType error); - void CompleteOperationAndRunNext(); - void RunOperationIfIdle(); void PendingClosure(const base::Closure& callback); void PendingErrorCallback(const ErrorCallback& callback, ErrorType error); void PendingResponseCallback( @@ -204,8 +203,7 @@ scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_; base::WeakPtr<storage::BlobStorageContext> blob_storage_context_; BackendState backend_state_; - std::list<base::Closure> pending_operations_; - bool operation_running_; + scoped_ptr<ServiceWorkerCacheScheduler> scheduler_; bool initializing_; // Whether or not to store data in disk or memory.
diff --git a/content/browser/service_worker/service_worker_cache_scheduler.cc b/content/browser/service_worker/service_worker_cache_scheduler.cc new file mode 100644 index 0000000..694c5821 --- /dev/null +++ b/content/browser/service_worker/service_worker_cache_scheduler.cc
@@ -0,0 +1,47 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_cache_scheduler.h" + +#include <string> + +#include "base/logging.h" + +namespace content { + +ServiceWorkerCacheScheduler::ServiceWorkerCacheScheduler() + : operation_running_(false) { +} + +ServiceWorkerCacheScheduler::~ServiceWorkerCacheScheduler() { +} + +void ServiceWorkerCacheScheduler::ScheduleOperation( + const base::Closure& closure) { + pending_operations_.push_back(closure); + RunOperationIfIdle(); +} + +void ServiceWorkerCacheScheduler::CompleteOperationAndRunNext() { + DCHECK(!pending_operations_.empty()); + operation_running_ = false; + pending_operations_.pop_front(); + RunOperationIfIdle(); +} + +bool ServiceWorkerCacheScheduler::Empty() const { + return pending_operations_.empty(); +} + +void ServiceWorkerCacheScheduler::RunOperationIfIdle() { + DCHECK(!operation_running_ || !pending_operations_.empty()); + + if (!operation_running_ && !pending_operations_.empty()) { + operation_running_ = true; + // TODO(jkarlin): Run multiple operations in parallel where allowed. + pending_operations_.front().Run(); + } +} + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_cache_scheduler.h b/content/browser/service_worker/service_worker_cache_scheduler.h new file mode 100644 index 0000000..dcf6f87 --- /dev/null +++ b/content/browser/service_worker/service_worker_cache_scheduler.h
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_SCHEDULER_H_ +#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_SCHEDULER_H_ + +#include <list> + +#include "base/callback.h" +#include "content/common/content_export.h" + +namespace content { + +class CONTENT_EXPORT ServiceWorkerCacheScheduler { + public: + ServiceWorkerCacheScheduler(); + virtual ~ServiceWorkerCacheScheduler(); + + // Adds the operation to the tail of the queue and starts it if the scheduler + // is idle. + void ScheduleOperation(const base::Closure& closure); + + // Call this after each operation completes. It cleans up the current + // operation and starts the next. + void CompleteOperationAndRunNext(); + + bool Empty() const; + + private: + void RunOperationIfIdle(); + + // The list of operations waiting on initialization. + std::list<base::Closure> pending_operations_; + bool operation_running_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheScheduler); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_SCHEDULER_H_
diff --git a/content/browser/service_worker/service_worker_cache_scheduler_unittest.cc b/content/browser/service_worker/service_worker_cache_scheduler_unittest.cc new file mode 100644 index 0000000..0520ca2 --- /dev/null +++ b/content/browser/service_worker/service_worker_cache_scheduler_unittest.cc
@@ -0,0 +1,85 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_cache_scheduler.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +class JobStats { + public: + JobStats(ServiceWorkerCacheScheduler* scheduler) + : scheduler_(scheduler), callback_count_(0) {} + + virtual void Run() = 0; + + int callback_count() const { return callback_count_; } + + protected: + ServiceWorkerCacheScheduler* scheduler_; + int callback_count_; +}; + +class SyncJob : public JobStats { + public: + SyncJob(ServiceWorkerCacheScheduler* scheduler) : JobStats(scheduler) {} + + void Run() override { + callback_count_++; + scheduler_->CompleteOperationAndRunNext(); + } +}; + +class AsyncJob : public JobStats { + public: + AsyncJob(ServiceWorkerCacheScheduler* scheduler) : JobStats(scheduler) {} + + void Run() override { callback_count_++; } + void Done() { scheduler_->CompleteOperationAndRunNext(); } +}; + +} // namespace + +class ServiceWorkerCacheSchedulerTest : public testing::Test { + protected: + ServiceWorkerCacheSchedulerTest() + : async_job_(AsyncJob(&scheduler_)), sync_job_(SyncJob(&scheduler_)) {} + + ServiceWorkerCacheScheduler scheduler_; + AsyncJob async_job_; + SyncJob sync_job_; +}; + +TEST_F(ServiceWorkerCacheSchedulerTest, ScheduleOne) { + scheduler_.ScheduleOperation( + base::Bind(&JobStats::Run, base::Unretained(&sync_job_))); + EXPECT_EQ(1, sync_job_.callback_count()); +} + +TEST_F(ServiceWorkerCacheSchedulerTest, ScheduleTwo) { + scheduler_.ScheduleOperation( + base::Bind(&JobStats::Run, base::Unretained(&sync_job_))); + scheduler_.ScheduleOperation( + base::Bind(&JobStats::Run, base::Unretained(&sync_job_))); + EXPECT_EQ(2, sync_job_.callback_count()); +} + +TEST_F(ServiceWorkerCacheSchedulerTest, Block) { + scheduler_.ScheduleOperation( + base::Bind(&JobStats::Run, base::Unretained(&async_job_))); + EXPECT_EQ(1, async_job_.callback_count()); + scheduler_.ScheduleOperation( + base::Bind(&JobStats::Run, base::Unretained(&sync_job_))); + EXPECT_EQ(0, sync_job_.callback_count()); + async_job_.Done(); + EXPECT_EQ(1, sync_job_.callback_count()); +} + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_cache_storage.cc b/content/browser/service_worker/service_worker_cache_storage.cc index 539cafb2..d5fb07c 100644 --- a/content/browser/service_worker/service_worker_cache_storage.cc +++ b/content/browser/service_worker/service_worker_cache_storage.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_util.h" #include "content/browser/service_worker/service_worker_cache.h" #include "content/browser/service_worker/service_worker_cache.pb.h" +#include "content/browser/service_worker/service_worker_cache_scheduler.h" #include "content/public/browser/browser_thread.h" #include "net/base/directory_lister.h" #include "net/base/net_errors.h" @@ -377,6 +378,8 @@ base::WeakPtr<storage::BlobStorageContext> blob_context, const GURL& origin) : initialized_(false), + initializing_(false), + scheduler_(new ServiceWorkerCacheScheduler()), origin_path_(path), cache_task_runner_(cache_task_runner), memory_only_(memory_only), @@ -404,43 +407,30 @@ const CacheAndErrorCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::OpenCache, - weak_factory_.GetWeakPtr(), - cache_name, - callback)); - return; - } + if (!initialized_) + LazyInit(); - scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); - if (cache.get()) { - callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); - return; - } - - cache_loader_->CreateCache( - cache_name, - base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, - weak_factory_.GetWeakPtr(), - cache_name, - callback)); + CacheAndErrorCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingCacheAndErrorCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::OpenCacheImpl, + weak_factory_.GetWeakPtr(), cache_name, pending_callback)); } void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, const BoolAndErrorCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, - weak_factory_.GetWeakPtr(), - cache_name, - callback)); - return; - } + if (!initialized_) + LazyInit(); - bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); - - callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); + BoolAndErrorCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::HasCacheImpl, + weak_factory_.GetWeakPtr(), cache_name, pending_callback)); } void ServiceWorkerCacheStorage::DeleteCache( @@ -448,54 +438,30 @@ const BoolAndErrorCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, - weak_factory_.GetWeakPtr(), - cache_name, - callback)); - return; - } + if (!initialized_) + LazyInit(); - CacheMap::iterator it = cache_map_.find(cache_name); - if (it == cache_map_.end()) { - callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); - return; - } - - base::WeakPtr<ServiceWorkerCache> cache = it->second; - cache_map_.erase(it); - - // Delete the name from ordered_cache_names_. - StringVector::iterator iter = std::find( - ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name); - DCHECK(iter != ordered_cache_names_.end()); - ordered_cache_names_.erase(iter); - - base::Closure closure = - base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose, - weak_factory_.GetWeakPtr(), cache_name, callback, - ordered_cache_names_, make_scoped_refptr(cache.get())); - - if (cache) { - cache->Close(closure); - return; - } - - closure.Run(); + BoolAndErrorCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::DeleteCacheImpl, + weak_factory_.GetWeakPtr(), cache_name, pending_callback)); } void ServiceWorkerCacheStorage::EnumerateCaches( const StringsAndErrorCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, - weak_factory_.GetWeakPtr(), - callback)); - return; - } + if (!initialized_) + LazyInit(); - callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR); + StringsAndErrorCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingStringsAndErrorCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::EnumerateCachesImpl, + weak_factory_.GetWeakPtr(), pending_callback)); } void ServiceWorkerCacheStorage::MatchCache( @@ -504,27 +470,15 @@ const ServiceWorkerCache::ResponseCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchCache, - weak_factory_.GetWeakPtr(), cache_name, - base::Passed(request.Pass()), callback)); - return; - } + if (!initialized_) + LazyInit(); - scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); - - if (!cache.get()) { - callback.Run(ServiceWorkerCache::ErrorTypeNotFound, - scoped_ptr<ServiceWorkerResponse>(), - scoped_ptr<storage::BlobDataHandle>()); - return; - } - - // Pass the cache along to the callback to keep the cache open until match is - // done. - cache->Match(request.Pass(), - base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch, - weak_factory_.GetWeakPtr(), cache, callback)); + ServiceWorkerCache::ResponseCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation(base::Bind( + &ServiceWorkerCacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(), + cache_name, base::Passed(request.Pass()), pending_callback)); } void ServiceWorkerCacheStorage::MatchAllCaches( @@ -532,32 +486,16 @@ const ServiceWorkerCache::ResponseCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!initialized_) { - LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchAllCaches, - weak_factory_.GetWeakPtr(), - base::Passed(request.Pass()), callback)); - return; - } + if (!initialized_) + LazyInit(); - scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy( - new ServiceWorkerCache::ResponseCallback(callback)); - - ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get(); - base::Closure barrier_closure = base::BarrierClosure( - ordered_cache_names_.size(), - base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll, - weak_factory_.GetWeakPtr(), - base::Passed(callback_copy.Pass()))); - - for (const std::string& cache_name : ordered_cache_names_) { - scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); - DCHECK(cache.get()); - - cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)), - base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch, - weak_factory_.GetWeakPtr(), cache, barrier_closure, - callback_ptr)); - } + ServiceWorkerCache::ResponseCallback pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesImpl, + weak_factory_.GetWeakPtr(), base::Passed(request.Pass()), + pending_callback)); } void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) { @@ -568,31 +506,12 @@ return; } - int live_cache_count = 0; - for (const auto& key_value : cache_map_) { - if (key_value.second) - live_cache_count += 1; - } - - if (live_cache_count == 0) { - callback.Run(); - return; - } - - // The closure might modify this object so delay calling it until after - // iterating through cache_map_ by adding one to the barrier. - base::Closure barrier_closure = - base::BarrierClosure(live_cache_count + 1, base::Bind(callback)); - - for (auto& key_value : cache_map_) { - if (key_value.second) { - key_value.second->Close(base::Bind( - CloseAllCachesDidCloseCache, - make_scoped_refptr(key_value.second.get()), barrier_closure)); - } - } - - barrier_closure.Run(); + base::Closure pending_callback = + base::Bind(&ServiceWorkerCacheStorage::PendingClosure, + weak_factory_.GetWeakPtr(), callback); + scheduler_->ScheduleOperation( + base::Bind(&ServiceWorkerCacheStorage::CloseAllCachesImpl, + weak_factory_.GetWeakPtr(), pending_callback)); } int64 ServiceWorkerCacheStorage::MemoryBackedSize() const { @@ -609,18 +528,34 @@ return sum; } +void ServiceWorkerCacheStorage::StartAsyncOperationForTesting() { + scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); +} + +void ServiceWorkerCacheStorage::CompleteAsyncOperationForTesting() { + scheduler_->CompleteOperationAndRunNext(); +} + // Init is run lazily so that it is called on the proper MessageLoop. -void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { +void ServiceWorkerCacheStorage::LazyInit() { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(!initialized_); - init_callbacks_.push_back(callback); - - // If this isn't the first call to LazyInit then return as the initialization - // has already started. - if (init_callbacks_.size() > 1u) + if (initializing_) return; + DCHECK(scheduler_->Empty()); + + initializing_ = true; + scheduler_->ScheduleOperation(base::Bind( + &ServiceWorkerCacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); +} + +void ServiceWorkerCacheStorage::LazyInitImpl() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(!initialized_); + DCHECK(initializing_); + // 1. Get the list of cache names (async call) // 2. For each cache name, load the cache (async call) // 3. Once each load is complete, update the map variables. @@ -632,12 +567,10 @@ cache_loader_->LoadIndex( indexed_cache_names.Pass(), base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, - weak_factory_.GetWeakPtr(), - callback)); + weak_factory_.GetWeakPtr())); } void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( - const base::Closure& callback, scoped_ptr<std::vector<std::string> > indexed_cache_names) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -647,13 +580,25 @@ ordered_cache_names_.push_back(indexed_cache_names->at(i)); } + initializing_ = false; initialized_ = true; - for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); - it != init_callbacks_.end(); - ++it) { - it->Run(); + + scheduler_->CompleteOperationAndRunNext(); +} + +void ServiceWorkerCacheStorage::OpenCacheImpl( + const std::string& cache_name, + const CacheAndErrorCallback& callback) { + scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); + if (cache.get()) { + callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); + return; } - init_callbacks_.clear(); + + cache_loader_->CreateCache( + cache_name, + base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, + weak_factory_.GetWeakPtr(), cache_name, callback)); } void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( @@ -689,6 +634,45 @@ callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); } +void ServiceWorkerCacheStorage::HasCacheImpl( + const std::string& cache_name, + const BoolAndErrorCallback& callback) { + bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); + + callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); +} + +void ServiceWorkerCacheStorage::DeleteCacheImpl( + const std::string& cache_name, + const BoolAndErrorCallback& callback) { + CacheMap::iterator it = cache_map_.find(cache_name); + if (it == cache_map_.end()) { + callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); + return; + } + + base::WeakPtr<ServiceWorkerCache> cache = it->second; + cache_map_.erase(it); + + // Delete the name from ordered_cache_names_. + StringVector::iterator iter = std::find( + ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name); + DCHECK(iter != ordered_cache_names_.end()); + ordered_cache_names_.erase(iter); + + base::Closure closure = + base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose, + weak_factory_.GetWeakPtr(), cache_name, callback, + ordered_cache_names_, make_scoped_refptr(cache.get())); + + if (cache) { + cache->Close(closure); + return; + } + + closure.Run(); +} + void ServiceWorkerCacheStorage::DeleteCacheDidClose( const std::string& cache_name, const BoolAndErrorCallback& callback, @@ -721,6 +705,31 @@ callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); } +void ServiceWorkerCacheStorage::EnumerateCachesImpl( + const StringsAndErrorCallback& callback) { + callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR); +} + +void ServiceWorkerCacheStorage::MatchCacheImpl( + const std::string& cache_name, + scoped_ptr<ServiceWorkerFetchRequest> request, + const ServiceWorkerCache::ResponseCallback& callback) { + scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); + + if (!cache.get()) { + callback.Run(ServiceWorkerCache::ErrorTypeNotFound, + scoped_ptr<ServiceWorkerResponse>(), + scoped_ptr<storage::BlobDataHandle>()); + return; + } + + // Pass the cache along to the callback to keep the cache open until match is + // done. + cache->Match(request.Pass(), + base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch, + weak_factory_.GetWeakPtr(), cache, callback)); +} + void ServiceWorkerCacheStorage::MatchCacheDidMatch( const scoped_refptr<ServiceWorkerCache>& cache, const ServiceWorkerCache::ResponseCallback& callback, @@ -730,6 +739,30 @@ callback.Run(error, response.Pass(), handle.Pass()); } +void ServiceWorkerCacheStorage::MatchAllCachesImpl( + scoped_ptr<ServiceWorkerFetchRequest> request, + const ServiceWorkerCache::ResponseCallback& callback) { + scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy( + new ServiceWorkerCache::ResponseCallback(callback)); + + ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get(); + base::Closure barrier_closure = base::BarrierClosure( + ordered_cache_names_.size(), + base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll, + weak_factory_.GetWeakPtr(), + base::Passed(callback_copy.Pass()))); + + for (const std::string& cache_name : ordered_cache_names_) { + scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); + DCHECK(cache.get()); + + cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)), + base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch, + weak_factory_.GetWeakPtr(), cache, barrier_closure, + callback_ptr)); + } +} + void ServiceWorkerCacheStorage::MatchAllCachesDidMatch( scoped_refptr<ServiceWorkerCache> cache, const base::Closure& barrier_closure, @@ -777,4 +810,91 @@ return make_scoped_refptr(cache.get()); } +void ServiceWorkerCacheStorage::CloseAllCachesImpl( + const base::Closure& callback) { + int live_cache_count = 0; + for (const auto& key_value : cache_map_) { + if (key_value.second) + live_cache_count += 1; + } + + if (live_cache_count == 0) { + callback.Run(); + return; + } + + // The closure might modify this object so delay calling it until after + // iterating through cache_map_ by adding one to the barrier. + base::Closure barrier_closure = + base::BarrierClosure(live_cache_count + 1, base::Bind(callback)); + + for (auto& key_value : cache_map_) { + if (key_value.second) { + key_value.second->Close(base::Bind( + CloseAllCachesDidCloseCache, + make_scoped_refptr(key_value.second.get()), barrier_closure)); + } + } + + barrier_closure.Run(); +} + +void ServiceWorkerCacheStorage::PendingClosure(const base::Closure& callback) { + base::WeakPtr<ServiceWorkerCacheStorage> cache_storage = + weak_factory_.GetWeakPtr(); + + callback.Run(); + if (cache_storage) + scheduler_->CompleteOperationAndRunNext(); +} + +void ServiceWorkerCacheStorage::PendingBoolAndErrorCallback( + const BoolAndErrorCallback& callback, + bool found, + CacheStorageError error) { + base::WeakPtr<ServiceWorkerCacheStorage> cache_storage = + weak_factory_.GetWeakPtr(); + + callback.Run(found, error); + if (cache_storage) + scheduler_->CompleteOperationAndRunNext(); +} + +void ServiceWorkerCacheStorage::PendingCacheAndErrorCallback( + const CacheAndErrorCallback& callback, + const scoped_refptr<ServiceWorkerCache>& cache, + CacheStorageError error) { + base::WeakPtr<ServiceWorkerCacheStorage> cache_storage = + weak_factory_.GetWeakPtr(); + + callback.Run(cache, error); + if (cache_storage) + scheduler_->CompleteOperationAndRunNext(); +} + +void ServiceWorkerCacheStorage::PendingStringsAndErrorCallback( + const StringsAndErrorCallback& callback, + const StringVector& strings, + CacheStorageError error) { + base::WeakPtr<ServiceWorkerCacheStorage> cache_storage = + weak_factory_.GetWeakPtr(); + + callback.Run(strings, error); + if (cache_storage) + scheduler_->CompleteOperationAndRunNext(); +} + +void ServiceWorkerCacheStorage::PendingResponseCallback( + const ServiceWorkerCache::ResponseCallback& callback, + ServiceWorkerCache::ErrorType error, + scoped_ptr<ServiceWorkerResponse> response, + scoped_ptr<storage::BlobDataHandle> blob_data_handle) { + base::WeakPtr<ServiceWorkerCacheStorage> cache_storage = + weak_factory_.GetWeakPtr(); + + callback.Run(error, response.Pass(), blob_data_handle.Pass()); + if (cache_storage) + scheduler_->CompleteOperationAndRunNext(); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_cache_storage.h b/content/browser/service_worker/service_worker_cache_storage.h index 6eebb7d..6a65902 100644 --- a/content/browser/service_worker/service_worker_cache_storage.h +++ b/content/browser/service_worker/service_worker_cache_storage.h
@@ -26,12 +26,13 @@ } namespace content { +class ServiceWorkerCacheScheduler; // TODO(jkarlin): Constrain the total bytes used per origin. // ServiceWorkerCacheStorage holds the set of caches for a given origin. It is // owned by the ServiceWorkerCacheStorageManager. This class expects to be run -// on the IO thread. +// on the IO thread. The asynchronous methods are executed serially. class CONTENT_EXPORT ServiceWorkerCacheStorage { public: enum CacheStorageError { @@ -94,12 +95,19 @@ void MatchAllCaches(scoped_ptr<ServiceWorkerFetchRequest> request, const ServiceWorkerCache::ResponseCallback& callback); + // Calls close on each cache and runs the callback after all of them have + // closed. void CloseAllCaches(const base::Closure& callback); // The size of all of the origin's contents in memory. Returns 0 if the cache - // backend is not a memory backend. + // backend is not a memory backend. Runs synchronously. int64 MemoryBackedSize() const; + // The functions below are for tests to verify that the operations run + // serially. + void StartAsyncOperationForTesting(); + void CompleteAsyncOperationForTesting(); + private: class MemoryLoader; class SimpleCacheLoader; @@ -112,17 +120,15 @@ scoped_refptr<ServiceWorkerCache> GetLoadedCache( const std::string& cache_name); - // Initializer and its callback are below. While LazyInit is running any new - // operations will be queued and started in order after initialization. - void LazyInit(const base::Closure& closure); + // Initializer and its callback are below. + void LazyInit(); + void LazyInitImpl(); void LazyInitDidLoadIndex( - const base::Closure& callback, scoped_ptr<std::vector<std::string> > indexed_cache_names); - void AddCacheToMap(const std::string& cache_name, - base::WeakPtr<ServiceWorkerCache> cache); - - // The CreateCache callbacks are below. + // The Open and CreateCache callbacks are below. + void OpenCacheImpl(const std::string& cache_name, + const CacheAndErrorCallback& callback); void CreateCacheDidCreateCache( const std::string& cache_name, const CacheAndErrorCallback& callback, @@ -131,7 +137,14 @@ const scoped_refptr<ServiceWorkerCache>& cache, bool success); + // The HasCache callbacks are below. + void HasCacheImpl(const std::string& cache_name, + const BoolAndErrorCallback& callback); + // The DeleteCache callbacks are below. + void DeleteCacheImpl(const std::string& cache_name, + const BoolAndErrorCallback& callback); + void DeleteCacheDidClose(const std::string& cache_name, const BoolAndErrorCallback& callback, const StringVector& ordered_cache_names, @@ -142,7 +155,13 @@ void DeleteCacheDidCleanUp(const BoolAndErrorCallback& callback, bool success); + // The EnumerateCache callbacks are below. + void EnumerateCachesImpl(const StringsAndErrorCallback& callback); + // The MatchCache callbacks are below. + void MatchCacheImpl(const std::string& cache_name, + scoped_ptr<ServiceWorkerFetchRequest> request, + const ServiceWorkerCache::ResponseCallback& callback); void MatchCacheDidMatch(const scoped_refptr<ServiceWorkerCache>& cache, const ServiceWorkerCache::ResponseCallback& callback, ServiceWorkerCache::ErrorType error, @@ -150,6 +169,8 @@ scoped_ptr<storage::BlobDataHandle> handle); // The MatchAllCaches callbacks are below. + void MatchAllCachesImpl(scoped_ptr<ServiceWorkerFetchRequest> request, + const ServiceWorkerCache::ResponseCallback& callback); void MatchAllCachesDidMatch(scoped_refptr<ServiceWorkerCache> cache, const base::Closure& barrier_closure, ServiceWorkerCache::ResponseCallback* callback, @@ -159,11 +180,32 @@ void MatchAllCachesDidMatchAll( scoped_ptr<ServiceWorkerCache::ResponseCallback> callback); + // The CloseAllCaches callbacks are below. + void CloseAllCachesImpl(const base::Closure& callback); + + void PendingClosure(const base::Closure& callback); + void PendingBoolAndErrorCallback(const BoolAndErrorCallback& callback, + bool found, + CacheStorageError error); + void PendingCacheAndErrorCallback( + const CacheAndErrorCallback& callback, + const scoped_refptr<ServiceWorkerCache>& cache, + CacheStorageError error); + void PendingStringsAndErrorCallback(const StringsAndErrorCallback& callback, + const StringVector& strings, + CacheStorageError error); + void PendingResponseCallback( + const ServiceWorkerCache::ResponseCallback& callback, + ServiceWorkerCache::ErrorType error, + scoped_ptr<ServiceWorkerResponse> response, + scoped_ptr<storage::BlobDataHandle> blob_data_handle); + // Whether or not we've loaded the list of cache names into memory. bool initialized_; + bool initializing_; - // The list of operations waiting on initialization. - std::vector<base::Closure> init_callbacks_; + // The pending operation scheduler. + scoped_ptr<ServiceWorkerCacheScheduler> scheduler_; // The map of cache names to ServiceWorkerCache objects. CacheMap cache_map_;
diff --git a/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc b/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc index cb205835..cc8ec07 100644 --- a/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc +++ b/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc
@@ -22,7 +22,7 @@ namespace content { class ServiceWorkerCacheStorageManagerTest : public testing::Test { - protected: + public: ServiceWorkerCacheStorageManagerTest() : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), callback_bool_(false), @@ -424,13 +424,13 @@ } TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) { - EXPECT_TRUE(Open(origin1_, "������")); + EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); scoped_refptr<ServiceWorkerCache> cache = callback_cache_; - EXPECT_TRUE(Open(origin1_, "������")); + EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); EXPECT_EQ(callback_cache_.get(), cache.get()); EXPECT_TRUE(Keys(origin1_)); EXPECT_EQ(1u, callback_strings_.size()); - EXPECT_STREQ("������", callback_strings_[0].c_str()); + EXPECT_STREQ("ä½ å¥½", callback_strings_[0].c_str()); } TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) { @@ -522,6 +522,25 @@ EXPECT_TRUE(callback_cache_->AsWeakPtr()); } +TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenRunsSerially) { + EXPECT_FALSE(Delete(origin1_, "tmp")); // Init storage. + ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); + cache_storage->StartAsyncOperationForTesting(); + + scoped_ptr<base::RunLoop> open_loop(new base::RunLoop()); + cache_manager_->OpenCache( + origin1_, "foo", + base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback, + base::Unretained(this), base::Unretained(open_loop.get()))); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(callback_cache_); + + cache_storage->CompleteAsyncOperationForTesting(); + open_loop->Run(); + EXPECT_TRUE(callback_cache_); +} + TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, MemoryBackedSize) { ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); EXPECT_EQ(0, cache_storage->MemoryBackedSize());
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index db0b4e9f..d66de442 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -21,11 +21,13 @@ #include "content/browser/service_worker/service_worker_process_manager.h" #include "content/browser/service_worker/service_worker_quota_client.h" #include "content/browser/service_worker/service_worker_request_handler.h" +#include "content/browser/service_worker/service_worker_utils.h" #include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/service_worker_context.h" #include "net/base/net_errors.h" +#include "net/base/net_util.h" #include "net/url_request/url_request_context_getter.h" #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/quota/quota_manager_proxy.h" @@ -278,6 +280,27 @@ callback.Run(usage_infos); } +void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker( + const GURL& other_url, + const CheckHasServiceWorkerCallback& callback, + ServiceWorkerStatusCode status, + const scoped_refptr<ServiceWorkerRegistration>& registration) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (status != SERVICE_WORKER_OK) { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, false)); + return; + } + + DCHECK(registration); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(callback, registration->active_version() && + ServiceWorkerUtils::ScopeMatches( + registration->pattern(), other_url))); +} + namespace { void StatusCodeToBoolCallbackAdapter( const ServiceWorkerContext::ResultCallback& callback, @@ -309,6 +332,30 @@ DeleteForOrigin(origin_url, base::Bind(&EmptySuccessCallback)); } +void ServiceWorkerContextWrapper::CheckHasServiceWorker( + const GURL& url, + const GURL& other_url, + const CheckHasServiceWorkerCallback& callback) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker, this, + url, other_url, callback)); + return; + } + if (!context_core_.get()) { + LOG(ERROR) << "ServiceWorkerContextCore is no longer alive."; + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback, false)); + return; + } + GURL stripped_url = net::SimplifyUrlForRequest(url); + context()->storage()->FindRegistrationForDocument( + stripped_url, base::Bind(&ServiceWorkerContextWrapper:: + DidFindRegistrationForCheckHasServiceWorker, + this, other_url, callback)); +} + void ServiceWorkerContextWrapper::AddObserver( ServiceWorkerContextObserver* observer) { observer_list_->AddObserver(observer);
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h index 8494035..4eb6771 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.h +++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -85,6 +85,10 @@ const net::CompletionCallback& callback) override; void GetAllOriginsInfo(const GetUsageInfoCallback& callback) override; void DeleteForOrigin(const GURL& origin_url) override; + void CheckHasServiceWorker( + const GURL& url, + const GURL& other_url, + const CheckHasServiceWorkerCallback& callback) override; // DeleteForOrigin with completion callback. Does not exit early, and returns // false if one or more of the deletions fail. @@ -129,6 +133,12 @@ const GetUsageInfoCallback& callback, const std::vector<ServiceWorkerRegistrationInfo>& registrations); + void DidFindRegistrationForCheckHasServiceWorker( + const GURL& other_url, + const CheckHasServiceWorkerCallback& callback, + ServiceWorkerStatusCode status, + const scoped_refptr<ServiceWorkerRegistration>& registration); + const scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> > observer_list_; const scoped_ptr<ServiceWorkerProcessManager> process_manager_;
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index a210b51..b1c8b4d5 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -34,8 +34,6 @@ const char kNoDocumentURLErrorMessage[] = "No URL is associated with the caller's document."; -const char kDisallowedURLErrorMessage[] = - "The URL is not supported."; const char kShutdownErrorMessage[] = "The Service Worker system has shutdown."; const char kUserDeniedPermissionMessage[] = @@ -301,12 +299,7 @@ if (!CanRegisterServiceWorker( provider_host->document_url(), pattern, script_url)) { - // TODO(kinuko): Change this back to BadMessageReceived() once we start - // to check these in the renderer too. (http://crbug.com/453982) - Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError( - thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, - base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) + - base::ASCIIToUTF16(kDisallowedURLErrorMessage))); + BadMessageReceived(); return; } @@ -391,12 +384,7 @@ } if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) { - // TODO(kinuko): Change this back to BadMessageReceived() once we start - // to check these in the renderer too. (http://crbug.com/453982) - Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError( - thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, - base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix) + - base::ASCIIToUTF16(kDisallowedURLErrorMessage))); + BadMessageReceived(); return; } @@ -466,12 +454,7 @@ } if (!CanGetRegistration(provider_host->document_url(), document_url)) { - // TODO(kinuko): Change this back to BadMessageReceived() once we start - // to check these in the renderer too. (http://crbug.com/453982) - Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError( - thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, - base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) + - base::ASCIIToUTF16(kDisallowedURLErrorMessage))); + BadMessageReceived(); return; } @@ -583,6 +566,10 @@ GetContext()->GetLiveRegistration(version->registration_id()); DCHECK(registration); + // Set the document URL to the script url in order to allow + // register/unregister/getRegistration on ServiceWorkerGlobalScope. + provider_host->SetDocumentUrl(version->script_url()); + ServiceWorkerRegistrationObjectInfo info; ServiceWorkerVersionAttributes attrs; GetRegistrationObjectInfoAndVersionAttributes( @@ -690,7 +677,11 @@ ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(render_process_id_, provider_id); - DCHECK(provider_host); + if (!provider_host) { + BadMessageReceived(); + return; + } + provider_host->SetReadyToSendMessagesToWorker(thread_id); EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc index 040761e4..8931290 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -212,8 +212,8 @@ host->SetDocumentUrl(GURL("https://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - SendRegister( - kProviderId, GURL(""), GURL("https://www.example.com/bar/hoge.js")); + SendRegister(kProviderId, GURL(""), + GURL("https://www.example.com/bar/hoge.js")); EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } @@ -235,10 +235,10 @@ host->SetDocumentUrl(GURL("http://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - Register(kProviderId, - GURL("http://www.example.com/"), - GURL("http://www.example.com/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("http://www.example.com/"), + GURL("http://www.example.com/bar")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, Register_CrossOriginShouldFail) { @@ -249,40 +249,40 @@ context()->AddProviderHost(host.Pass()); // Script has a different host - Register(kProviderId, - GURL("https://www.example.com/"), - GURL("https://foo.example.com/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://www.example.com/"), + GURL("https://foo.example.com/bar")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); // Scope has a different host - Register(kProviderId, - GURL("https://foo.example.com/"), - GURL("https://www.example.com/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://foo.example.com/"), + GURL("https://www.example.com/bar")); + EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); // Script has a different port - Register(kProviderId, - GURL("https://www.example.com/"), - GURL("https://www.example.com:8080/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://www.example.com/"), + GURL("https://www.example.com:8080/bar")); + EXPECT_EQ(3, dispatcher_host_->bad_messages_received_count_); // Scope has a different transport - Register(kProviderId, - GURL("wss://www.example.com/"), - GURL("https://www.example.com/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("wss://www.example.com/"), + GURL("https://www.example.com/bar")); + EXPECT_EQ(4, dispatcher_host_->bad_messages_received_count_); // Script and scope have a different host but match each other - Register(kProviderId, - GURL("https://foo.example.com/"), - GURL("https://foo.example.com/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://foo.example.com/"), + GURL("https://foo.example.com/bar")); + EXPECT_EQ(5, dispatcher_host_->bad_messages_received_count_); // Script and scope URLs are invalid SendRegister(kProviderId, GURL(), GURL("h@ttps://@")); - EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); + EXPECT_EQ(6, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, @@ -293,20 +293,20 @@ host->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a")); context()->AddProviderHost(host.Pass()); - Register(kProviderId, - GURL("filesystem:https://www.example.com/temporary/"), - GURL("https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("filesystem:https://www.example.com/temporary/"), + GURL("https://www.example.com/temporary/bar")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); - Register(kProviderId, - GURL("https://www.example.com/temporary/"), - GURL("filesystem:https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://www.example.com/temporary/"), + GURL("filesystem:https://www.example.com/temporary/bar")); + EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); - Register(kProviderId, - GURL("filesystem:https://www.example.com/temporary/"), - GURL("filesystem:https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("filesystem:https://www.example.com/temporary/"), + GURL("filesystem:https://www.example.com/temporary/bar")); + EXPECT_EQ(3, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, @@ -317,20 +317,20 @@ host->SetDocumentUrl(GURL("https://www.example.com/temporary/")); context()->AddProviderHost(host.Pass()); - Register(kProviderId, - GURL("filesystem:https://www.example.com/temporary/"), - GURL("https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("filesystem:https://www.example.com/temporary/"), + GURL("https://www.example.com/temporary/bar")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); - Register(kProviderId, - GURL("https://www.example.com/temporary/"), - GURL("filesystem:https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("https://www.example.com/temporary/"), + GURL("filesystem:https://www.example.com/temporary/bar")); + EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); - Register(kProviderId, - GURL("filesystem:https://www.example.com/temporary/"), - GURL("filesystem:https://www.example.com/temporary/bar"), - ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); + SendRegister(kProviderId, + GURL("filesystem:https://www.example.com/temporary/"), + GURL("filesystem:https://www.example.com/temporary/bar")); + EXPECT_EQ(3, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, Unregister_HTTPS) { @@ -346,7 +346,7 @@ } TEST_F(ServiceWorkerDispatcherHostTest, - Unregister_NonSecureTransportLocalhost) { + Unregister_NotSecureTransportLocalhost) { const int64 kProviderId = 99; // Dummy value scoped_ptr<ServiceWorkerProviderHost> host( CreateServiceWorkerProviderHost(kProviderId)); @@ -365,9 +365,8 @@ host->SetDocumentUrl(GURL("https://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - Unregister(kProviderId, - GURL("https://foo.example.com/"), - ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID); + SendUnregister(kProviderId, GURL("https://foo.example.com/")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, Unregister_InvalidScopeShouldFail) { @@ -388,9 +387,8 @@ host->SetDocumentUrl(GURL("http://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - Unregister(kProviderId, - GURL("http://www.example.com/"), - ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID); + SendUnregister(kProviderId, GURL("http://www.example.com/")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) { @@ -455,9 +453,8 @@ host->SetDocumentUrl(GURL("https://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - GetRegistration(kProviderId, - GURL("https://foo.example.com/"), - ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID); + SendGetRegistration(kProviderId, GURL("https://foo.example.com/")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, @@ -473,16 +470,15 @@ } TEST_F(ServiceWorkerDispatcherHostTest, - GetRegistration_NotSecureOriginShouldFail) { + GetRegistration_NonSecureOriginShouldFail) { const int64 kProviderId = 99; // Dummy value scoped_ptr<ServiceWorkerProviderHost> host( CreateServiceWorkerProviderHost(kProviderId)); host->SetDocumentUrl(GURL("http://www.example.com/foo")); context()->AddProviderHost(host.Pass()); - GetRegistration(kProviderId, - GURL("http://www.example.com/"), - ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID); + SendGetRegistration(kProviderId, GURL("http://www.example.com/")); + EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); } TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_EarlyContextDeletion) {
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 46f9074..2926c75 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -5,6 +5,9 @@ #include "content/browser/service_worker/service_worker_provider_host.h" #include "base/stl_util.h" +#include "content/browser/frame_host/frame_tree.h" +#include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/message_port_message_filter.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_request_handler.h" @@ -14,33 +17,72 @@ #include "content/browser/service_worker/service_worker_registration_handle.h" #include "content/browser/service_worker/service_worker_utils.h" #include "content/browser/service_worker/service_worker_version.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/resource_request_body.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" #include "content/public/common/child_process_host.h" namespace content { namespace { -void FocusOnUIThread(int render_process_id, - int render_frame_id, - const ServiceWorkerProviderHost::FocusCallback& callback) { - WebContents* web_contents = WebContents::FromRenderFrameHost( - RenderFrameHost::FromID(render_process_id, render_frame_id)); - - bool result = false; - - if (web_contents && web_contents->GetDelegate()) { - result = true; - web_contents->GetDelegate()->ActivateContents(web_contents); +void GetClientInfoOnUIThread( + int render_process_id, + int render_frame_id, + const ServiceWorkerProviderHost::GetClientInfoCallback& callback) { + RenderFrameHostImpl* render_frame_host = + RenderFrameHostImpl::FromID(render_process_id, render_frame_id); + if (!render_frame_host) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback, ServiceWorkerClientInfo())); + return; } + // TODO(mlamouri,michaeln): it is possible to end up collecting information + // for a frame that is actually being navigated and isn't exactly what we are + // expecting. + ServiceWorkerClientInfo client_info( + render_frame_host->GetVisibilityState(), + render_frame_host->IsFocused(), + render_frame_host->GetLastCommittedURL(), + render_frame_host->GetParent() ? REQUEST_CONTEXT_FRAME_TYPE_NESTED + : REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, result)); + base::Bind(callback, client_info)); +} + +void FocusOnUIThread( + int render_process_id, + int render_frame_id, + const ServiceWorkerProviderHost::GetClientInfoCallback& callback) { + RenderFrameHostImpl* render_frame_host = + RenderFrameHostImpl::FromID(render_process_id, render_frame_id); + WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( + WebContents::FromRenderFrameHost(render_frame_host)); + + if (!render_frame_host || !web_contents) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback, ServiceWorkerClientInfo())); + return; + } + + FrameTreeNode* frame_tree_node = render_frame_host->frame_tree_node(); + + // Focus the frame in the frame tree node, in case it has changed. + frame_tree_node->frame_tree()->SetFocusedFrame(frame_tree_node); + + // Focus the frame's view to make sure the frame is now considered as focused. + render_frame_host->GetView()->Focus(); + + // Move the web contents to the foreground. + web_contents->Activate(); + + GetClientInfoOnUIThread(render_process_id, render_frame_id, callback); } } // anonymous namespace @@ -258,7 +300,7 @@ new_routing_ids)); } -void ServiceWorkerProviderHost::Focus(const FocusCallback& callback) { +void ServiceWorkerProviderHost::Focus(const GetClientInfoCallback& callback) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&FocusOnUIThread, @@ -268,10 +310,12 @@ } void ServiceWorkerProviderHost::GetClientInfo( - int embedded_worker_id, - int request_id) { - Send(new ServiceWorkerMsg_GetClientInfo( - kDocumentMainThreadId, embedded_worker_id, request_id, provider_id())); + const GetClientInfoCallback& callback) const { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&GetClientInfoOnUIThread, + render_process_id_, + render_frame_id_, + callback)); } void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index b3e60c1..386bee2 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -45,7 +45,8 @@ : public NON_EXPORTED_BASE(ServiceWorkerRegistration::Listener), public base::SupportsWeakPtr<ServiceWorkerProviderHost> { public: - typedef base::Callback<void(bool)> FocusCallback; + using GetClientInfoCallback = + base::Callback<void(const ServiceWorkerClientInfo&)>; // If |render_frame_id| is MSG_ROUTING_NONE, this provider host works for the // worker context. @@ -141,12 +142,11 @@ // Activates the WebContents associated with // { render_process_id_, render_frame_id_ }. - // Runs the |callback| with the result in parameter describing whether the - // focusing action was successful. - void Focus(const FocusCallback& callback); + // Runs the |callback| with the updated ServiceWorkerClientInfo in parameter. + void Focus(const GetClientInfoCallback& callback); // Asks the renderer to send back the document information. - void GetClientInfo(int embedded_worker_id, int request_id); + void GetClientInfo(const GetClientInfoCallback& callback) const; // Adds reference of this host's process to the |pattern|, the reference will // be removed in destructor.
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.cc b/content/browser/service_worker/service_worker_read_from_cache_job.cc index 135c5898..31498de 100644 --- a/content/browser/service_worker/service_worker_read_from_cache_job.cc +++ b/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -75,6 +75,11 @@ } net::LoadState ServiceWorkerReadFromCacheJob::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ServiceWorkerReadFromCacheJob::GetLoadState")); if (reader_.get() && reader_->IsReadPending()) return net::LOAD_STATE_READING_RESPONSE; return net::LOAD_STATE_IDLE;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 8776f0e..198a02d 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -14,11 +14,22 @@ #include "content/browser/service_worker/embedded_worker_instance.h" #include "content/browser/service_worker/embedded_worker_registry.h" #include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_utils.h" +#include "content/browser/storage_partition_impl.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/common/child_process_host.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" +#include "content/public/common/result_codes.h" #include "net/http/http_response_info.h" namespace content { @@ -45,6 +56,8 @@ friend class base::RefCounted<GetClientDocumentsCallback>; virtual ~GetClientDocumentsCallback() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (version_->running_status() == RUNNING) { version_->embedded_worker_->SendMessage( ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); @@ -53,9 +66,7 @@ std::vector<ServiceWorkerClientInfo> clients_; int request_id_; - - // |version_| must outlive this callback. - ServiceWorkerVersion* version_; + scoped_refptr<ServiceWorkerVersion> version_; DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); }; @@ -151,6 +162,110 @@ callback.Run(status, false); } +using WindowOpenedCallback = base::Callback<void(int, int)>; + +// The WindowOpenedObserver class is a WebContentsObserver that will wait for a +// new Window's WebContents to be initialized, run the |callback| passed to its +// constructor then self destroy. +// The callback will receive the process and frame ids. If something went wrong +// those will be (kInvalidUniqueID, MSG_ROUTING_NONE). +// The callback will be called in the IO thread. +class WindowOpenedObserver : public WebContentsObserver { + public: + WindowOpenedObserver(WebContents* web_contents, + const WindowOpenedCallback& callback) + : WebContentsObserver(web_contents), + callback_(callback) + {} + + void DidCommitProvisionalLoadForFrame( + RenderFrameHost* render_frame_host, + const GURL& validated_url, + ui::PageTransition transition_type) override { + DCHECK(web_contents()); + + if (render_frame_host != web_contents()->GetMainFrame()) + return; + + RunCallback(render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID()); + } + + void RenderProcessGone(base::TerminationStatus status) override { + RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE); + } + + void WebContentsDestroyed() override { + RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE); + } + + private: + void RunCallback(int render_process_id, int render_frame_id) { + // After running the callback, |this| will stop observing, thus + // web_contents() should return nullptr and |RunCallback| should no longer + // be called. Then, |this| will self destroy. + DCHECK(web_contents()); + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback_, + render_process_id, + render_frame_id)); + Observe(nullptr); + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); + } + + const WindowOpenedCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(WindowOpenedObserver); +}; + +void OpenWindowOnUI( + const GURL& url, + const GURL& script_url, + int process_id, + const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper, + const WindowOpenedCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + BrowserContext* browser_context = context_wrapper->storage_partition() + ? context_wrapper->storage_partition()->browser_context() + : nullptr; + // We are shutting down. + if (!browser_context) + return; + + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(process_id); + if (render_process_host->IsIsolatedGuest()) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback, + ChildProcessHost::kInvalidUniqueID, + MSG_ROUTING_NONE)); + return; + } + + OpenURLParams params(url, + Referrer(script_url, blink::WebReferrerPolicyDefault), + NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, + true /* is_renderer_initiated */); + + WebContents* web_contents = + GetContentClient()->browser()->OpenURL(browser_context, params); + DCHECK(web_contents); + + new WindowOpenedObserver(web_contents, callback); +} + +void KillEmbeddedWorkerProcess(int process_id, ResultCode code) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(process_id); + if (render_process_host->GetHandle() != base::kNullProcessHandle) + render_process_host->ReceivedBadMessage(); +} + } // namespace ServiceWorkerVersion::ServiceWorkerVersion( @@ -614,6 +729,8 @@ ServiceWorkerProviderHost* provider_host) { DCHECK(!ContainsKey(controllee_map_, provider_host)); int controllee_id = controllee_by_id_.Add(provider_host); + // IDMap<>'s last index is kInvalidServiceWorkerClientId. + CHECK(controllee_id != kInvalidServiceWorkerClientId); controllee_map_[provider_host] = controllee_id; // Reset the timer if it's running (so that it's kept alive a bit longer // right after a new controllee is added). @@ -734,9 +851,6 @@ SERVICE_WORKER_ERROR_FAILED); RunIDMapCallbacks(&geofencing_callbacks_, SERVICE_WORKER_ERROR_FAILED); - RunIDMapCallbacks(&get_client_info_callbacks_, - SERVICE_WORKER_ERROR_FAILED, - ServiceWorkerClientInfo()); RunIDMapCallbacks(&cross_origin_connect_callbacks_, SERVICE_WORKER_ERROR_FAILED, false); @@ -808,14 +922,12 @@ OnGeofencingEventFinished) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, OnCrossOriginConnectEventFinished) + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, + OnOpenWindow) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, OnPostMessageToDocument) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, OnFocusClient) - IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, - OnGetClientInfoSuccess) - IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, - OnGetClientInfoError) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, OnSkipWaiting) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, @@ -875,40 +987,14 @@ TRACE_EVENT0("ServiceWorker", "ServiceWorkerVersion::OnGetClientDocuments"); while (!it.IsAtEnd()) { - int client_request_id = get_client_info_callbacks_.Add( - new GetClientInfoCallback(base::Bind( - &ServiceWorkerVersion::DidGetClientInfo, - weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback))); - it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(), - client_request_id); + // TODO(mlamouri): we could coalesce those requests into one. + it.GetCurrentValue()->GetClientInfo( + base::Bind(&ServiceWorkerVersion::DidGetClientInfo, + weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback)); it.Advance(); } } -void ServiceWorkerVersion::OnGetClientInfoSuccess( - int request_id, - const ServiceWorkerClientInfo& info) { - GetClientInfoCallback* callback = - get_client_info_callbacks_.Lookup(request_id); - if (!callback) { - // The callback may already have been cleared by OnStopped, just ignore. - return; - } - callback->Run(SERVICE_WORKER_OK, info); - RemoveCallbackAndStopIfDoomed(&get_client_info_callbacks_, request_id); -} - -void ServiceWorkerVersion::OnGetClientInfoError(int request_id) { - GetClientInfoCallback* callback = - get_client_info_callbacks_.Lookup(request_id); - if (!callback) { - // The callback may already have been cleared by OnStopped, just ignore. - return; - } - callback->Run(SERVICE_WORKER_ERROR_FAILED, ServiceWorkerClientInfo()); - RemoveCallbackAndStopIfDoomed(&get_client_info_callbacks_, request_id); -} - void ServiceWorkerVersion::OnActivateEventFinished( int request_id, blink::WebServiceWorkerEventResult result) { @@ -1060,6 +1146,89 @@ RemoveCallbackAndStopIfDoomed(&cross_origin_connect_callbacks_, request_id); } +void ServiceWorkerVersion::OnOpenWindow(int request_id, const GURL& url) { + // Just abort if we are shutting down. + if (!context_) + return; + + if (url.GetOrigin() != script_url_.GetOrigin()) { + // There should be a same origin check by Blink, if the request is still not + // same origin, the process might be compromised and should be eliminated. + DVLOG(1) << "Received a cross origin openWindow() request from a service " + "worker. Killing associated process."; + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&KillEmbeddedWorkerProcess, + embedded_worker_->process_id(), + RESULT_CODE_KILLED_BAD_MESSAGE)); + return; + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&OpenWindowOnUI, + url, + script_url_, + embedded_worker_->process_id(), + make_scoped_refptr(context_->wrapper()), + base::Bind(&ServiceWorkerVersion::DidOpenWindow, + weak_factory_.GetWeakPtr(), + request_id))); +} + +void ServiceWorkerVersion::DidOpenWindow(int request_id, + int render_process_id, + int render_frame_id) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (running_status() != RUNNING) + return; + + if (render_process_id == ChildProcessHost::kInvalidUniqueID && + render_frame_id == MSG_ROUTING_NONE) { + embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError(request_id)); + return; + } + + for (const auto& it : controllee_map_) { + const ServiceWorkerProviderHost* provider_host = it.first; + if (provider_host->process_id() != render_process_id || + provider_host->frame_id() != render_frame_id) { + continue; + } + + // it.second is the client_id associated with the provider_host. + provider_host->GetClientInfo( + base::Bind(&ServiceWorkerVersion::OnOpenWindowFinished, + weak_factory_.GetWeakPtr(), request_id, it.second)); + return; + } + + // If here, it means that no provider_host was found, in which case, the + // renderer should still be informed that the window was opened. + OnOpenWindowFinished(request_id, 0, ServiceWorkerClientInfo()); +} + +void ServiceWorkerVersion::OnOpenWindowFinished( + int request_id, + int client_id, + const ServiceWorkerClientInfo& client_info) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (running_status() != RUNNING) + return; + + ServiceWorkerClientInfo client(client_info); + + // If the |client_info| is empty, it means that the opened window wasn't + // controlled but the action still succeeded. The renderer process is + // expecting an empty client in such case. + if (!client.IsEmpty()) + client.client_id = client_id; + + embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowResponse( + request_id, client)); +} + void ServiceWorkerVersion::OnPostMessageToDocument( int client_id, const base::string16& message, @@ -1078,7 +1247,7 @@ void ServiceWorkerVersion::OnFocusClient(int request_id, int client_id) { TRACE_EVENT2("ServiceWorker", - "ServiceWorkerVersion::OnFocusDocument", + "ServiceWorkerVersion::OnFocusClient", "Request id", request_id, "Client id", client_id); ServiceWorkerProviderHost* provider_host = @@ -1091,17 +1260,24 @@ provider_host->Focus( base::Bind(&ServiceWorkerVersion::OnFocusClientFinished, weak_factory_.GetWeakPtr(), - request_id)); + request_id, + client_id)); } -void ServiceWorkerVersion::OnFocusClientFinished(int request_id, bool result) { +void ServiceWorkerVersion::OnFocusClientFinished( + int request_id, + int cliend_id, + const ServiceWorkerClientInfo& client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (running_status() != RUNNING) return; + ServiceWorkerClientInfo client_info(client); + client_info.client_id = cliend_id; + embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( - request_id, result)); + request_id, client_info)); } void ServiceWorkerVersion::OnSkipWaiting(int request_id) { @@ -1167,10 +1343,21 @@ void ServiceWorkerVersion::DidGetClientInfo( int client_id, scoped_refptr<GetClientDocumentsCallback> callback, - ServiceWorkerStatusCode status, const ServiceWorkerClientInfo& info) { - if (status == SERVICE_WORKER_OK) - callback->AddClientInfo(client_id, info); + // If the request to the provider_host returned an empty + // ServiceWorkerClientInfo, that means that it wasn't possible to associate + // it with a valid RenderFrameHost. It might be because the frame was killed + // or navigated in between. + if (info.IsEmpty()) + return; + + // We can get info for a frame that was navigating end ended up with a + // different URL than expected. In such case, we should make sure to not + // expose cross-origin WindowClient. + if (info.url.GetOrigin() != script_url_.GetOrigin()) + return; + + callback->AddClientInfo(client_id, info); } void ServiceWorkerVersion::ScheduleStopWorker() { @@ -1208,7 +1395,6 @@ !notification_click_callbacks_.IsEmpty() || !push_callbacks_.IsEmpty() || !geofencing_callbacks_.IsEmpty() || - !get_client_info_callbacks_.IsEmpty() || !cross_origin_connect_callbacks_.IsEmpty() || !streaming_url_request_jobs_.empty(); }
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 015fc9d..125cfaf 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -40,13 +40,14 @@ namespace content { class EmbeddedWorkerRegistry; -struct NavigatorConnectClient; -struct PlatformNotificationData; class ServiceWorkerContextCore; class ServiceWorkerProviderHost; class ServiceWorkerRegistration; class ServiceWorkerURLRequestJob; class ServiceWorkerVersionInfo; +struct NavigatorConnectClient; +struct PlatformNotificationData; +struct ServiceWorkerClientInfo; // This class corresponds to a specific version of a ServiceWorker // script for a given pattern. When a script is upgraded, there may be @@ -63,9 +64,6 @@ typedef base::Callback<void(ServiceWorkerStatusCode, ServiceWorkerFetchEventResult, const ServiceWorkerResponse&)> FetchCallback; - typedef base::Callback<void(ServiceWorkerStatusCode, - const ServiceWorkerClientInfo&)> - GetClientInfoCallback; typedef base::Callback<void(ServiceWorkerStatusCode, bool)> CrossOriginConnectCallback; @@ -346,9 +344,6 @@ // Message handlers. void OnGetClientDocuments(int request_id); - void OnGetClientInfoSuccess(int request_id, - const ServiceWorkerClientInfo& info); - void OnGetClientInfoError(int request_id); void OnActivateEventFinished(int request_id, blink::WebServiceWorkerEventResult result); void OnInstallEventFinished(int request_id, @@ -363,6 +358,14 @@ void OnGeofencingEventFinished(int request_id); void OnCrossOriginConnectEventFinished(int request_id, bool accept_connection); + void OnOpenWindow(int request_id, const GURL& url); + void DidOpenWindow(int request_id, + int render_process_id, + int render_frame_id); + void OnOpenWindowFinished(int request_id, + int client_id, + const ServiceWorkerClientInfo& client_info); + void OnPostMessageToDocument(int client_id, const base::string16& message, const std::vector<int>& sent_message_port_ids); @@ -370,13 +373,16 @@ void OnSkipWaiting(int request_id); void OnClaimClients(int request_id); - void OnFocusClientFinished(int request_id, bool result); + void OnFocusClientFinished(int request_id, + int client_id, + const ServiceWorkerClientInfo& client); + void DidSkipWaiting(int request_id); void DidClaimClients(int request_id, ServiceWorkerStatusCode status); void DidGetClientInfo(int client_id, scoped_refptr<GetClientDocumentsCallback> callback, - ServiceWorkerStatusCode status, const ServiceWorkerClientInfo& info); + void ScheduleStopWorker(); void StopWorkerIfIdle(); bool HasInflightRequests() const; @@ -406,7 +412,6 @@ IDMap<StatusCallback, IDMapOwnPointer> notification_click_callbacks_; IDMap<StatusCallback, IDMapOwnPointer> push_callbacks_; IDMap<StatusCallback, IDMapOwnPointer> geofencing_callbacks_; - IDMap<GetClientInfoCallback, IDMapOwnPointer> get_client_info_callbacks_; IDMap<CrossOriginConnectCallback, IDMapOwnPointer> cross_origin_connect_callbacks_; @@ -414,6 +419,7 @@ ControlleeMap controllee_map_; ControlleeByIDMap controllee_by_id_; + // Will be null while shutting down. base::WeakPtr<ServiceWorkerContextCore> context_; ObserverList<Listener> listeners_; ServiceWorkerScriptCacheMap script_cache_map_;
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc index 0138c90..7cbf53ed 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job.cc +++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -102,6 +102,11 @@ } net::LoadState ServiceWorkerWriteToCacheJob::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ServiceWorkerWriteToCacheJob::GetLoadState")); if (writer_ && writer_->IsWritePending()) return net::LOAD_STATE_WAITING_FOR_APPCACHE; if (net_request_)
diff --git a/content/browser/shared_worker/worker_browsertest.cc b/content/browser/shared_worker/worker_browsertest.cc index ce39df5..14100b9 100644 --- a/content/browser/shared_worker/worker_browsertest.cc +++ b/content/browser/shared_worker/worker_browsertest.cc
@@ -118,9 +118,8 @@ ASSERT_TRUE(ws_server.Start()); // Generate test URL. - std::string scheme("http"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); GURL url = ws_server.GetURL( "websocket_shared_worker.html").ReplaceComponents(replacements);
diff --git a/content/browser/web_contents/opened_by_dom_browsertest.cc b/content/browser/web_contents/opened_by_dom_browsertest.cc index 9a20a94c2..dab6eb8 100644 --- a/content/browser/web_contents/opened_by_dom_browsertest.cc +++ b/content/browser/web_contents/opened_by_dom_browsertest.cc
@@ -123,8 +123,7 @@ GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); GURL::Replacements replace_host; - std::string foo_com("foo.com"); - replace_host.SetHostStr(foo_com); + replace_host.SetHostStr("foo.com"); url2 = url2.ReplaceComponents(replace_host); GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 094361d..84565a2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -202,6 +202,30 @@ static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode); } +// Enable sudden termination for the current RenderFrameHost of +// |frame_tree_node| if the ID of its SiteInstance is |site_instance_id|. Used +// with FrameTree::ForEach. +bool EnableSuddenTermination(int32 site_instance_id, + FrameTreeNode* frame_tree_node) { + if (frame_tree_node->current_frame_host()->GetSiteInstance()->GetId() + == site_instance_id) { + frame_tree_node->current_frame_host() + ->set_override_sudden_termination_status(true); + } + return true; +} + +// Returns false and sets |sudden_termination_allowed| to false if sudden +// termination is not allowed for the current RenderFrameHost of +// |frame_tree_node|. Used with FrameTree::ForEach. +bool SuddenTerminationAllowed(bool* sudden_termination_allowed, + FrameTreeNode* frame_tree_node) { + if (frame_tree_node->current_frame_host()->SuddenTerminationAllowed()) + return true; + *sudden_termination_allowed = false; + return false; +} + } // namespace WebContents* WebContents::Create(const WebContents::CreateParams& params) { @@ -326,8 +350,6 @@ closed_by_user_gesture_(false), minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)), maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)), - totalPinchGestureAmount_(0), - currentPinchZoomStepDelta_(0), render_view_message_source_(NULL), render_frame_message_source_(NULL), fullscreen_widget_routing_id_(MSG_ROUTING_NONE), @@ -641,7 +663,7 @@ return host ? host->GetProcess() : NULL; } -RenderFrameHost* WebContentsImpl::GetMainFrame() { +RenderFrameHostImpl* WebContentsImpl::GetMainFrame() { return frame_tree_.root()->current_frame_host(); } @@ -782,7 +804,7 @@ void WebContentsImpl::SetParentNativeViewAccessible( gfx::NativeViewAccessible accessible_parent) { accessible_parent_ = accessible_parent; - RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame()); + RenderFrameHostImpl* rfh = GetMainFrame(); if (rfh) rfh->SetParentNativeViewAccessible(accessible_parent); } @@ -1111,16 +1133,17 @@ } bool WebContentsImpl::NeedToFireBeforeUnload() { + bool sudden_termination_allowed = true; + frame_tree_.ForEach(base::Bind( + &SuddenTerminationAllowed, &sudden_termination_allowed)); // TODO(creis): Should we fire even for interstitial pages? return WillNotifyDisconnection() && !ShowingInterstitialPage() && - !static_cast<RenderViewHostImpl*>( - GetRenderViewHost())->SuddenTerminationAllowed(); + !sudden_termination_allowed; } void WebContentsImpl::DispatchBeforeUnload(bool for_cross_site_transition) { - static_cast<RenderFrameHostImpl*>(GetMainFrame())->DispatchBeforeUnload( - for_cross_site_transition); + GetMainFrame()->DispatchBeforeUnload(for_cross_site_transition); } void WebContentsImpl::Stop() { @@ -1354,7 +1377,7 @@ void WebContentsImpl::RenderWidgetWasResized( RenderWidgetHostImpl* render_widget_host, bool width_changed) { - RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame()); + RenderFrameHostImpl* rfh = GetMainFrame(); if (!rfh || render_widget_host != rfh->GetRenderWidgetHost()) return; @@ -1402,46 +1425,6 @@ return delegate_ && delegate_->PreHandleGestureEvent(this, event); } -bool WebContentsImpl::HandleGestureEvent( - const blink::WebGestureEvent& event) { - // Some platforms (eg. Mac) send GesturePinch events for trackpad pinch-zoom. - // Use them to implement browser zoom, as for HandleWheelEvent above. - if (event.type == blink::WebInputEvent::GesturePinchUpdate && - event.sourceDevice == blink::WebGestureDeviceTouchpad) { - // The scale difference necessary to trigger a zoom action. Derived from - // experimentation to find a value that feels reasonable. - const float kZoomStepValue = 0.6f; - - // Find the (absolute) thresholds on either side of the current zoom factor, - // then convert those to actual numbers to trigger a zoom in or out. - // This logic deliberately makes the range around the starting zoom value - // for the gesture twice as large as the other ranges (i.e., the notches are - // at ..., -3*step, -2*step, -step, step, 2*step, 3*step, ... but not at 0) - // so that it's easier to get back to your starting point than it is to - // overshoot. - float nextStep = (abs(currentPinchZoomStepDelta_) + 1) * kZoomStepValue; - float backStep = abs(currentPinchZoomStepDelta_) * kZoomStepValue; - float zoomInThreshold = (currentPinchZoomStepDelta_ >= 0) ? nextStep - : -backStep; - float zoomOutThreshold = (currentPinchZoomStepDelta_ <= 0) ? -nextStep - : backStep; - - totalPinchGestureAmount_ += (event.data.pinchUpdate.scale - 1.0); - if (totalPinchGestureAmount_ > zoomInThreshold) { - currentPinchZoomStepDelta_++; - if (delegate_) - delegate_->ContentsZoomChange(true); - } else if (totalPinchGestureAmount_ < zoomOutThreshold) { - currentPinchZoomStepDelta_--; - if (delegate_) - delegate_->ContentsZoomChange(false); - } - return true; - } - - return false; -} - void WebContentsImpl::HandleMouseDown() { if (delegate_) delegate_->HandleMouseDown(); @@ -1811,7 +1794,7 @@ // Resume blocked requests for both the RenderViewHost and RenderFrameHost. // TODO(brettw): It seems bogus to reach into here and initialize the host. static_cast<RenderViewHostImpl*>(new_contents->GetRenderViewHost())->Init(); - static_cast<RenderFrameHostImpl*>(new_contents->GetMainFrame())->Init(); + new_contents->GetMainFrame()->Init(); return new_contents; } @@ -1928,13 +1911,13 @@ BrowserAccessibilityManager* WebContentsImpl::GetRootBrowserAccessibilityManager() { - RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame()); + RenderFrameHostImpl* rfh = GetMainFrame(); return rfh ? rfh->browser_accessibility_manager() : NULL; } BrowserAccessibilityManager* WebContentsImpl::GetOrCreateRootBrowserAccessibilityManager() { - RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame()); + RenderFrameHostImpl* rfh = GetMainFrame(); return rfh ? rfh->GetOrCreateBrowserAccessibilityManager() : NULL; } @@ -2496,6 +2479,11 @@ } void WebContentsImpl::StopFinding(StopFindAction action) { + // See if a top level browser plugin handles the stop finding request first. + if (browser_plugin_embedder_ && + browser_plugin_embedder_->StopFinding(action)) { + return; + } Send(new ViewMsg_StopFinding(GetRoutingID(), action)); } @@ -2541,6 +2529,17 @@ observers_, DidStartProvisionalLoadForFrame( render_frame_host, validated_url, is_error_page, is_iframe_srcdoc)); + + // Notify accessibility if this is a reload. + NavigationEntry* entry = controller_.GetVisibleEntry(); + if (entry && ui::PageTransitionCoreTypeIs( + entry->GetTransitionType(), ui::PAGE_TRANSITION_RELOAD)) { + FrameTreeNode* ftn = render_frame_host->frame_tree_node(); + BrowserAccessibilityManager* manager = + ftn->current_frame_host()->browser_accessibility_manager(); + if (manager) + manager->UserIsReloading(); + } } void WebContentsImpl::DidStartNavigationTransition( @@ -2562,6 +2561,12 @@ validated_url, params.error_code, params.error_description)); + + FrameTreeNode* ftn = render_frame_host->frame_tree_node(); + BrowserAccessibilityManager* manager = + ftn->current_frame_host()->browser_accessibility_manager(); + if (manager) + manager->NavigationFailed(); } void WebContentsImpl::DidFailLoadWithError( @@ -2637,6 +2642,11 @@ observers_, DidCommitProvisionalLoadForFrame( render_frame_host, url, transition_type)); + + BrowserAccessibilityManager* manager = + render_frame_host->browser_accessibility_manager(); + if (manager) + manager->NavigationSucceeded(); } void WebContentsImpl::DidNavigateMainFramePreCommit( @@ -3680,6 +3690,10 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh, base::TerminationStatus status, int error_code) { + // TODO(nasko): This isn't ideal; the termination process should be handled by + // RenderFrameDeleted(). See http://crbug.com/455943. + ClearPowerSaveBlockers(rvh->GetMainFrame()); + if (rvh != GetRenderViewHost()) { // The pending page's RenderViewHost is gone. return; @@ -3808,6 +3822,17 @@ bool to_different_document) { SetIsLoading(render_frame_host->GetRenderViewHost(), true, to_different_document, NULL); + + // Notify accessibility that the user is navigating away from the + // current document. + // + // TODO(dmazzoni): do this using a WebContentsObserver. + FrameTreeNode* ftn = static_cast<RenderFrameHostImpl*>(render_frame_host)-> + frame_tree_node(); + BrowserAccessibilityManager* manager = + ftn->current_frame_host()->browser_accessibility_manager(); + if (manager) + manager->UserIsNavigatingAway(); } void WebContentsImpl::DidStopLoading(RenderFrameHost* render_frame_host) { @@ -4062,7 +4087,8 @@ rfhi->IsWaitingForUnloadACK()) { // Hang occurred while firing the beforeunload/unload handler. // Pretend the handler fired so tab closing continues as if it had. - rvhi->set_sudden_termination_allowed(true); + frame_tree_.ForEach(base::Bind( + &EnableSuddenTermination, rvhi->GetSiteInstance()->GetId())); if (!GetRenderManager()->ShouldCloseTabOnUnresponsiveRenderer()) return;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index c76a40a79..1ed80a1 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -215,7 +215,7 @@ const GURL& GetVisibleURL() const override; const GURL& GetLastCommittedURL() const override; RenderProcessHost* GetRenderProcessHost() const override; - RenderFrameHost* GetMainFrame() override; + RenderFrameHostImpl* GetMainFrame() override; RenderFrameHost* GetFocusedFrame() override; void ForEachFrame( const base::Callback<void(RenderFrameHost*)>& on_frame) override; @@ -542,7 +542,6 @@ void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override; bool PreHandleGestureEvent(const blink::WebGestureEvent& event) override; - bool HandleGestureEvent(const blink::WebGestureEvent& event) override; void DidSendScreenRects(RenderWidgetHostImpl* rwh) override; BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override; BrowserAccessibilityManager* GetOrCreateRootBrowserAccessibilityManager() @@ -1137,11 +1136,6 @@ int minimum_zoom_percent_; int maximum_zoom_percent_; - // The raw accumulated zoom value and the actual zoom increments made for an - // an in-progress pinch gesture. - float totalPinchGestureAmount_; - int currentPinchZoomStepDelta_; - // The intrinsic size of the page. gfx::Size preferred_size_;
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index e4a8ee7..a9ccfda1 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -402,7 +402,7 @@ // to the WebContentObservers. See http://crbug.com/347339. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, RenderFrameCreatedCorrectProcessForObservers) { - std::string foo_com("foo.com"); + static const char kFooCom[] = "foo.com"; GURL::Replacements replace_host; net::HostPortPair foo_host_port; GURL cross_site_url; @@ -413,12 +413,12 @@ ASSERT_TRUE(test_server()->Start()); foo_host_port = test_server()->host_port_pair(); - foo_host_port.set_host(foo_com); + foo_host_port.set_host(kFooCom); GURL initial_url(test_server()->GetURL("/title1.html")); cross_site_url = test_server()->GetURL("/title2.html"); - replace_host.SetHostStr(foo_com); + replace_host.SetHostStr(kFooCom); cross_site_url = cross_site_url.ReplaceComponents(replace_host); // Navigate to the initial URL and capture the RenderFrameHost for later
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index ded5a4b..ab40bcd 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -8,6 +8,7 @@ #include "content/browser/frame_host/cross_site_transferring_request.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/audio_stream_monitor.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" @@ -1425,8 +1426,8 @@ EXPECT_FALSE(fake_delegate.hide_validation_message_was_called()); // Crash the renderer. - contents()->GetMainFrame()->GetRenderViewHost()->OnMessageReceived( - ViewHostMsg_RenderProcessGone( + contents()->GetMainFrame()->OnMessageReceived( + FrameHostMsg_RenderProcessGone( 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); // Confirm HideValidationMessage was called. @@ -1459,8 +1460,8 @@ EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents())); // Crash the renderer. - test_rvh()->OnMessageReceived( - ViewHostMsg_RenderProcessGone( + main_rfh()->OnMessageReceived( + FrameHostMsg_RenderProcessGone( 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); // Confirm fullscreen has exited. @@ -1865,8 +1866,8 @@ interstitial->TestDidNavigate(2, interstitial_url); // Crash the renderer - test_rvh()->OnMessageReceived( - ViewHostMsg_RenderProcessGone( + main_rfh()->OnMessageReceived( + FrameHostMsg_RenderProcessGone( 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); // While the interstitial is showing, go back. @@ -1904,8 +1905,8 @@ interstitial->Show(); // Crash the renderer - test_rvh()->OnMessageReceived( - ViewHostMsg_RenderProcessGone( + main_rfh()->OnMessageReceived( + FrameHostMsg_RenderProcessGone( 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); interstitial->TestDidNavigate(2, interstitial_url); @@ -1956,8 +1957,8 @@ // Before the interstitial has a chance to process its shutdown task, // simulate quitting the browser. This goes through all processes and // tells them to destruct. - rvh->OnMessageReceived( - ViewHostMsg_RenderProcessGone(0, 0, 0)); + rvh->GetMainFrame()->OnMessageReceived( + FrameHostMsg_RenderProcessGone(0, 0, 0)); RunAllPendingInMessageLoop(); EXPECT_TRUE(deleted); @@ -2632,56 +2633,6 @@ contents()->SetDelegate(NULL); } -// Tests that trackpad GesturePinchUpdate events get turned into browser zoom. -TEST_F(WebContentsImplTest, HandleGestureEvent) { - using blink::WebGestureEvent; - using blink::WebInputEvent; - - scoped_ptr<ContentsZoomChangedDelegate> delegate( - new ContentsZoomChangedDelegate()); - contents()->SetDelegate(delegate.get()); - - const float kZoomStepValue = 0.6f; - blink::WebGestureEvent event = SyntheticWebGestureEventBuilder::Build( - WebInputEvent::GesturePinchUpdate, blink::WebGestureDeviceTouchpad); - - // A pinch less than the step value doesn't change the zoom level. - event.data.pinchUpdate.scale = 1.0f + kZoomStepValue * 0.8f; - EXPECT_TRUE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount()); - - // But repeating the event so the combined scale is greater does. - EXPECT_TRUE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount()); - EXPECT_TRUE(delegate->last_zoom_in()); - - // Pinching back out one step goes back to 100%. - event.data.pinchUpdate.scale = 1.0f - kZoomStepValue; - EXPECT_TRUE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount()); - EXPECT_FALSE(delegate->last_zoom_in()); - - // Pinching out again doesn't zoom (step is twice as large around 100%). - EXPECT_TRUE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount()); - - // And again now it zooms once per step. - EXPECT_TRUE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount()); - EXPECT_FALSE(delegate->last_zoom_in()); - - // No other type of gesture event is handled by WebContentsImpl (for example - // a touchscreen pinch gesture). - event = SyntheticWebGestureEventBuilder::Build( - WebInputEvent::GesturePinchUpdate, blink::WebGestureDeviceTouchscreen); - event.data.pinchUpdate.scale = 1.0f + kZoomStepValue * 3; - EXPECT_FALSE(contents()->HandleGestureEvent(event)); - EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount()); - - // Ensure pointers to the delegate aren't kept beyond it's lifetime. - contents()->SetDelegate(NULL); -} - // Tests that GetRelatedActiveContentsCount is shared between related // SiteInstances and includes WebContents that have not navigated yet. TEST_F(WebContentsImplTest, ActiveContentsCountBasic) { @@ -3026,7 +2977,71 @@ FrameHostMsg_MediaPausedNotification(0, kPlayerRemoteId)); EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing()); + + // Start a player with both audio and video. A video power save blocker + // should be created. If audio stream monitoring is available, an audio power + // save blocker should be created too. + rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification( + 0, kPlayerAudioVideoId, true, true, false)); + EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); + EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), + !AudioStreamMonitor::monitoring_available()); + + // Crash the renderer. + contents()->GetMainFrame()->OnMessageReceived( + FrameHostMsg_RenderProcessGone( + 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); + + // Verify that all the power save blockers have been released. + EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing()); + EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing()); } #endif +// Test that sudden termination status is properly tracked for a frame. +TEST_F(WebContentsImplTest, SuddenTerminationForFrame) { + const GURL url("http://www.chromium.org"); + contents()->NavigateAndCommit(url); + + TestRenderFrameHost* frame = contents()->GetMainFrame(); + EXPECT_TRUE(frame->SuddenTerminationAllowed()); + + // Register a BeforeUnload handler. + frame->SendBeforeUnloadHandlersPresent(true); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + + // Unregister the BeforeUnload handler. + frame->SendBeforeUnloadHandlersPresent(false); + EXPECT_TRUE(frame->SuddenTerminationAllowed()); + + // Register an Unload handler. + frame->SendUnloadHandlersPresent(true); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + + // Unregister the Unload handler. + frame->SendUnloadHandlersPresent(false); + EXPECT_TRUE(frame->SuddenTerminationAllowed()); + + // Register a BeforeUnload handler and an Unload handler. + frame->SendBeforeUnloadHandlersPresent(true); + frame->SendUnloadHandlersPresent(true); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + + // Override the sudden termination status. + frame->set_override_sudden_termination_status(true); + EXPECT_TRUE(frame->SuddenTerminationAllowed()); + frame->set_override_sudden_termination_status(false); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + + // Sudden termination should not be allowed unless there are no BeforeUnload + // handlers and no Unload handlers in the RenderFrame. + frame->SendBeforeUnloadHandlersPresent(false); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + frame->SendBeforeUnloadHandlersPresent(true); + frame->SendUnloadHandlersPresent(false); + EXPECT_FALSE(frame->SuddenTerminationAllowed()); + frame->SendBeforeUnloadHandlersPresent(false); + EXPECT_TRUE(frame->SuddenTerminationAllowed()); +} + } // namespace content
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc index 3bde564..100f3cb6 100644 --- a/content/browser/webui/url_data_manager_backend.cc +++ b/content/browser/webui/url_data_manager_backend.cc
@@ -337,11 +337,20 @@ int bytes_read; if (pending_buf_.get()) { CHECK(pending_buf_->data()); + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455423 URLRequestChromeJob::CompleteRead")); CompleteRead(pending_buf_.get(), pending_buf_size_, &bytes_read); pending_buf_ = NULL; NotifyReadComplete(bytes_read); } } else { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION("455423 URLRequestJob::NotifyDone")); // The request failed. NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); @@ -716,10 +725,14 @@ void URLDataManagerBackend::DataAvailable(RequestID request_id, base::RefCountedMemory* bytes) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455423 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455423 URLDataManagerBackend::DataAvailable")); // Forward this data on to the pending net::URLRequest, if it exists. PendingRequestMap::iterator i = pending_requests_.find(request_id); if (i != pending_requests_.end()) { - URLRequestChromeJob* job(i->second); + URLRequestChromeJob* job = i->second; pending_requests_.erase(i); job->DataAvailable(bytes); }
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index f9e69a2..1bec3c8 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -38,7 +38,10 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" -#include "sandbox/linux/suid/client/setuid_sandbox_client.h" +#include "sandbox/linux/services/credentials.h" +#include "sandbox/linux/services/namespace_sandbox.h" +#include "sandbox/linux/services/namespace_utils.h" +#include "sandbox/linux/suid/client/setuid_sandbox_host.h" #include "sandbox/linux/suid/common/sandbox.h" #include "ui/base/ui_base_switches.h" #include "ui/gfx/switches.h" @@ -49,12 +52,14 @@ namespace content { +namespace { + // Receive a fixed message on fd and return the sender's PID. // Returns true if the message received matches the expected message. -static bool ReceiveFixedMessage(int fd, - const char* expect_msg, - size_t expect_len, - base::ProcessId* sender_pid) { +bool ReceiveFixedMessage(int fd, + const char* expect_msg, + size_t expect_len, + base::ProcessId* sender_pid) { char buf[expect_len + 1]; ScopedVector<base::ScopedFD> fds_vec; @@ -69,6 +74,8 @@ return true; } +} // namespace + // static ZygoteHost* ZygoteHost::GetInstance() { return ZygoteHostImpl::GetInstance(); @@ -79,7 +86,7 @@ control_lock_(), pid_(-1), init_(false), - using_suid_sandbox_(false), + use_suid_sandbox_for_adj_oom_score_(false), sandbox_binary_(), have_read_sandbox_status_word_(false), sandbox_status_(0), @@ -141,8 +148,16 @@ sandbox_binary_ = sandbox_cmd.c_str(); + const bool using_namespace_sandbox = ShouldUseNamespaceSandbox(); // A non empty sandbox_cmd means we want a SUID sandbox. - using_suid_sandbox_ = !sandbox_cmd.empty(); + const bool using_suid_sandbox = + !sandbox_cmd.empty() && !using_namespace_sandbox; + + // Use the SUID sandbox for adjusting OOM scores when we are using the setuid + // or namespace sandbox. This is needed beacuse the processes are + // non-dumpable, so /proc/pid/oom_score_adj can only be written by root. + use_suid_sandbox_for_adj_oom_score_ = + using_namespace_sandbox || using_suid_sandbox; // Start up the sandbox host process and get the file descriptor for the // renderers to talk to it. @@ -150,20 +165,24 @@ fds_to_map.push_back(std::make_pair(sfd, GetSandboxFD())); base::ScopedFD dummy_fd; - if (using_suid_sandbox_) { - scoped_ptr<sandbox::SetuidSandboxClient> - sandbox_client(sandbox::SetuidSandboxClient::Create()); - sandbox_client->PrependWrapper(&cmd_line); - sandbox_client->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd); - sandbox_client->SetupLaunchEnvironment(); + if (using_suid_sandbox) { + scoped_ptr<sandbox::SetuidSandboxHost> sandbox_host( + sandbox::SetuidSandboxHost::Create()); + sandbox_host->PrependWrapper(&cmd_line); + sandbox_host->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd); + sandbox_host->SetupLaunchEnvironment(); } options.fds_to_remap = &fds_to_map; - base::Process process = base::LaunchProcess(cmd_line.argv(), options); + base::Process process = + using_namespace_sandbox + ? sandbox::NamespaceSandbox::LaunchProcess(cmd_line, options) + : base::LaunchProcess(cmd_line, options); CHECK(process.IsValid()) << "Failed to launch zygote process"; + dummy_fd.reset(); - if (using_suid_sandbox_) { + if (using_suid_sandbox) { // The SUID sandbox will execute the zygote in a new PID namespace, and // the main zygote process will then fork from there. Watch now our // elaborate dance to find and validate the zygote's PID. @@ -458,7 +477,7 @@ selinux_valid = true; } - if (using_suid_sandbox_ && !selinux) { + if (use_suid_sandbox_for_adj_oom_score_ && !selinux) { #if defined(USE_TCMALLOC) // If heap profiling is running, these processes are not exiting, at least // on ChromeOS. The easiest thing to do is not launch them when profiling. @@ -482,7 +501,7 @@ base::LaunchProcess(adj_oom_score_cmdline, options); if (sandbox_helper_process.IsValid()) base::EnsureProcessGetsReaped(sandbox_helper_process.Pid()); - } else if (!using_suid_sandbox_) { + } else if (!use_suid_sandbox_for_adj_oom_score_) { if (!base::AdjustOOMScore(pid, score)) PLOG(ERROR) << "Failed to adjust OOM score of renderer with pid " << pid; } @@ -559,4 +578,22 @@ return 0; } +bool ZygoteHostImpl::ShouldUseNamespaceSandbox() { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kNoSandbox)) { + return false; + } + + if (!command_line.HasSwitch(switches::kEnableNamespaceSandbox)) { + return false; + } + + if (!sandbox::Credentials::CanCreateProcessInNewUserNS()) { + return false; + } + + return true; +} + } // namespace content
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.h b/content/browser/zygote_host/zygote_host_impl_linux.h index e18e0980..643989f 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.h +++ b/content/browser/zygote_host/zygote_host_impl_linux.h
@@ -82,6 +82,9 @@ ssize_t ReadReply(void* buf, size_t buflen); + // Whether we should use the namespace sandbox instead of the setuid sandbox. + bool ShouldUseNamespaceSandbox(); + int control_fd_; // the socket to the zygote // A lock protecting all communication with the zygote. This lock must be // acquired before sending a command and released after the result has been @@ -89,7 +92,7 @@ base::Lock control_lock_; pid_t pid_; bool init_; - bool using_suid_sandbox_; + bool use_suid_sandbox_for_adj_oom_score_; std::string sandbox_binary_; bool have_read_sandbox_status_word_; int sandbox_status_;
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index a8d488a..53b076f 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -59,6 +59,7 @@ #include "third_party/WebKit/public/platform/WebWaitableEvent.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h" #include "ui/base/layout.h" +#include "ui/events/keycodes/dom4/keycode_converter.h" using blink::WebData; using blink::WebFallbackThemeEngine; @@ -665,38 +666,6 @@ return result; } -blink::Platform::TraceEventHandle BlinkPlatformImpl::addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - unsigned char flags) { - return addTraceEvent(phase, category_group_enabled, name, id, - monotonicallyIncreasingTime(), - num_args, arg_names, arg_types, arg_values, flags); -} - -blink::Platform::TraceEventHandle BlinkPlatformImpl::addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - const blink::WebConvertableToTraceFormat* convertable_values, - unsigned char flags) { - return addTraceEvent(phase, category_group_enabled, name, id, - monotonicallyIncreasingTime(), - num_args, arg_names, arg_types, arg_values, - convertable_values, flags); -} - void BlinkPlatformImpl::updateTraceEventDuration( const unsigned char* category_group_enabled, const char* name, @@ -1286,4 +1255,14 @@ delete impl; } +WebString BlinkPlatformImpl::domCodeStringFromEnum(int dom_code) { + return WebString::fromUTF8(ui::KeycodeConverter::DomCodeToCodeString( + static_cast<ui::DomCode>(dom_code))); +} + +int BlinkPlatformImpl::domEnumFromCodeString(const WebString& code) { + return static_cast<int>(ui::KeycodeConverter::CodeStringToDomCode( + code.utf8().data())); +} + } // namespace content
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 25e6826..2c1764f 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -122,29 +122,6 @@ const unsigned long long* arg_values, const blink::WebConvertableToTraceFormat* convertable_values, unsigned char flags); - // TODO(charliea): Remove the addTraceEvent methods without timestamps - // once Blink uses the new signature with timestamps - virtual TraceEventHandle addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - unsigned char flags); - virtual TraceEventHandle addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - const blink::WebConvertableToTraceFormat* convertable_values, - unsigned char flags); virtual void updateTraceEventDuration( const unsigned char* category_group_enabled, const char* name, @@ -189,6 +166,9 @@ WebBluetoothImpl* BluetoothImplForTesting() { return bluetooth_.get(); } + virtual blink::WebString domCodeStringFromEnum(int dom_code); + virtual int domEnumFromCodeString(const blink::WebString& codeString); + private: static void DestroyCurrentThread(void*);
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index 20decd40..6f1727a 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h
@@ -22,8 +22,14 @@ namespace base { class MessageLoop; -namespace debug { +namespace trace_event { class TraceMemoryController; +} // namespace trace_event + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TraceMemoryController; } // namespace debug } // namespace base
diff --git a/content/child/notifications/notification_data_conversions.h b/content/child/notifications/notification_data_conversions.h index 2739ca42..24a8bab 100644 --- a/content/child/notifications/notification_data_conversions.h +++ b/content/child/notifications/notification_data_conversions.h
@@ -7,7 +7,7 @@ #include "content/common/content_export.h" #include "content/public/common/platform_notification_data.h" -#include "third_party/WebKit/public/platform/WebNotificationData.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h" namespace content {
diff --git a/content/child/notifications/notification_data_conversions_unittest.cc b/content/child/notifications/notification_data_conversions_unittest.cc index 4089bbe..ac08574 100644 --- a/content/child/notifications/notification_data_conversions_unittest.cc +++ b/content/child/notifications/notification_data_conversions_unittest.cc
@@ -7,9 +7,9 @@ #include "base/strings/utf_string_conversions.h" #include "content/public/common/platform_notification_data.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebNotificationData.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h" namespace content { namespace {
diff --git a/content/child/notifications/notification_image_loader.cc b/content/child/notifications/notification_image_loader.cc index c194b024..a844a43 100644 --- a/content/child/notifications/notification_image_loader.cc +++ b/content/child/notifications/notification_image_loader.cc
@@ -7,7 +7,6 @@ #include "base/logging.h" #include "content/child/child_thread_impl.h" #include "content/child/image_decoder.h" -#include "content/child/worker_task_runner.h" #include "third_party/WebKit/public/platform/Platform.h" #include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/platform/WebURLLoader.h" @@ -27,12 +26,14 @@ NotificationImageLoader::~NotificationImageLoader() {} -void NotificationImageLoader::StartOnMainThread(const WebURL& image_url, - int worker_thread_id) { +void NotificationImageLoader::StartOnMainThread( + const WebURL& image_url, + const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner) { DCHECK(ChildThreadImpl::current()); DCHECK(!url_loader_); + DCHECK(worker_task_runner); - worker_thread_id_ = worker_thread_id; + worker_task_runner_ = worker_task_runner; WebURLRequest request(image_url); request.setRequestContext(WebURLRequest::RequestContextImage); @@ -79,14 +80,10 @@ void NotificationImageLoader::RunCallbackOnWorkerThread() { scoped_refptr<NotificationImageLoader> loader = make_scoped_refptr(this); - if (!worker_thread_id_) { + if (worker_task_runner_->BelongsToCurrentThread()) callback_.Run(loader); - return; - } - - WorkerTaskRunner::Instance()->PostTask( - worker_thread_id_, - base::Bind(callback_, loader)); + else + worker_task_runner_->PostTask(FROM_HERE, base::Bind(callback_, loader)); } } // namespace content
diff --git a/content/child/notifications/notification_image_loader.h b/content/child/notifications/notification_image_loader.h index a3a723c8..33c615c 100644 --- a/content/child/notifications/notification_image_loader.h +++ b/content/child/notifications/notification_image_loader.h
@@ -14,6 +14,10 @@ class SkBitmap; +namespace base { +class SingleThreadTaskRunner; +} + namespace blink { class WebURL; struct WebURLError; @@ -41,9 +45,11 @@ const NotificationImageLoadedCallback& callback); // Asynchronously starts loading |image_url|. - // Must be called on the main thread. |worker_thread_id| identifies the id - // of the thread on which the callback should be executed upon completion. - void StartOnMainThread(const blink::WebURL& image_url, int worker_thread_id); + // Must be called on the main thread. The callback should be executed by + // |worker_task_runner|. + void StartOnMainThread( + const blink::WebURL& image_url, + const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner); // Returns the SkBitmap resulting from decoding the loaded buffer. SkBitmap GetDecodedImage() const; @@ -71,7 +77,7 @@ NotificationImageLoadedCallback callback_; scoped_ptr<blink::WebURLLoader> url_loader_; - int worker_thread_id_; + scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_; bool completed_; std::vector<uint8_t> buffer_;
diff --git a/content/child/notifications/notification_manager.cc b/content/child/notifications/notification_manager.cc index 39cb604..9108a3a 100644 --- a/content/child/notifications/notification_manager.cc +++ b/content/child/notifications/notification_manager.cc
@@ -6,6 +6,7 @@ #include "base/lazy_instance.h" #include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" #include "base/threading/thread_local.h" #include "content/child/notifications/notification_data_conversions.h" #include "content/child/notifications/notification_dispatcher.h" @@ -15,9 +16,9 @@ #include "content/child/worker_task_runner.h" #include "content/common/platform_notification_messages.h" #include "content/public/common/platform_notification_data.h" -#include "third_party/WebKit/public/platform/WebNotificationData.h" -#include "third_party/WebKit/public/platform/WebNotificationDelegate.h" #include "third_party/WebKit/public/platform/WebSerializedOrigin.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationDelegate.h" #include "third_party/skia/include/core/SkBitmap.h" using blink::WebNotificationPermission; @@ -212,11 +213,9 @@ new NotificationImageLoader(callback)); main_thread_task_runner_->PostTask( - FROM_HERE, - base::Bind(&NotificationImageLoader::StartOnMainThread, - pending_notification, - image_url, - CurrentWorkerId())); + FROM_HERE, base::Bind(&NotificationImageLoader::StartOnMainThread, + pending_notification, image_url, + base::ThreadTaskRunnerHandle::Get())); return pending_notification; }
diff --git a/content/child/notifications/notification_manager.h b/content/child/notifications/notification_manager.h index 1fb44ba..47d979d5 100644 --- a/content/child/notifications/notification_manager.h +++ b/content/child/notifications/notification_manager.h
@@ -15,7 +15,7 @@ #include "content/child/notifications/notification_dispatcher.h" #include "content/child/notifications/notification_image_loader.h" #include "content/child/worker_task_runner.h" -#include "third_party/WebKit/public/platform/WebNotificationManager.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationManager.h" class SkBitmap;
diff --git a/content/child/push_messaging/push_provider.cc b/content/child/push_messaging/push_provider.cc index c795625..48ff9b5 100644 --- a/content/child/push_messaging/push_provider.cc +++ b/content/child/push_messaging/push_provider.cc
@@ -13,8 +13,8 @@ #include "content/child/thread_safe_sender.h" #include "content/child/worker_task_runner.h" #include "content/common/push_messaging_messages.h" -#include "third_party/WebKit/public/platform/WebPushRegistration.h" #include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushRegistration.h" namespace content { namespace {
diff --git a/content/child/push_messaging/push_provider.h b/content/child/push_messaging/push_provider.h index 3a243c78..4557ceb 100644 --- a/content/child/push_messaging/push_provider.h +++ b/content/child/push_messaging/push_provider.h
@@ -12,8 +12,8 @@ #include "content/child/push_messaging/push_dispatcher.h" #include "content/child/worker_task_runner.h" #include "content/public/common/push_messaging_status.h" -#include "third_party/WebKit/public/platform/WebPushError.h" -#include "third_party/WebKit/public/platform/WebPushProvider.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushProvider.h" class GURL;
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index bccff3b..1a1c88a4 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -576,6 +576,17 @@ base::TimeTicks renderer_completion_time = ToRendererCompletionTime( *request_info, request_complete_data.completion_time); + + // If we have a threaded data provider, this message needs to bounce off the + // background thread before it's returned to this thread and handled, + // to make sure it's processed after all incoming data. + if (request_info->threaded_data_provider) { + request_info->threaded_data_provider->OnRequestCompleteForegroundThread( + weak_factory_.GetWeakPtr(), request_complete_data, + renderer_completion_time); + return; + } + // The request ID will be removed from our pending list in the destructor. // Normally, dispatching this message causes the reference-counted request to // die immediately. @@ -587,6 +598,23 @@ request_complete_data.encoded_data_length); } +void ResourceDispatcher::CompletedRequestAfterBackgroundThreadFlush( + int request_id, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time) { + PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); + if (!request_info) + return; + + RequestPeer* peer = request_info->peer; + peer->OnCompletedRequest(request_complete_data.error_code, + request_complete_data.was_ignored_by_handler, + request_complete_data.exists_in_cache, + request_complete_data.security_info, + renderer_completion_time, + request_complete_data.encoded_data_length); +} + int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, ResourceType resource_type, int origin_pid,
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index 9df2d868..ce21c3b 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -91,6 +91,20 @@ bool AttachThreadedDataReceiver( int request_id, blink::WebThreadedDataReceiver* threaded_data_receiver); + // If we have a ThreadedDataProvider attached, an OnRequestComplete message + // will get bounced via the background thread and then passed to this function + // to resume processing. + void CompletedRequestAfterBackgroundThreadFlush( + int request_id, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time); + + void set_message_sender(IPC::Sender* sender) { + DCHECK(sender); + DCHECK(pending_requests_.empty()); + message_sender_ = sender; + } + IPC::Sender* message_sender() const { return message_sender_; } // This does not take ownership of the delegate. It is expected that the
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 79b0f24..fe4bb69 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -4,8 +4,11 @@ #include "content/child/runtime_features.h" +#include <vector> + #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/strings/string_split.h" #include "content/common/content_switches_internal.h" #include "content/public/common/content_switches.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" @@ -186,6 +189,29 @@ WebRuntimeFeatures::enableV8IdleTasks(false); else WebRuntimeFeatures::enableV8IdleTasks(true); + + // Enable explicitly enabled features, and then disable explicitly disabled + // ones. + if (command_line.HasSwitch(switches::kEnableBlinkFeatures)) { + std::vector<std::string> enabled_features; + base::SplitString( + command_line.GetSwitchValueASCII(switches::kEnableBlinkFeatures), ',', + &enabled_features); + for (const std::string& feature : enabled_features) { + WebRuntimeFeatures::enableFeatureFromString( + blink::WebString::fromLatin1(feature), true); + } + } + if (command_line.HasSwitch(switches::kDisableBlinkFeatures)) { + std::vector<std::string> disabled_features; + base::SplitString( + command_line.GetSwitchValueASCII(switches::kDisableBlinkFeatures), ',', + &disabled_features); + for (const std::string& feature : disabled_features) { + WebRuntimeFeatures::enableFeatureFromString( + blink::WebString::fromLatin1(feature), false); + } + } } } // namespace content
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index 73b9a29..2a713bc 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -84,8 +84,6 @@ OnSetControllerServiceWorker) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument, OnPostMessage) - IPC_MESSAGE_HANDLER(ServiceWorkerMsg_GetClientInfo, - OnGetClientInfo) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() DCHECK(handled) << "Unhandled message:" << msg.type(); @@ -663,30 +661,6 @@ found->second->dispatchMessageEvent(message, ports); } -void ServiceWorkerDispatcher::OnGetClientInfo(int thread_id, - int embedded_worker_id, - int request_id, - int provider_id) { - blink::WebServiceWorkerClientInfo info; - ProviderClientMap::iterator found = provider_clients_.find(provider_id); - // TODO(ksakamoto): Could we track these values in the browser side? Except - // for |isFocused|, it would be pretty easy. - if (found != provider_clients_.end() && found->second->getClientInfo(&info)) { - ServiceWorkerClientInfo result; - result.client_id = info.clientID; - result.page_visibility_state = info.pageVisibilityState; - result.is_focused = info.isFocused; - result.url = info.url; - result.frame_type = static_cast<RequestContextFrameType>(info.frameType); - - thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetClientInfoSuccess( - embedded_worker_id, request_id, result)); - } else { - thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetClientInfoError( - embedded_worker_id, request_id)); - } -} - void ServiceWorkerDispatcher::AddServiceWorker( int handle_id, WebServiceWorkerImpl* worker) { DCHECK(!ContainsKey(service_workers_, handle_id));
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h index 3f1deff..9ef86cc 100644 --- a/content/child/service_worker/service_worker_dispatcher.h +++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -205,10 +205,6 @@ const base::string16& message, const std::vector<int>& sent_message_port_ids, const std::vector<int>& new_routing_ids); - void OnGetClientInfo(int thread_id, - int embedded_worker_id, - int request_id, - int provider_id); void SetReadyRegistration( int provider_id,
diff --git a/content/child/threaded_data_provider.cc b/content/child/threaded_data_provider.cc index 69ed34b..6a533d3 100644 --- a/content/child/threaded_data_provider.cc +++ b/content/child/threaded_data_provider.cc
@@ -157,13 +157,13 @@ delete threaded_data_receiver_; } -void DestructOnMainThread(ThreadedDataProvider* data_provider) { +void ThreadedDataProvider::DestructOnMainThread() { DCHECK(ChildThreadImpl::current()); // The ThreadedDataProvider must be destructed on the main thread to // be threadsafe when removing the message filter and releasing the shared // memory buffer. - delete data_provider; + delete this; } void ThreadedDataProvider::Stop() { @@ -203,7 +203,35 @@ // use this instance on the background thread. background_thread_weak_factory_.reset(NULL); main_thread_task_runner_->PostTask(FROM_HERE, - base::Bind(&DestructOnMainThread, this)); + base::Bind(&ThreadedDataProvider::DestructOnMainThread, + base::Unretained(this))); +} + +void ThreadedDataProvider::OnRequestCompleteForegroundThread( + base::WeakPtr<ResourceDispatcher> resource_dispatcher, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time) { + DCHECK(ChildThreadImpl::current()); + + background_thread_.message_loop()->PostTask(FROM_HERE, + base::Bind(&ThreadedDataProvider::OnRequestCompleteBackgroundThread, + base::Unretained(this), resource_dispatcher, + request_complete_data, renderer_completion_time)); +} + +void ThreadedDataProvider::OnRequestCompleteBackgroundThread( + base::WeakPtr<ResourceDispatcher> resource_dispatcher, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time) { + DCHECK(background_thread_.isCurrentThread()); + + main_thread_task_runner_->PostTask(FROM_HERE, + base::Bind( + &ResourceDispatcher::CompletedRequestAfterBackgroundThreadFlush, + resource_dispatcher, + request_id_, + request_complete_data, + renderer_completion_time)); } void ThreadedDataProvider::OnResourceMessageFilterAddedMainThread() { @@ -229,7 +257,7 @@ if (!queued_data_.empty()) { std::vector<QueuedSharedMemoryData>::iterator iter = queued_data_.begin(); for (; iter != queued_data_.end(); ++iter) { - ForwardAndACKData(iter->data, iter->length); + ForwardAndACKData(iter->data, iter->length, iter->encoded_length); } queued_data_.clear(); @@ -247,7 +275,7 @@ CHECK(data_ptr + data_offset); if (resource_filter_active_) { - ForwardAndACKData(data_ptr + data_offset, data_length); + ForwardAndACKData(data_ptr + data_offset, data_length, encoded_data_length); } else { // There's a brief interval between the point where we know the filter // has been installed on the I/O thread, and when we know for sure there's @@ -258,6 +286,7 @@ QueuedSharedMemoryData queued_data; queued_data.data = data_ptr + data_offset; queued_data.length = data_length; + queued_data.encoded_length = encoded_data_length; queued_data_.push_back(queued_data); } } @@ -269,11 +298,12 @@ background_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(&ThreadedDataProvider::ForwardAndACKData, base::Unretained(this), - data, data_length)); + data, data_length, encoded_data_length)); } void ThreadedDataProvider::ForwardAndACKData(const char* data, - int data_length) { + int data_length, + int encoded_data_length) { DCHECK(background_thread_.isCurrentThread()); // TODO(oysteine): SiteIsolationPolicy needs to be be checked @@ -281,7 +311,34 @@ // (or earlier on the I/O thread), otherwise once SiteIsolationPolicy does // actual blocking as opposed to just UMA logging this will bypass it. threaded_data_receiver_->acceptData(data, data_length); + + scoped_ptr<std::vector<char>> data_copy; + if (threaded_data_receiver_->needsMainthreadDataCopy()) { + data_copy.reset(new std::vector<char>(data, data + data_length)); + } + + main_thread_task_runner_->PostTask(FROM_HERE, + base::Bind(&ThreadedDataProvider::DataNotifyForegroundThread, + base::Unretained(this), + base::Passed(&data_copy), + data_length, + encoded_data_length)); + ipc_channel_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_)); } +void ThreadedDataProvider::DataNotifyForegroundThread( + scoped_ptr<std::vector<char> > data_copy, + int data_length, + int encoded_data_length) { + if (data_copy) { + DCHECK(threaded_data_receiver_->needsMainthreadDataCopy()); + DCHECK_EQ((size_t)data_length, data_copy->size()); + } + + threaded_data_receiver_->acceptMainthreadDataNotification( + (data_copy && !data_copy->empty()) ? &data_copy->front() : NULL, + data_length, encoded_data_length); +} + } // namespace content
diff --git a/content/child/threaded_data_provider.h b/content/child/threaded_data_provider.h index 0605ac13..fcd7008 100644 --- a/content/child/threaded_data_provider.h +++ b/content/child/threaded_data_provider.h
@@ -14,6 +14,8 @@ #include "ipc/ipc_channel.h" #include "ipc/message_filter.h" +struct ResourceMsg_RequestCompleteData; + namespace blink { class WebThreadedDataReceiver; } @@ -23,6 +25,7 @@ } namespace content { +class ResourceDispatcher; class WebThreadImpl; class ThreadedDataProvider { @@ -33,8 +36,9 @@ linked_ptr<base::SharedMemory> shm_buffer, int shm_size, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_); - virtual ~ThreadedDataProvider(); + // Any destruction of this class has to bounce via the background thread to + // ensure all data is flushed; call Stop() to start this process. void Stop(); void OnReceivedDataOnBackgroundThread(int data_offset, int data_length, @@ -45,11 +49,28 @@ int encoded_data_length); void OnResourceMessageFilterAddedMainThread(); + void OnRequestCompleteForegroundThread( + base::WeakPtr<ResourceDispatcher> resource_dispatcher, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time); private: + ~ThreadedDataProvider(); + void DestructOnMainThread(); + void StopOnBackgroundThread(); void OnResourceMessageFilterAddedBackgroundThread(); - void ForwardAndACKData(const char* data, int data_length); + void OnRequestCompleteBackgroundThread( + base::WeakPtr<ResourceDispatcher> resource_dispatcher, + const ResourceMsg_RequestCompleteData& request_complete_data, + const base::TimeTicks& renderer_completion_time); + void ForwardAndACKData(const char* data, + int data_length, + int encoded_data_length); + void DataNotifyForegroundThread( + scoped_ptr<std::vector<char> > data_copy, + int data_length, + int encoded_data_length); scoped_refptr<IPC::MessageFilter> filter_; int request_id_; @@ -66,6 +87,7 @@ struct QueuedSharedMemoryData { const char* data; int length; + int encoded_length; }; std::vector<QueuedSharedMemoryData> queued_data_;
diff --git a/content/child/web_data_consumer_handle_impl.cc b/content/child/web_data_consumer_handle_impl.cc index a26656ed..a310238 100644 --- a/content/child/web_data_consumer_handle_impl.cc +++ b/content/child/web_data_consumer_handle_impl.cc
@@ -7,6 +7,7 @@ #include <limits> #include "base/bind.h" #include "base/logging.h" +#include "base/profiler/scoped_tracker.h" #include "third_party/mojo/src/mojo/public/c/system/types.h" namespace content { @@ -109,6 +110,11 @@ } void WebDataConsumerHandleImpl::OnHandleGotReadable(MojoResult) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455434 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455434 WebDataConsumerHandleImpl::OnHandleGotReadable")); DCHECK(client_); client_->didGetReadable(); }
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 1f852bd..adca0daa 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -14,6 +14,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" +#include "base/profiler/scoped_tracker.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/time/time.h" @@ -896,6 +897,11 @@ } void WebURLLoaderImpl::Context::OnHandleGotWritable(MojoResult result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455434 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455434 WebURLLoaderImpl::Context::OnHandleGotWritable")); if (result != MOJO_RESULT_OK) { if (client_) { client_->didFail(loader_,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 1760a33..d6cf0421 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -147,6 +147,7 @@ "//third_party/icu", "//ui/accessibility", "//ui/base", + "//ui/base/ime", "//ui/events/ipc", "//ui/gfx", "//ui/gfx/geometry",
diff --git a/content/common/DEPS b/content/common/DEPS index e8daa45..1e63887 100644 --- a/content/common/DEPS +++ b/content/common/DEPS
@@ -24,10 +24,7 @@ "+third_party/WebKit/public/platform/WebIDBDatabase.h", "+third_party/WebKit/public/platform/WebIDBTypes.h", "+third_party/WebKit/public/platform/WebLockOrientationError.h", - "+third_party/WebKit/public/platform/WebNotificationPermission.h", "+third_party/WebKit/public/platform/WebPageVisibilityState.h", - "+third_party/WebKit/public/platform/WebPushError.h", - "+third_party/WebKit/public/platform/WebPushPermissionStatus.h", "+third_party/WebKit/public/platform/WebReferrerPolicy.h", "+third_party/WebKit/public/platform/WebScreenOrientationLockType.h", "+third_party/WebKit/public/platform/WebScreenOrientationType.h", @@ -41,6 +38,9 @@ "+third_party/WebKit/public/platform/WebString.h", "+third_party/WebKit/public/platform/linux/WebFontRenderStyle.h", "+third_party/WebKit/public/platform/linux/WebFallbackFont.h", + "+third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h", + "+third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h", + "+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h", "+third_party/WebKit/public/web/mac/WebScrollbarTheme.h", "+third_party/WebKit/public/web/WebAXEnums.h", "+third_party/WebKit/public/web/WebCompositionUnderline.h",
diff --git a/content/common/dwrite_font_platform_win.cc b/content/common/dwrite_font_platform_win.cc index c2547b5..aa9d98f 100644 --- a/content/common/dwrite_font_platform_win.cc +++ b/content/common/dwrite_font_platform_win.cc
@@ -746,6 +746,24 @@ return reg_fonts_[idx]; } +const wchar_t* kFontsToIgnore[] = { + // "Gill Sans Ultra Bold" turns into an Ultra Bold weight "Gill Sans" in + // DirectWrite, but most users don't have any other weights. The regular + // weight font is named "Gill Sans MT", but that ends up in a different + // family with that name. On Mac, there's a "Gill Sans" with various weights, + // so CSS authors use { 'font-family': 'Gill Sans', 'Gill Sans MT', ... } and + // because of the DirectWrite family futzing, they end up with an Ultra Bold + // font, when they just wanted "Gill Sans". Mozilla implemented a more + // complicated hack where they effectively rename the Ultra Bold font to + // "Gill Sans MT Ultra Bold", but because the Ultra Bold font is so ugly + // anyway, we simply ignore it. See + // http://www.microsoft.com/typography/fonts/font.aspx?FMID=978 for a picture + // of the font, and the file name. We also ignore "Gill Sans Ultra Bold + // Condensed". + L"gilsanub.ttf", + L"gillubcd.ttf", +}; + bool FontCollectionLoader::LoadFontListFromRegistry() { const wchar_t kFontsRegistry[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; @@ -773,7 +791,15 @@ value.size() < kMaxFontFileNameLength - 1) || base::FilePath::CompareEqualIgnoreCase(system_font_path.value(), path.DirName().value())) { - reg_fonts_.push_back(value.c_str()); + bool should_ignore = false; + for (const auto& ignore : kFontsToIgnore) { + if (base::FilePath::CompareEqualIgnoreCase(path.value(), ignore)) { + should_ignore = true; + break; + } + } + if (!should_ignore) + reg_fonts_.push_back(value.c_str()); } } }
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index d22c7043..a80f1b6 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -214,10 +214,11 @@ IPC_STRUCT_TRAITS_MEMBER(report_type) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams) - IPC_STRUCT_TRAITS_MEMBER(is_post) - IPC_STRUCT_TRAITS_MEMBER(extra_headers) - IPC_STRUCT_TRAITS_MEMBER(browser_initiated_post_data) +IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams) + IPC_STRUCT_TRAITS_MEMBER(method) + IPC_STRUCT_TRAITS_MEMBER(headers) + IPC_STRUCT_TRAITS_MEMBER(load_flags) + IPC_STRUCT_TRAITS_MEMBER(has_user_gesture) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::CommitNavigationParams) @@ -251,9 +252,18 @@ // These structs contain parameters shared by other navigation IPCs. IPC_STRUCT_MEMBER(content::CommonNavigationParams, common_params) - IPC_STRUCT_MEMBER(content::RequestNavigationParams, request_params) IPC_STRUCT_MEMBER(content::CommitNavigationParams, commit_params) + // Whether the navigation is a POST request (as opposed to a GET). + IPC_STRUCT_MEMBER(bool, is_post) + + // Extra headers (separated by \n) to send during the request. + IPC_STRUCT_MEMBER(std::string, extra_headers) + + // If is_post is true, holds the post_data information from browser. Empty + // otherwise. + IPC_STRUCT_MEMBER(std::vector<unsigned char>, browser_initiated_post_data) + // The page_id for this navigation, or -1 if it is a new navigation. Back, // Forward, and Reload navigations should have a valid page_id. If the load // succeeds, then this page_id will be reflected in the resultant @@ -319,28 +329,6 @@ IPC_STRUCT_MEMBER(bool, user_gesture) IPC_STRUCT_END() -// PlzNavigate -IPC_STRUCT_BEGIN(FrameHostMsg_BeginNavigation_Params) - // TODO(clamy): See if it is possible to define a common struct between this - // IPC and ResourceMsg_Request_Params. - - // The request method: GET, POST, etc. - IPC_STRUCT_MEMBER(std::string, method) - - // Additional HTTP request headers. - IPC_STRUCT_MEMBER(std::string, headers) - - // net::URLRequest load flags (net::LOAD_NORMAL) by default). - IPC_STRUCT_MEMBER(int, load_flags) - - // Optional resource request body (may be null). - IPC_STRUCT_MEMBER(scoped_refptr<content::ResourceRequestBody>, - request_body) - - // True if the request was user initiated. - IPC_STRUCT_MEMBER(bool, has_user_gesture) -IPC_STRUCT_END() - #if defined(OS_MACOSX) || defined(OS_ANDROID) // This message is used for supporting popup menus on Mac OS X and Android using // native controls. See the FrameHostMsg_ShowPopup message. @@ -397,6 +385,10 @@ // Requests that the RenderFrame or RenderFrameProxy sets its opener to null. IPC_MESSAGE_ROUTED0(FrameMsg_DisownOpener) +// Requests that the RenderFrame send back a response after waiting for the +// commit, activation and frame swap of the current DOM tree in blink. +IPC_MESSAGE_ROUTED1(FrameMsg_FlushVisualStateRequest, uint64 /* id */) + // Instructs the renderer to create a new RenderFrame object with |routing_id|. // The new frame should be created as a child of the object identified by // |parent_routing_id| or as top level if that is MSG_ROUTING_NONE. @@ -545,12 +537,6 @@ #endif // PlzNavigate -// Tells the renderer that a navigation has been requested. -IPC_MESSAGE_ROUTED2(FrameMsg_RequestNavigation, - content::CommonNavigationParams, /* common_params */ - content::RequestNavigationParams /* request_params */) - -// PlzNavigate // Tells the renderer that a navigation is ready to commit. The renderer should // request |stream_url| to get access to the stream containing the body of the // response. @@ -591,6 +577,12 @@ // detached from the DOM. IPC_MESSAGE_ROUTED0(FrameHostMsg_Detach) +// Indicates the renderer process is gone. This actually is sent by the +// browser process to itself, but keeps the interface cleaner. +IPC_MESSAGE_ROUTED2(FrameHostMsg_RenderProcessGone, + int, /* this really is base::TerminationStatus */ + int /* exit_code */) + // Sent by the renderer when the frame becomes focused. IPC_MESSAGE_ROUTED0(FrameHostMsg_FrameFocused) @@ -844,18 +836,31 @@ // PlzNavigate // Tells the browser to perform a navigation. -IPC_MESSAGE_ROUTED2(FrameHostMsg_BeginNavigation, - FrameHostMsg_BeginNavigation_Params, - content::CommonNavigationParams) +IPC_MESSAGE_ROUTED3(FrameHostMsg_BeginNavigation, + content::CommonNavigationParams, + content::BeginNavigationParams, + scoped_refptr<content::ResourceRequestBody>) // Sent once a paint happens after the first non empty layout. In other words // after the frame has painted something. IPC_MESSAGE_ROUTED0(FrameHostMsg_DidFirstVisuallyNonEmptyPaint) +// Sent as a response to FrameMsg_FlushVisualStateRequest. +// The message is delivered using RenderWidget::QueueMessage. +IPC_MESSAGE_ROUTED1(FrameHostMsg_FlushVisualStateResponse, uint64 /* id */) + // Puts the browser into "tab fullscreen" mode for the sending renderer. // See the comment in chrome/browser/ui/browser.h for more details. IPC_MESSAGE_ROUTED1(FrameHostMsg_ToggleFullscreen, bool /* enter_fullscreen */) +// Messages to signal the presence or absence of BeforeUnload or Unload handlers +// for a frame. |present| is true if there is at least one of the handlers for +// the frame. +IPC_MESSAGE_ROUTED1(FrameHostMsg_BeforeUnloadHandlersPresent, + bool /* present */) +IPC_MESSAGE_ROUTED1(FrameHostMsg_UnloadHandlersPresent, + bool /* present */) + #if defined(OS_MACOSX) || defined(OS_ANDROID) // Message to show/hide a popup menu using native controls.
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc index ec473f32..0f894be5 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.cc +++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -25,13 +25,13 @@ namespace content { -CommandBufferProxyImpl::CommandBufferProxyImpl( - GpuChannelHost* channel, - int route_id) +CommandBufferProxyImpl::CommandBufferProxyImpl(GpuChannelHost* channel, + int route_id) : channel_(channel), route_id_(route_id), flush_count_(0), last_put_offset_(-1), + last_barrier_put_offset_(-1), next_signal_id_(0) { } @@ -179,16 +179,36 @@ "put_offset", put_offset); - if (last_put_offset_ == put_offset) + bool put_offset_changed = last_put_offset_ != put_offset; + last_put_offset_ = put_offset; + last_barrier_put_offset_ = put_offset; + + if (channel_) { + channel_->OrderingBarrier(route_id_, put_offset, ++flush_count_, + latency_info_, put_offset_changed, true); + } + + if (put_offset_changed) + latency_info_.clear(); +} + +void CommandBufferProxyImpl::OrderingBarrier(int32 put_offset) { + if (last_state_.error != gpu::error::kNoError) return; - last_put_offset_ = put_offset; + TRACE_EVENT1("gpu", "CommandBufferProxyImpl::OrderingBarrier", "put_offset", + put_offset); - Send(new GpuCommandBufferMsg_AsyncFlush(route_id_, - put_offset, - ++flush_count_, - latency_info_)); - latency_info_.clear(); + bool put_offset_changed = last_barrier_put_offset_ != put_offset; + last_barrier_put_offset_ = put_offset; + + if (channel_) { + channel_->OrderingBarrier(route_id_, put_offset, ++flush_count_, + latency_info_, put_offset_changed, false); + } + + if (put_offset_changed) + latency_info_.clear(); } void CommandBufferProxyImpl::SetLatencyInfo(
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h index ea39740..28af2ef4 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.h +++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -89,6 +89,7 @@ State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 shm_id) override; @@ -190,6 +191,7 @@ int route_id_; unsigned int flush_count_; int32 last_put_offset_; + int32 last_barrier_put_offset_; base::Closure channel_error_callback_;
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc index be28c50c..72e8991 100644 --- a/content/common/gpu/client/gpu_channel_host.cc +++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -30,6 +30,16 @@ GpuListenerInfo::~GpuListenerInfo() {} +ProxyFlushInfo::ProxyFlushInfo() + : flush_pending(false), + route_id(MSG_ROUTING_NONE), + put_offset(0), + flush_count(0) { +} + +ProxyFlushInfo::~ProxyFlushInfo() { +} + // static scoped_refptr<GpuChannelHost> GpuChannelHost::Create( GpuChannelHostFactory* factory, @@ -112,6 +122,39 @@ return false; } +void GpuChannelHost::OrderingBarrier( + int route_id, + int32 put_offset, + unsigned int flush_count, + const std::vector<ui::LatencyInfo>& latency_info, + bool put_offset_changed, + bool do_flush) { + AutoLock lock(context_lock_); + if (flush_info_.flush_pending && flush_info_.route_id != route_id) + InternalFlush(); + + if (put_offset_changed) { + flush_info_.flush_pending = true; + flush_info_.route_id = route_id; + flush_info_.put_offset = put_offset; + flush_info_.flush_count = flush_count; + flush_info_.latency_info.insert(flush_info_.latency_info.end(), + latency_info.begin(), latency_info.end()); + + if (do_flush) + InternalFlush(); + } +} + +void GpuChannelHost::InternalFlush() { + DCHECK(flush_info_.flush_pending); + Send(new GpuCommandBufferMsg_AsyncFlush( + flush_info_.route_id, flush_info_.put_offset, flush_info_.flush_count, + flush_info_.latency_info)); + flush_info_.latency_info.clear(); + flush_info_.flush_pending = false; +} + CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer( int32 surface_id, CommandBufferProxyImpl* share_group, @@ -178,10 +221,8 @@ init_params.gpu_preference = gpu_preference; int32 route_id = GenerateRouteID(); bool succeeded = false; - if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size, - init_params, - route_id, - &succeeded))) { + if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer( + size, init_params, route_id, &succeeded))) { LOG(ERROR) << "Failed to send GpuChannelMsg_CreateOffscreenCommandBuffer."; return NULL; } @@ -229,6 +270,9 @@ AutoLock lock(context_lock_); proxies_.erase(route_id); + if (flush_info_.flush_pending && flush_info_.route_id == route_id) + flush_info_.flush_pending = false; + delete command_buffer; }
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h index 877baa0..fbff47b5b 100644 --- a/content/common/gpu/client/gpu_channel_host.h +++ b/content/common/gpu/client/gpu_channel_host.h
@@ -23,6 +23,7 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_sync_channel.h" #include "ipc/message_filter.h" +#include "ui/events/latency_info.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" @@ -63,6 +64,17 @@ scoped_refptr<base::MessageLoopProxy> loop; }; +struct ProxyFlushInfo { + ProxyFlushInfo(); + ~ProxyFlushInfo(); + + bool flush_pending; + int route_id; + int32 put_offset; + unsigned int flush_count; + std::vector<ui::LatencyInfo> latency_info; +}; + class CONTENT_EXPORT GpuChannelHostFactory { public: virtual ~GpuChannelHostFactory() {} @@ -103,6 +115,15 @@ // IPC::Sender implementation: bool Send(IPC::Message* msg) override; + // Set an ordering barrier. AsyncFlushes any pending barriers on other + // routes. Combines multiple OrderingBarriers into a single AsyncFlush. + void OrderingBarrier(int route_id, + int32 put_offset, + unsigned int flush_count, + const std::vector<ui::LatencyInfo>& latency_info, + bool put_offset_changed, + bool do_flush); + // Create and connect to a command buffer in the GPU process. CommandBufferProxyImpl* CreateViewCommandBuffer( int32 surface_id, @@ -173,6 +194,8 @@ ~GpuChannelHost() override; void Connect(const IPC::ChannelHandle& channel_handle, base::WaitableEvent* shutdown_event); + bool InternalSend(IPC::Message* msg); + void InternalFlush(); // A filter used internally to route incoming messages from the IO thread // to the correct message loop. It also maintains some shared state between @@ -245,6 +268,7 @@ // Used to look up a proxy from its routing id. typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap; ProxyMap proxies_; + ProxyFlushInfo flush_info_; DISALLOW_COPY_AND_ASSIGN(GpuChannelHost); };
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h index fe47f69..24679b0 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h
@@ -24,7 +24,7 @@ public gpu::ImageFactory { public: GpuMemoryBufferFactorySurfaceTexture(); - ~GpuMemoryBufferFactorySurfaceTexture(); + ~GpuMemoryBufferFactorySurfaceTexture() override; static bool IsGpuMemoryBufferConfigurationSupported( gfx::GpuMemoryBuffer::Format format,
diff --git a/content/common/gpu/image_transport_surface_android.cc b/content/common/gpu/image_transport_surface_android.cc index a2cadd0..6d67df28 100644 --- a/content/common/gpu/image_transport_surface_android.cc +++ b/content/common/gpu/image_transport_surface_android.cc
@@ -39,11 +39,11 @@ const gfx::GLSurfaceHandle& handle); // gfx::GLSurface implementation. - virtual bool OnMakeCurrent(gfx::GLContext* context) override; - virtual void WakeUpGpu() override; + bool OnMakeCurrent(gfx::GLContext* context) override; + void WakeUpGpu() override; protected: - virtual ~ImageTransportSurfaceAndroid(); + ~ImageTransportSurfaceAndroid() override; private: void ScheduleWakeUp(); @@ -59,10 +59,10 @@ gfx::GLSurface* surface); // gfx::GLSurface implementation. - virtual bool SwapBuffers() override; + bool SwapBuffers() override; protected: - virtual ~DirectSurfaceAndroid(); + ~DirectSurfaceAndroid() override; private: DISALLOW_COPY_AND_ASSIGN(DirectSurfaceAndroid);
diff --git a/content/common/gpu/media/android_video_decode_accelerator.h b/content/common/gpu/media/android_video_decode_accelerator.h index 2b41925..ae299c8 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.h +++ b/content/common/gpu/media/android_video_decode_accelerator.h
@@ -37,16 +37,15 @@ const base::Callback<bool(void)>& make_context_current); // media::VideoDecodeAccelerator implementation. - virtual bool Initialize(media::VideoCodecProfile profile, - Client* client) override; - virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) override; - virtual void AssignPictureBuffers( + bool Initialize(media::VideoCodecProfile profile, Client* client) override; + void Decode(const media::BitstreamBuffer& bitstream_buffer) override; + void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override; - virtual void ReusePictureBuffer(int32 picture_buffer_id) override; - virtual void Flush() override; - virtual void Reset() override; - virtual void Destroy() override; - virtual bool CanDecodeOnIOThread() override; + void ReusePictureBuffer(int32 picture_buffer_id) override; + void Flush() override; + void Reset() override; + void Destroy() override; + bool CanDecodeOnIOThread() override; private: enum State { @@ -56,7 +55,7 @@ static const base::TimeDelta kDecodePollDelay; - virtual ~AndroidVideoDecodeAccelerator(); + ~AndroidVideoDecodeAccelerator() override; // Configures |media_codec_| with the given codec parameters from the client. bool ConfigureMediaCodec();
diff --git a/content/common/gpu/media/android_video_decode_accelerator_unittest.cc b/content/common/gpu/media/android_video_decode_accelerator_unittest.cc index e391d11..efd5b75 100644 --- a/content/common/gpu/media/android_video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/android_video_decode_accelerator_unittest.cc
@@ -33,29 +33,27 @@ class MockVideoDecodeAcceleratorClient : public media::VideoDecodeAccelerator::Client { public: - MockVideoDecodeAcceleratorClient() {}; - virtual ~MockVideoDecodeAcceleratorClient() {}; + MockVideoDecodeAcceleratorClient() {} + ~MockVideoDecodeAcceleratorClient() override {} // VideoDecodeAccelerator::Client implementation. - virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, - const gfx::Size& dimensions, - uint32 texture_target) override {}; - virtual void DismissPictureBuffer(int32 picture_buffer_id) override {}; - virtual void PictureReady(const media::Picture& picture) override {}; - virtual void NotifyEndOfBitstreamBuffer( - int32 bitstream_buffer_id) override {}; - virtual void NotifyFlushDone() override {}; - virtual void NotifyResetDone() override {}; - virtual void NotifyError( - media::VideoDecodeAccelerator::Error error) override {}; + void ProvidePictureBuffers(uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + uint32 texture_target) override {} + void DismissPictureBuffer(int32 picture_buffer_id) override {} + void PictureReady(const media::Picture& picture) override {} + void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) override {} + void NotifyFlushDone() override {} + void NotifyResetDone() override {} + void NotifyError(media::VideoDecodeAccelerator::Error error) override {} }; class AndroidVideoDecodeAcceleratorTest : public testing::Test { public: - virtual ~AndroidVideoDecodeAcceleratorTest() {} + ~AndroidVideoDecodeAcceleratorTest() override {} protected: - virtual void SetUp() override { + void SetUp() override { JNIEnv* env = base::android::AttachCurrentThread(); media::RegisterJni(env); // TODO(felipeg): fix GL bindings, so that the decoder can perform GL
diff --git a/content/common/gpu/media/android_video_encode_accelerator.h b/content/common/gpu/media/android_video_encode_accelerator.h index a587f104..7f2f4c01 100644 --- a/content/common/gpu/media/android_video_encode_accelerator.h +++ b/content/common/gpu/media/android_video_encode_accelerator.h
@@ -32,23 +32,22 @@ : public media::VideoEncodeAccelerator { public: AndroidVideoEncodeAccelerator(); - virtual ~AndroidVideoEncodeAccelerator(); + ~AndroidVideoEncodeAccelerator() override; // media::VideoEncodeAccelerator implementation. - virtual std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles() override; - virtual bool Initialize(media::VideoFrame::Format format, - const gfx::Size& input_visible_size, - media::VideoCodecProfile output_profile, - uint32 initial_bitrate, - Client* client) override; - virtual void Encode(const scoped_refptr<media::VideoFrame>& frame, - bool force_keyframe) override; - virtual void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) - override; - virtual void RequestEncodingParametersChange(uint32 bitrate, - uint32 framerate) override; - virtual void Destroy() override; + std::vector<media::VideoEncodeAccelerator::SupportedProfile> + GetSupportedProfiles() override; + bool Initialize(media::VideoFrame::Format format, + const gfx::Size& input_visible_size, + media::VideoCodecProfile output_profile, + uint32 initial_bitrate, + Client* client) override; + void Encode(const scoped_refptr<media::VideoFrame>& frame, + bool force_keyframe) override; + void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) override; + void RequestEncodingParametersChange(uint32 bitrate, + uint32 framerate) override; + void Destroy() override; private: enum {
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc index 69ea9f7..fb51f59 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc +++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -884,6 +884,12 @@ RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); } + hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); + if (SUCCEEDED(hr)) { + DVLOG(1) << "Successfully set Low latency mode on decoder."; + } else { + DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; + } return true; }
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc index 82acdce..019446b 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -21,7 +21,6 @@ #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" #include "media/base/media_switches.h" #include "media/filters/h264_parser.h" -#include "ui/gfx/geometry/rect.h" #include "ui/gl/scoped_binders.h" #define NOTIFY_ERROR(x) \ @@ -340,7 +339,7 @@ // thread is waiting on pictures_assigned_. DCHECK(free_output_buffers_.empty()); for (size_t i = 0; i < output_buffer_map_.size(); ++i) { - DCHECK(buffers[i].size() == coded_size_); + DCHECK(buffers[i].size() == frame_buffer_size_); OutputRecord& output_record = output_buffer_map_[i]; DCHECK(!output_record.at_device); @@ -353,7 +352,7 @@ EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, egl_context_, buffers[i].texture_id(), - coded_size_, + frame_buffer_size_, i, output_format_fourcc_, output_planes_count_); @@ -730,9 +729,8 @@ // Check and see if we have format info yet. struct v4l2_format format; - gfx::Size visible_size; bool again = false; - if (!GetFormatInfo(&format, &visible_size, &again)) + if (!GetFormatInfo(&format, &again)) return false; if (again) { @@ -745,7 +743,7 @@ if (decoder_state_ == kInitialized) { DVLOG(3) << "DecodeBufferInitial(): running initialization"; // Success! Setup our parameters. - if (!CreateBuffersForFormat(format, visible_size)) + if (!CreateBuffersForFormat(format)) return false; // We expect to process the initial buffer once during stream init to @@ -1087,7 +1085,7 @@ << " as picture_id=" << output_record.picture_id; const media::Picture& picture = media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec, - gfx::Rect(visible_size_), false); + gfx::Rect(frame_buffer_size_), false); pending_picture_ready_.push( PictureRecord(output_record.cleared, picture)); SendPictureReady(); @@ -1535,15 +1533,14 @@ struct v4l2_format format; bool again; - gfx::Size visible_size; - bool ret = GetFormatInfo(&format, &visible_size, &again); + bool ret = GetFormatInfo(&format, &again); if (!ret || again) { LOG(ERROR) << "Couldn't get format information after resolution change"; NOTIFY_ERROR(PLATFORM_FAILURE); return; } - if (!CreateBuffersForFormat(format, visible_size)) { + if (!CreateBuffersForFormat(format)) { LOG(ERROR) << "Couldn't reallocate buffers after resolution change"; NOTIFY_ERROR(PLATFORM_FAILURE); return; @@ -1618,8 +1615,7 @@ } bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, - gfx::Size* visible_size, - bool* again) { + bool* again) { DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); *again = false; @@ -1643,22 +1639,17 @@ return false; } - gfx::Size coded_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height); - if (!GetVisibleSize(coded_size, visible_size)) - *visible_size = coded_size; - return true; } bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( - const struct v4l2_format& format, - const gfx::Size& visible_size) { + const struct v4l2_format& format) { DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); output_planes_count_ = format.fmt.pix_mp.num_planes; - coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); - visible_size_ = visible_size; + frame_buffer_size_.SetSize( + format.fmt.pix_mp.width, format.fmt.pix_mp.height); DVLOG(3) << "CreateBuffersForFormat(): new resolution: " - << coded_size_.ToString(); + << frame_buffer_size_.ToString(); if (!CreateOutputBuffers()) return false; @@ -1666,40 +1657,6 @@ return true; } -bool V4L2VideoDecodeAccelerator::GetVisibleSize(const gfx::Size& coded_size, - gfx::Size* visible_size) { - DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); - - struct v4l2_crop crop_arg; - memset(&crop_arg, 0, sizeof(crop_arg)); - crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - - IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CROP, &crop_arg); - - gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width, - crop_arg.c.height); - DVLOG(3) << "visible rectangle is " << rect.ToString(); - if (!gfx::Rect(coded_size).Contains(rect)) { - DLOG(ERROR) << "visible rectangle " << rect.ToString() - << " is not inside coded size " << coded_size.ToString(); - return false; - } - if (rect.IsEmpty()) { - DLOG(ERROR) << "visible size is empty"; - return false; - } - - // Chrome assume picture frame is coded at (0, 0). - if (!rect.origin().IsOrigin()) { - DLOG(ERROR) << "Unexpected visible rectangle " << rect.ToString() - << ", top-left is not origin"; - return false; - } - *visible_size = rect.size(); - - return true; -} - bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { DVLOG(3) << "CreateInputBuffers()"; // We always run this as we prepare to initialize. @@ -1829,12 +1786,13 @@ DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " << "buffer_count=" << output_buffer_map_.size() - << ", coded_size=" << coded_size_.ToString(); + << ", width=" << frame_buffer_size_.width() + << ", height=" << frame_buffer_size_.height(); child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, output_buffer_map_.size(), - coded_size_, + frame_buffer_size_, device_->GetTextureTarget())); // Wait for the client to call AssignPictureBuffers() on the Child thread. @@ -2007,16 +1965,15 @@ return true; } struct v4l2_format format; - gfx::Size visible_size; bool again = false; - bool ret = GetFormatInfo(&format, &visible_size, &again); + bool ret = GetFormatInfo(&format, &again); if (!ret || again) { DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed"; return false; } - gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width), - base::checked_cast<int>(format.fmt.pix_mp.height)); - if (coded_size_ != new_coded_size) { + gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), + base::checked_cast<int>(format.fmt.pix_mp.height)); + if (frame_buffer_size_ != new_size) { DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; return true; }
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.h b/content/common/gpu/media/v4l2_video_decode_accelerator.h index 11eba5ab..43ab8f1 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.h
@@ -242,18 +242,11 @@ void StartResolutionChangeIfNeeded(); void FinishResolutionChange(); - // Try to get output format and visible size, detected after parsing the - // beginning of the stream. Sets |again| to true if more parsing is needed. - bool GetFormatInfo(struct v4l2_format* format, - gfx::Size* visible_size, - bool* again); - // Create output buffers for the given |format| and |visible_size|. - bool CreateBuffersForFormat(const struct v4l2_format& format, - const gfx::Size& visible_size); - - // Try to get |visible_size|. Return false if cropping is not supported or the - // crop size is not inside |coded_size|. - bool GetVisibleSize(const gfx::Size& coded_size, gfx::Size* visible_size); + // Try to get output format, detected after parsing the beginning + // of the stream. Sets |again| to true if more parsing is needed. + bool GetFormatInfo(struct v4l2_format* format, bool* again); + // Create output buffers for the given |format|. + bool CreateBuffersForFormat(const struct v4l2_format& format); // // Device tasks, to be run on device_poll_thread_. @@ -422,11 +415,8 @@ // to avoid races with potential Reset requests. base::WaitableEvent pictures_assigned_; - // Output picture coded size. - gfx::Size coded_size_; - - // Output picture visible size. - gfx::Size visible_size_; + // Output picture size. + gfx::Size frame_buffer_size_; // // The device polling thread handles notifications of V4L2 device changes.
diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc index 628b4c8..941bc11 100644 --- a/content/common/gpu/media/vaapi_drm_picture.cc +++ b/content/common/gpu/media/vaapi_drm_picture.cc
@@ -105,7 +105,7 @@ gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, texture_id()); gl_image_ = ui::GpuMemoryBufferFactoryOzoneNativeBuffer::CreateImageForPixmap( - pixmap_, size(), gfx::GpuMemoryBuffer::RGBA_8888, GL_RGBA); + pixmap_, size(), gfx::GpuMemoryBuffer::BGRA_8888, GL_RGBA); if (!gl_image_) { LOG(ERROR) << "Failed to create GLImage"; return false;
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc index af6f1498..f1e63bb0 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.cc +++ b/content/common/gpu/media/vt_video_decode_accelerator.cc
@@ -632,15 +632,27 @@ CVImageBufferRef image_buffer) { if (status) { NOTIFY_STATUS("Decoding", status); - } else if (CFGetTypeID(image_buffer) != CVPixelBufferGetTypeID()) { + return; + } + + // The type of |image_buffer| is CVImageBuffer, but we only handle + // CVPixelBuffers. This should be guaranteed as we set + // kCVPixelBufferOpenGLCompatibilityKey in |image_config|. + // + // Sometimes, for unknown reasons (http://crbug.com/453050), |image_buffer| is + // NULL, which causes CFGetTypeID() to crash. While the rest of the code would + // smoothly handle NULL as a dropped frame, we choose to fail permanantly here + // until the issue is better understood. + if (!image_buffer || CFGetTypeID(image_buffer) != CVPixelBufferGetTypeID()) { DLOG(ERROR) << "Decoded frame is not a CVPixelBuffer"; NotifyError(PLATFORM_FAILURE); - } else { - Frame* frame = reinterpret_cast<Frame*>(source_frame_refcon); - frame->image.reset(image_buffer, base::scoped_policy::RETAIN); - gpu_task_runner_->PostTask(FROM_HERE, base::Bind( - &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); + return; } + + Frame* frame = reinterpret_cast<Frame*>(source_frame_refcon); + frame->image.reset(image_buffer, base::scoped_policy::RETAIN); + gpu_task_runner_->PostTask(FROM_HERE, base::Bind( + &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); } void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) { @@ -715,7 +727,10 @@ switch (state_) { case STATE_DECODING: // TODO(sandersd): Batch where possible. - while (ProcessReorderQueue() || ProcessTaskQueue()); + while (state_ == STATE_DECODING) { + if (!ProcessReorderQueue() && !ProcessTaskQueue()) + break; + } return; case STATE_ERROR:
diff --git a/content/common/gpu/stream_texture_android.h b/content/common/gpu/stream_texture_android.h index 066d4fa..72e4ed4 100644 --- a/content/common/gpu/stream_texture_android.h +++ b/content/common/gpu/stream_texture_android.h
@@ -30,32 +30,32 @@ StreamTexture(GpuCommandBufferStub* owner_stub, int32 route_id, uint32 texture_id); - virtual ~StreamTexture(); + ~StreamTexture() override; // gfx::GLImage implementation: - virtual void Destroy(bool have_context) override; - virtual gfx::Size GetSize() override; - virtual bool BindTexImage(unsigned target) override; - virtual void ReleaseTexImage(unsigned target) override; - virtual bool CopyTexImage(unsigned target) override; - virtual void WillUseTexImage() override; - virtual void DidUseTexImage() override {} - virtual void WillModifyTexImage() override {} - virtual void DidModifyTexImage() override {} - virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int z_order, - gfx::OverlayTransform transform, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect) override; + void Destroy(bool have_context) override; + gfx::Size GetSize() override; + bool BindTexImage(unsigned target) override; + void ReleaseTexImage(unsigned target) override; + bool CopyTexImage(unsigned target) override; + void WillUseTexImage() override; + void DidUseTexImage() override {} + void WillModifyTexImage() override {} + void DidModifyTexImage() override {} + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override; // GpuCommandBufferStub::DestructionObserver implementation. - virtual void OnWillDestroyStub() override; + void OnWillDestroyStub() override; // Called when a new frame is available for the SurfaceTexture. void OnFrameAvailable(); // IPC::Listener implementation: - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; // IPC message handlers: void OnStartListening();
diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h index 8bff08c..511805ea 100644 --- a/content/common/media/media_player_messages_android.h +++ b/content/common/media/media_player_messages_android.h
@@ -30,6 +30,8 @@ IPC_STRUCT_TRAITS_MEMBER(audio_sampling_rate) IPC_STRUCT_TRAITS_MEMBER(is_audio_encrypted) IPC_STRUCT_TRAITS_MEMBER(audio_extra_data) + IPC_STRUCT_TRAITS_MEMBER(audio_codec_delay_ns) + IPC_STRUCT_TRAITS_MEMBER(audio_seek_preroll_ns) IPC_STRUCT_TRAITS_MEMBER(video_codec) IPC_STRUCT_TRAITS_MEMBER(video_size)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 63e6908..4171937 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -34,21 +34,20 @@ CommonNavigationParams::~CommonNavigationParams() { } -RequestNavigationParams::RequestNavigationParams() : is_post(false) {} - -RequestNavigationParams::RequestNavigationParams( - bool is_post, - const std::string& extra_headers, - const base::RefCountedMemory* post_data) - : is_post(is_post), - extra_headers(extra_headers) { - if (post_data) { - browser_initiated_post_data.assign( - post_data->front(), post_data->front() + post_data->size()); - } +BeginNavigationParams::BeginNavigationParams() + : load_flags(0), + has_user_gesture(false) { } -RequestNavigationParams::~RequestNavigationParams() {} +BeginNavigationParams::BeginNavigationParams(std::string method, + std::string headers, + int load_flags, + bool has_user_gesture) + : method(method), + headers(headers), + load_flags(load_flags), + has_user_gesture(has_user_gesture) { +} CommitNavigationParams::CommitNavigationParams() : is_overriding_user_agent(false) {
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index b23847c..757d1a7 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -68,24 +68,27 @@ FrameMsg_UILoadMetricsReportType::Value report_type; }; -// Used by FrameMsg_Navigate. -// PlzNavigate: sent to the renderer when requesting a navigation. -struct CONTENT_EXPORT RequestNavigationParams { - RequestNavigationParams(); - RequestNavigationParams(bool is_post, - const std::string& extra_headers, - const base::RefCountedMemory* post_data); - ~RequestNavigationParams(); +// PlzNavigate: parameters needed to start a navigation on the IO thread. +struct CONTENT_EXPORT BeginNavigationParams { + // TODO(clamy): See if it is possible to reuse this in + // ResourceMsg_Request_Params. + BeginNavigationParams(); + BeginNavigationParams(std::string method, + std::string headers, + int load_flags, + bool has_user_gesture); - // Whether the navigation is a POST request (as opposed to a GET). - bool is_post; + // The request method: GET, POST, etc. + std::string method; - // Extra headers (separated by \n) to send during the request. - std::string extra_headers; + // Additional HTTP request headers. + std::string headers; - // If is_post is true, holds the post_data information from browser. Empty - // otherwise. - std::vector<unsigned char> browser_initiated_post_data; + // net::URLRequest load flags (net::LOAD_NORMAL) by default). + int load_flags; + + // True if the request was user initiated. + bool has_user_gesture; }; // Used by FrameMsg_Navigate.
diff --git a/content/common/platform_notification_messages.h b/content/common/platform_notification_messages.h index 96358e8..778574c 100644 --- a/content/common/platform_notification_messages.h +++ b/content/common/platform_notification_messages.h
@@ -7,7 +7,7 @@ #include "content/public/common/platform_notification_data.h" #include "ipc/ipc_message_macros.h" -#include "third_party/WebKit/public/platform/WebNotificationPermission.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h" #include "third_party/skia/include/core/SkBitmap.h" #define IPC_MESSAGE_START PlatformNotificationMsgStart
diff --git a/content/common/push_messaging_messages.h b/content/common/push_messaging_messages.h index bd945d2b..2acf204 100644 --- a/content/common/push_messaging_messages.h +++ b/content/common/push_messaging_messages.h
@@ -7,8 +7,8 @@ #include "content/public/common/push_messaging_status.h" #include "ipc/ipc_message_macros.h" -#include "third_party/WebKit/public/platform/WebPushError.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" #include "url/gurl.h" #define IPC_MESSAGE_START PushMessagingMsgStart
diff --git a/content/common/sandbox_init_win.cc b/content/common/sandbox_init_win.cc index fe67bda7..16e3e4a 100644 --- a/content/common/sandbox_init_win.cc +++ b/content/common/sandbox_init_win.cc
@@ -26,11 +26,6 @@ // process to swap its window station. During this time all the UI will be // broken. This has to run before threads and windows are created. if (!command_line.HasSwitch(switches::kNoSandbox)) { -#if defined(ADDRESS_SANITIZER) && defined(OS_WIN) - LOG(FATAL) << "AddressSanitizer for Windows doesn't support sandboxing " - "yet (http://crbug.com/382867). " - "Please rerun with sandbox disabled."; -#endif // Precreate the desktop and window station used by the renderers. sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); sandbox::ResultCode result = policy->CreateAlternateDesktop(true);
diff --git a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h index 4a0e6c5..f8693d9 100644 --- a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h +++ b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h
@@ -15,10 +15,10 @@ class SandboxBPFBasePolicyAndroid : public SandboxBPFBasePolicy { public: SandboxBPFBasePolicyAndroid(); - virtual ~SandboxBPFBasePolicyAndroid(); + ~SandboxBPFBasePolicyAndroid() override; // sandbox::SandboxBPFPolicy: - virtual sandbox::bpf_dsl::ResultExpr EvaluateSyscall( + sandbox::bpf_dsl::ResultExpr EvaluateSyscall( int system_call_number) const override; private:
diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc index 480b265..998a0fe 100644 --- a/content/common/sandbox_linux/sandbox_linux.cc +++ b/content/common/sandbox_linux/sandbox_linux.cc
@@ -32,6 +32,7 @@ #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" #include "content/public/common/content_switches.h" #include "content/public/common/sandbox_linux.h" +#include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/services/proc_util.h" #include "sandbox/linux/services/thread_helpers.h" #include "sandbox/linux/services/yama.h" @@ -115,8 +116,7 @@ seccomp_bpf_with_tsync_supported_(false), yama_is_enforcing_(false), initialize_sandbox_ran_(false), - setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) -{ + setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) { if (setuid_sandbox_client_ == NULL) { LOG(FATAL) << "Failed to instantiate the setuid sandbox client."; } @@ -213,6 +213,12 @@ sandbox_status_flags_ |= kSandboxLinuxPIDNS; if (setuid_sandbox_client_->IsInNewNETNamespace()) sandbox_status_flags_ |= kSandboxLinuxNetNS; + } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) { + sandbox_status_flags_ |= kSandboxLinuxUserNS; + if (sandbox::NamespaceSandbox::InNewPidNamespace()) + sandbox_status_flags_ |= kSandboxLinuxPIDNS; + if (sandbox::NamespaceSandbox::InNewNetNamespace()) + sandbox_status_flags_ |= kSandboxLinuxNetNS; } // We report whether the sandbox will be activated when renderers, workers
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc index c401d873..17893ffa 100644 --- a/content/common/sandbox_win.cc +++ b/content/common/sandbox_win.cc
@@ -339,12 +339,24 @@ return false; #endif // NDEBUG + // Add the policy for read-only PDB file access for AddressSanitizer. +#if defined(ADDRESS_SANITIZER) + base::FilePath exe; + if (!PathService::Get(base::FILE_EXE, &exe)) + return false; + base::FilePath pdb_path = exe.DirName().Append(L"*.pdb"); + result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, + sandbox::TargetPolicy::FILES_ALLOW_READONLY, + pdb_path.value().c_str()); + if (result != sandbox::SBOX_ALL_OK) + return false; +#endif + AddGenericDllEvictionPolicy(policy); return true; } -bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy, - std::string& type_str) { +bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) { sandbox::ResultCode result; // Renderers need to share events with plugins. result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, @@ -354,11 +366,8 @@ return false; // Win8+ adds a device DeviceApi that we don't need. - // Only close this handle on renderer processes. See crbug.com/452613. - if (base::win::GetVersion() > base::win::VERSION_WIN7 && - type_str == switches::kRendererProcess) { + if (base::win::GetVersion() > base::win::VERSION_WIN7) result = policy->AddKernelObjectToClose(L"File", L"\\Device\\DeviceApi"); - } if (result != sandbox::SBOX_ALL_OK) return false; @@ -653,8 +662,7 @@ if (delegate) delegate->PreSandbox(&disable_default_policy, &exposed_dir); - if (!disable_default_policy && - !AddPolicyForSandboxedProcess(policy, type_str)) + if (!disable_default_policy && !AddPolicyForSandboxedProcess(policy)) return base::Process(); if (type_str == switches::kRendererProcess) {
diff --git a/content/common/service_worker/service_worker_client_info.cc b/content/common/service_worker/service_worker_client_info.cc new file mode 100644 index 0000000..5662818 --- /dev/null +++ b/content/common/service_worker/service_worker_client_info.cc
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/service_worker/service_worker_client_info.h" + +#include "base/logging.h" +#include "content/common/service_worker/service_worker_types.h" + +namespace content { + +ServiceWorkerClientInfo::ServiceWorkerClientInfo() + : client_id(kInvalidServiceWorkerClientId), + page_visibility_state(blink::WebPageVisibilityStateLast), + is_focused(false), + frame_type(REQUEST_CONTEXT_FRAME_TYPE_LAST) { +} + +ServiceWorkerClientInfo::ServiceWorkerClientInfo( + blink::WebPageVisibilityState page_visibility_state, + bool is_focused, + const GURL& url, + RequestContextFrameType frame_type) + : client_id(kInvalidServiceWorkerClientId), + page_visibility_state(page_visibility_state), + is_focused(is_focused), + url(url), + frame_type(frame_type) { +} + +bool ServiceWorkerClientInfo::IsEmpty() const { + return page_visibility_state == blink::WebPageVisibilityStateLast && + is_focused == false && + url.is_empty() && + frame_type == REQUEST_CONTEXT_FRAME_TYPE_LAST; +} + +bool ServiceWorkerClientInfo::IsValid() const { + return !IsEmpty() && client_id != kInvalidServiceWorkerClientId; +} + +} // namespace content
diff --git a/content/common/service_worker/service_worker_client_info.h b/content/common/service_worker/service_worker_client_info.h new file mode 100644 index 0000000..c90ba69 --- /dev/null +++ b/content/common/service_worker/service_worker_client_info.h
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_INFO_CLIENT_H_ +#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_INFO_CLIENT_H_ + +#include "content/public/common/request_context_frame_type.h" +#include "third_party/WebKit/public/platform/WebPageVisibilityState.h" +#include "url/gurl.h" + +namespace content { + +// This class holds the information related to a service worker window client. +// It is the content/ equivalent of Blink's WebServiceWorkerClientInfo. +// An instance can be created empty or can be filed with the expected +// properties. Except for the client_id, it is preferred to use the constructor +// to fill the properties. +struct ServiceWorkerClientInfo { + ServiceWorkerClientInfo(); + ServiceWorkerClientInfo(blink::WebPageVisibilityState page_visibility_state, + bool is_focused, + const GURL& url, + RequestContextFrameType frame_type); + + // Returns whether the instance is empty. + bool IsEmpty() const; + + // Returns whether the instance is valid. A valid instance is not empty and + // has a valid client_id. + bool IsValid() const; + + int client_id; + blink::WebPageVisibilityState page_visibility_state; + bool is_focused; + GURL url; + RequestContextFrameType frame_type; +}; + +} // namespace content + +#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_INFO_CLIENT_H_
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h index 5aee688..1c644866 100644 --- a/content/common/service_worker/service_worker_messages.h +++ b/content/common/service_worker/service_worker_messages.h
@@ -8,6 +8,7 @@ #include <vector> #include "base/strings/string16.h" +#include "content/common/service_worker/service_worker_client_info.h" #include "content/common/service_worker/service_worker_status_code.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/common/navigator_connect_client.h" @@ -222,20 +223,16 @@ base::string16 /* message */, std::vector<int> /* sent_message_port_ids */) +// Ask the browser to open a tab/window (renderer->browser). +IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_OpenWindow, + int /* request_id */, + GURL /* url */) + // Ask the browser to focus a client (renderer->browser). IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_FocusClient, int /* request_id */, int /* client_id */) -// Response to ServiceWorkerMsg_GetClientInfo. -IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_GetClientInfoSuccess, - int /* request_id */, - content::ServiceWorkerClientInfo) - -// Response to ServiceWorkerMsg_GetClientInfo. -IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_GetClientInfoError, - int /* request_id */) - // Asks the browser to force this worker to become activated. IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_SkipWaiting, int /* request_id */) @@ -403,13 +400,6 @@ std::vector<int> /* sent_message_port_ids */, std::vector<int> /* new_routing_ids */) -// Sent to client documents to request document properties. -IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_GetClientInfo, - int /* thread_id */, - int /* embedded_worker_id */, - int /* request_id */, - int /* provider_id */) - // Sent via EmbeddedWorker to dispatch events. IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_InstallEvent, int /* request_id */, @@ -459,10 +449,19 @@ int /* request_id */, std::vector<content::ServiceWorkerClientInfo>) +// Sent via EmbeddedWorker as a response of OpenWindow. +IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_OpenWindowResponse, + int /* request_id */, + content::ServiceWorkerClientInfo /* client */) + +// Sent via EmbeddedWorker as an error response of OpenWindow. +IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_OpenWindowError, + int /* request_id */ ) + // Sent via EmbeddedWorker as a response of FocusClient. IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FocusClientResponse, int /* request_id */, - bool /* result */) + content::ServiceWorkerClientInfo /* client */) // Sent via EmbeddedWorker at successful completion of CacheStorage operations. IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_CacheStorageHasSuccess,
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h index 6191a47..8d3dc296 100644 --- a/content/common/service_worker/service_worker_types.h +++ b/content/common/service_worker/service_worker_types.h
@@ -48,6 +48,7 @@ static const int64 kInvalidServiceWorkerResourceId = -1; static const int64 kInvalidServiceWorkerResponseId = -1; static const int kInvalidEmbeddedWorkerThreadId = -1; +static const int kInvalidServiceWorkerClientId = 0; enum FetchRequestMode { FETCH_REQUEST_MODE_SAME_ORIGIN, @@ -204,14 +205,6 @@ int changed_; }; -struct ServiceWorkerClientInfo { - int client_id; - blink::WebPageVisibilityState page_visibility_state; - bool is_focused; - GURL url; - RequestContextFrameType frame_type; -}; - } // namespace content #endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_H_
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc index 6c872d4..3cb20a5 100644 --- a/content/common/swapped_out_messages.cc +++ b/content/common/swapped_out_messages.cc
@@ -24,7 +24,6 @@ case FrameHostMsg_OpenURL::ID: case ViewHostMsg_Focus::ID: // Handled by RenderViewHost. - case ViewHostMsg_RenderProcessGone::ID: case ViewHostMsg_ClosePage_ACK::ID: case ViewHostMsg_SwapCompositorFrame::ID: // Handled by WorkerMessageFilter (or by SharedWorkerMessageFilter when @@ -36,6 +35,7 @@ // Handled by RenderFrameHost. case FrameHostMsg_BeforeUnload_ACK::ID: case FrameHostMsg_SwapOut_ACK::ID: + case FrameHostMsg_RenderProcessGone::ID: // Frame detach must occur after the RenderView has swapped out. case FrameHostMsg_Detach::ID: case FrameHostMsg_DomOperationResponse::ID:
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 968c228e..77c2d73 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -1070,12 +1070,6 @@ // a ViewMsg_CreatingNew_ACK. IPC_MESSAGE_ROUTED0(ViewHostMsg_RenderViewReady) -// Indicates the renderer process is gone. This actually is sent by the -// browser process to itself, but keeps the interface cleaner. -IPC_MESSAGE_ROUTED2(ViewHostMsg_RenderProcessGone, - int, /* this really is base::TerminationStatus */ - int /* exit_code */) - // Sent by the renderer process to request that the browser close the view. // This corresponds to the window.close() API, and the browser may ignore // this message. Otherwise, the browser will generates a ViewMsg_Close
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 071dce7..3451faf0 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -21,6 +21,8 @@ '../ui/accessibility/accessibility.gyp:accessibility', '../ui/accessibility/accessibility.gyp:ax_gen', '../ui/base/ui_base.gyp:ui_base', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', + '../ui/events/events.gyp:events', '../ui/events/events.gyp:events_base', '../ui/events/events.gyp:gesture_detection', '../ui/gfx/gfx.gyp:gfx', @@ -182,6 +184,7 @@ 'public/browser/presentation_service_delegate.h', 'public/browser/profiler_controller.h', 'public/browser/profiler_subscriber.h', + 'public/browser/push_messaging_service.cc', 'public/browser/push_messaging_service.h', 'public/browser/quota_permission_context.h', 'public/browser/readback_types.h', @@ -1219,6 +1222,8 @@ 'browser/service_worker/service_worker_cache_listener.h', 'browser/service_worker/service_worker_cache_quota_client.cc', 'browser/service_worker/service_worker_cache_quota_client.h', + 'browser/service_worker/service_worker_cache_scheduler.cc', + 'browser/service_worker/service_worker_cache_scheduler.h', 'browser/service_worker/service_worker_cache_storage.cc', 'browser/service_worker/service_worker_cache_storage.h', 'browser/service_worker/service_worker_cache_storage_manager.cc', @@ -1628,11 +1633,6 @@ '<@(private_browser_sources)', ], 'conditions': [ - ['toolkit_views==1', { - 'dependencies': [ - '../ui/events/events.gyp:events', - ], - }], ['OS == "win"', { 'dependencies': [ '../third_party/power_gadget/power_gadget.gyp:power_gadget',
diff --git a/content/content_browsertests.isolate b/content/content_browsertests.isolate index 9701675..9de603a 100644 --- a/content/content_browsertests.isolate +++ b/content/content_browsertests.isolate
@@ -86,6 +86,18 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/content_browsertests.dSYM/', + '<(PRODUCT_DIR)/Content Shell.app.dSYM/', + '<(PRODUCT_DIR)/ffmpegsumo.so.dSYM/', + '<(PRODUCT_DIR)/npapi_test_plugin.plugin.dSYM/', + '<(PRODUCT_DIR)/test_netscape_plugin.plugin.dSYM/', + '<(PRODUCT_DIR)/ppapi_tests.plugin.dSYM/', + ], + }, + }], ['OS=="mac" or OS=="win"', { 'variables': { 'command': [
diff --git a/content/content_common.gypi b/content/content_common.gypi index 31f3ea7..6d93515 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -12,6 +12,7 @@ '../third_party/WebKit/public/blink_headers.gyp:blink_headers', '../third_party/icu/icu.gyp:icuuc', '../ui/accessibility/accessibility.gyp:accessibility', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/events/ipc/events_ipc.gyp:events_ipc', '../ui/gfx/gfx.gyp:gfx', @@ -491,6 +492,8 @@ 'common/screen_orientation_messages.h', 'common/send_zygote_child_ping_linux.cc', 'common/service_worker/embedded_worker_messages.h', + 'common/service_worker/service_worker_client_info.cc', + 'common/service_worker/service_worker_client_info.h', 'common/service_worker/service_worker_messages.h', 'common/service_worker/service_worker_status_code.cc', 'common/service_worker/service_worker_status_code.h',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 43ba927..d0d9df6 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi
@@ -369,6 +369,8 @@ 'renderer/scheduler/renderer_scheduler_impl.h', 'renderer/scheduler/renderer_task_queue_selector.cc', 'renderer/scheduler/renderer_task_queue_selector.h', + 'renderer/scheduler/resource_dispatch_throttler.cc', + 'renderer/scheduler/resource_dispatch_throttler.h', 'renderer/scheduler/single_thread_idle_task_runner.cc', 'renderer/scheduler/single_thread_idle_task_runner.h', 'renderer/scheduler/task_queue_manager.cc',
diff --git a/content/content_shell.gypi b/content/content_shell.gypi index bbf3938..cfd93be4 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi
@@ -60,6 +60,7 @@ '../storage/storage_browser.gyp:storage', '../third_party/WebKit/public/blink.gyp:blink', '../third_party/WebKit/public/blink.gyp:blink_test_support', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/events/events.gyp:events_base', '../ui/gfx/gfx.gyp:gfx',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 6cdd46b..f151a21a 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -519,8 +519,9 @@ 'browser/service_worker/embedded_worker_instance_unittest.cc', 'browser/service_worker/embedded_worker_test_helper.cc', 'browser/service_worker/embedded_worker_test_helper.h', - 'browser/service_worker/service_worker_cache_unittest.cc', + 'browser/service_worker/service_worker_cache_scheduler_unittest.cc', 'browser/service_worker/service_worker_cache_storage_manager_unittest.cc', + 'browser/service_worker/service_worker_cache_unittest.cc', 'browser/service_worker/service_worker_context_unittest.cc', 'browser/service_worker/service_worker_controllee_request_handler_unittest.cc', 'browser/service_worker/service_worker_context_request_handler_unittest.cc', @@ -652,6 +653,7 @@ 'renderer/render_widget_unittest.cc', 'renderer/scheduler/renderer_scheduler_impl_unittest.cc', 'renderer/scheduler/renderer_task_queue_selector_unittest.cc', + 'renderer/scheduler/resource_dispatch_throttler_unittest.cc', 'renderer/scheduler/task_queue_manager_unittest.cc', 'renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc', 'renderer/skia_benchmarking_extension_unittest.cc', @@ -757,6 +759,7 @@ 'test_support_content', '../skia/skia.gyp:skia', '../ui/accessibility/accessibility.gyp:ax_gen', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../v8/tools/gyp/v8.gyp:v8', ], 'include_dirs': [ @@ -780,6 +783,7 @@ '../testing/gtest.gyp:gtest', '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', '../ui/accessibility/accessibility.gyp:ax_gen', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', '../ui/base/ui_base.gyp:ui_base_test_support', '../ui/events/events.gyp:dom4_keycode_converter', @@ -1254,6 +1258,7 @@ '../skia/skia.gyp:skia', '../testing/gtest.gyp:gtest', '../ui/accessibility/accessibility.gyp:ax_gen', + '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', ], 'sources': [ # Source list duplicated in GN build.
diff --git a/content/content_unittests.isolate b/content/content_unittests.isolate index b72dcee..ba15585 100644 --- a/content/content_unittests.isolate +++ b/content/content_unittests.isolate
@@ -97,6 +97,13 @@ ], }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/content_unittests.dSYM/', + ], + }, + }], ['OS=="win" and (fastbuild==0 or fastbuild==1)', { 'variables': { 'files': [
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index a6728e04..aeacd36 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -521,6 +521,13 @@ // content. sandbox::TargetServices* target_services = sandbox_info->target_services; if (target_services) { +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + if (!LoadLibraryA("dbghelp.dll")) + return false; +#endif + target_services->LowerToken(); return true; }
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 103a7b8..8b612fb 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -357,6 +357,12 @@ WarmupWindowsLocales(permissions); +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + LoadLibraryA("dbghelp.dll"); +#endif + g_target_services->LowerToken(); } #endif
diff --git a/content/public/android/OWNERS b/content/public/android/OWNERS index 1f0649b1..7702ef7 100644 --- a/content/public/android/OWNERS +++ b/content/public/android/OWNERS
@@ -1,4 +1,5 @@ benm@chromium.org +dtrainor@chromium.org tedchoc@chromium.org yfriedman@chromium.org
diff --git a/content/public/android/java/res/OWNERS b/content/public/android/java/res/OWNERS new file mode 100644 index 0000000..7b0bde5 --- /dev/null +++ b/content/public/android/java/res/OWNERS
@@ -0,0 +1,7 @@ +set noparent +tedchoc@chromium.org +aurimas@chromium.org +newt@chromium.org +dtrainor@chromium.org +yusufo@chromium.org +dfalcantara@chromium.org
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java index 25efa3ce..2020994 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
@@ -415,6 +415,7 @@ @Override public void dropOomBindings() { synchronized (mLock) { + assert !mAlwaysInForeground; mInitialBinding.unbind(); mStrongBindingCount = 0;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java index 4bac354..950ea3b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
@@ -123,6 +123,13 @@ } /** + * Gets the SurfaceView for this ContentViewRenderView + */ + public SurfaceView getSurfaceView() { + return mSurfaceView; + } + + /** * Should be called when the ContentViewRenderView is not needed anymore so its associated * native resource can be freed. */
diff --git a/content/public/browser/android/content_protocol_handler.h b/content/public/browser/android/content_protocol_handler.h index 404ecb9..be9473e 100644 --- a/content/public/browser/android/content_protocol_handler.h +++ b/content/public/browser/android/content_protocol_handler.h
@@ -24,7 +24,7 @@ const scoped_refptr<base::TaskRunner>& content_task_runner); protected: - virtual ~ContentProtocolHandler() {} + ~ContentProtocolHandler() override {} }; } // namespace content
diff --git a/content/public/browser/browser_plugin_guest_delegate.cc b/content/public/browser/browser_plugin_guest_delegate.cc index 5dc31a1b..fd7dec4 100644 --- a/content/public/browser/browser_plugin_guest_delegate.cc +++ b/content/public/browser/browser_plugin_guest_delegate.cc
@@ -26,4 +26,8 @@ return false; } +bool BrowserPluginGuestDelegate::StopFinding(StopFindAction action) { + return false; +} + } // namespace content
diff --git a/content/public/browser/browser_plugin_guest_delegate.h b/content/public/browser/browser_plugin_guest_delegate.h index 5e5d1fe..31250d6 100644 --- a/content/public/browser/browser_plugin_guest_delegate.h +++ b/content/public/browser/browser_plugin_guest_delegate.h
@@ -80,6 +80,7 @@ virtual bool Find(int request_id, const base::string16& search_text, const blink::WebFindOptions& options); + virtual bool StopFinding(StopFindAction action); // Provides the delegate with an interface with which to size the guest. virtual void SetGuestSizer(GuestSizer* guest_sizer) {}
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 8f3d06c..acacd98 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -342,6 +342,11 @@ return nullptr; } +WebContents* ContentBrowserClient::OpenURL(BrowserContext* browser_context, + const OpenURLParams& params) { + return nullptr; +} + #if defined(OS_WIN) const wchar_t* ContentBrowserClient::GetResourceDllName() { return nullptr;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index d2ae7a0..5e5d5d42 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -108,6 +108,7 @@ class WebContents; class WebContentsViewDelegate; struct MainFunctionParams; +struct OpenURLParams; struct Referrer; struct WebPreferences; @@ -614,6 +615,11 @@ virtual PresentationServiceDelegate* GetPresentationServiceDelegate( WebContents* web_contents); + // Allows programmatic opening of a new tab/window without going through + // another WebContents. For example, from a Worker. + virtual WebContents* OpenURL(BrowserContext* browser_context, + const OpenURLParams& params); + #if defined(OS_POSIX) && !defined(OS_MACOSX) // Populates |mappings| with all files that need to be mapped before launching // a child process.
diff --git a/content/public/browser/platform_notification_service.h b/content/public/browser/platform_notification_service.h index 6cf800bc..bbe407c 100644 --- a/content/public/browser/platform_notification_service.h +++ b/content/public/browser/platform_notification_service.h
@@ -10,7 +10,7 @@ #include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" -#include "third_party/WebKit/public/platform/WebNotificationPermission.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h" class GURL; class SkBitmap;
diff --git a/content/public/browser/push_messaging_service.cc b/content/public/browser/push_messaging_service.cc new file mode 100644 index 0000000..154b02d2 --- /dev/null +++ b/content/public/browser/push_messaging_service.cc
@@ -0,0 +1,95 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/push_messaging_service.h" + +#include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/public/browser/browser_thread.h" + +namespace { + +const char kNotificationsShownServiceWorkerKey[] = + "notifications_shown_by_last_few_pushes"; + +} // namespace + +namespace content { + +static void CallGetNotificationsShownCallbackFromIO( + const PushMessagingService::GetNotificationsShownCallback& callback, + const std::string& data, + ServiceWorkerStatusCode service_worker_status) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + bool success = service_worker_status == SERVICE_WORKER_OK; + bool not_found = service_worker_status == SERVICE_WORKER_ERROR_NOT_FOUND; + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, data, success, not_found)); +} + +static void CallResultCallbackFromIO( + const ServiceWorkerContext::ResultCallback& callback, + ServiceWorkerStatusCode service_worker_status) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + bool success = service_worker_status == SERVICE_WORKER_OK; + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, success)); +} + +static void GetNotificationsShownOnIO( + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_wrapper, + int64 service_worker_registration_id, + const PushMessagingService::GetNotificationsShownCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + service_worker_context_wrapper->context()->storage()->GetUserData( + service_worker_registration_id, kNotificationsShownServiceWorkerKey, + base::Bind(&CallGetNotificationsShownCallbackFromIO, callback)); +} + +static void SetNotificationsShownOnIO( + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_wrapper, + int64 service_worker_registration_id, const GURL& origin, + const std::string& data, + const PushMessagingService::ResultCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + service_worker_context_wrapper->context()->storage()->StoreUserData( + service_worker_registration_id, origin, + kNotificationsShownServiceWorkerKey, data, + base::Bind(&CallResultCallbackFromIO, callback)); +} + +// static +void PushMessagingService::GetNotificationsShownByLastFewPushes( + ServiceWorkerContext* service_worker_context, + int64 service_worker_registration_id, + const GetNotificationsShownCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + scoped_refptr<ServiceWorkerContextWrapper> wrapper = + static_cast<ServiceWorkerContextWrapper*>(service_worker_context); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&GetNotificationsShownOnIO, + wrapper, + service_worker_registration_id, + callback)); +} + +// static +void PushMessagingService::SetNotificationsShownByLastFewPushes( + ServiceWorkerContext* service_worker_context, + int64 service_worker_registration_id, + const GURL& origin, + const std::string& notifications_shown, + const ResultCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + scoped_refptr<ServiceWorkerContextWrapper> wrapper = + static_cast<ServiceWorkerContextWrapper*>(service_worker_context); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&SetNotificationsShownOnIO, + wrapper, + service_worker_registration_id, + origin, + notifications_shown, + callback)); +} + +} // namespace content
diff --git a/content/public/browser/push_messaging_service.h b/content/public/browser/push_messaging_service.h index 885cbc1..44daa7c 100644 --- a/content/public/browser/push_messaging_service.h +++ b/content/public/browser/push_messaging_service.h
@@ -10,20 +10,43 @@ #include "base/callback.h" #include "content/common/content_export.h" #include "content/public/common/push_messaging_status.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" #include "url/gurl.h" namespace content { +class ServiceWorkerContext; + // A push service-agnostic interface that the Push API uses for talking to // push messaging services like GCM. Must only be used on the UI thread. class CONTENT_EXPORT PushMessagingService { public: + using GetNotificationsShownCallback = + base::Callback<void(const std::string& notifications_shown, + bool success, bool not_found)>; + + using ResultCallback = base::Callback<void(bool success)>; + using RegisterCallback = base::Callback<void(const std::string& /* registration_id */, PushRegistrationStatus /* status */)>; using UnregisterCallback = base::Callback<void(PushUnregistrationStatus)>; + // Provide a storage mechanism to read/write an opaque + // "notifications_shown_by_last_few_pushes" string associated with a Service + // Worker registration. Stored data is deleted when the associated + // registration is deleted. + static void GetNotificationsShownByLastFewPushes( + ServiceWorkerContext* service_worker_context, + int64 service_worker_registration_id, + const GetNotificationsShownCallback& callback); + static void SetNotificationsShownByLastFewPushes( + ServiceWorkerContext* service_worker_context, + int64 service_worker_registration_id, + const GURL& origin, + const std::string& notifications_shown, + const ResultCallback& callback); + virtual ~PushMessagingService() {} // Returns the absolute URL exposed by the push server where the webapp server
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index a0d609b..b6ca302 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -94,6 +94,15 @@ // result. virtual void ActivateFindInPageResultForAccessibility(int request_id) = 0; + // Roundtrips through the renderer and compositor pipeline to ensure that any + // changes to the contents resulting from operations executed prior to this + // call are visible on screen. The call completes asynchronously by running + // the supplied |callback| with a value of true upon successful completion and + // false otherwise (when the frame is destroyed, detached, etc..). + typedef base::Callback<void(bool)> FlushVisualStateResultCallback; + virtual void FlushVisualState( + const FlushVisualStateResultCallback& callback) = 0; + // Temporary until we get rid of RenderViewHost. virtual RenderViewHost* GetRenderViewHost() = 0;
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index b74e38f..19bb6af 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -30,6 +30,7 @@ namespace media { class AudioOutputController; +class BrowserCdm; } namespace content { @@ -185,9 +186,7 @@ virtual void AddPendingView() = 0; virtual void RemovePendingView() = 0; - // Sets a flag indicating that the process can be abnormally terminated. - virtual void SetSuddenTerminationAllowed(bool allowed) = 0; - // Returns true if the process can be abnormally terminated. + // Returns true if the process can be immediately terminated. virtual bool SuddenTerminationAllowed() const = 0; // Returns how long the child has been idle. The definition of idle @@ -271,6 +270,13 @@ virtual void GetAudioOutputControllers( const GetAudioOutputControllersCallback& callback) const = 0; +#if defined(ENABLE_BROWSER_CDMS) + // Returns the ::media::BrowserCdm instance associated with |render_frame_id| + // and |cdm_id|, or nullptr if not found. + virtual media::BrowserCdm* GetBrowserCdm(int render_frame_id, + int cdm_id) const = 0; +#endif + // Static management functions ----------------------------------------------- // Flag to run the renderer in process. This is primarily
diff --git a/content/public/browser/service_worker_context.h b/content/public/browser/service_worker_context.h index 22c989b..a28662bb 100644 --- a/content/public/browser/service_worker_context.h +++ b/content/public/browser/service_worker_context.h
@@ -32,6 +32,9 @@ typedef base::Callback<void(const std::vector<ServiceWorkerUsageInfo>& usage_info)> GetUsageInfoCallback; + typedef base::Callback<void(bool has_service_worker)> + CheckHasServiceWorkerCallback; + // Registers the header name which should not be passed to the ServiceWorker. // Must be called from the IO thread. CONTENT_EXPORT static void AddExcludedHeadersForFetchEvent( @@ -73,7 +76,7 @@ // TODO(jyasskin): Provide a way to SendMessage to a Scope. - // Determines if a request for 'url' can be satisfied while offline. + // Determines if a request for |url| can be satisfied while offline. // This method always completes asynchronously. virtual void CanHandleMainResourceOffline(const GURL& url, const GURL& first_party, @@ -84,6 +87,17 @@ virtual void GetAllOriginsInfo(const GetUsageInfoCallback& callback) = 0; virtual void DeleteForOrigin(const GURL& origin_url) = 0; + // Returns true if an active Service Worker registration exists that matches + // |url|, and if |other_url| falls inside the scope of the same registration. + // Note this still returns true even if there is a Service Worker registration + // which has a longer match for |other_url|. + // This function can be called from any thread, but the callback will always + // be called on the UI thread. + virtual void CheckHasServiceWorker( + const GURL& url, + const GURL& other_url, + const CheckHasServiceWorkerCallback& callback) = 0; + protected: ServiceWorkerContext() {} virtual ~ServiceWorkerContext() {}
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 4f59c26..e516d8c 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -44,8 +44,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(net::RequestPriority, net::MAXIMUM_PRIORITY) IPC_ENUM_TRAITS_MAX_VALUE(content::V8CacheOptions, content::V8_CACHE_OPTIONS_LAST) -IPC_ENUM_TRAITS_MAX_VALUE(content::V8ScriptStreamingMode, - content::V8_SCRIPT_STREAMING_MODE_LAST) IPC_ENUM_TRAITS_MIN_MAX_VALUE(ui::PointerType, ui::POINTER_TYPE_FIRST, ui::POINTER_TYPE_LAST) @@ -194,8 +192,6 @@ IPC_STRUCT_TRAITS_MEMBER(navigate_on_drag_drop) IPC_STRUCT_TRAITS_MEMBER(spatial_navigation_enabled) IPC_STRUCT_TRAITS_MEMBER(v8_cache_options) - IPC_STRUCT_TRAITS_MEMBER(v8_script_streaming_enabled) - IPC_STRUCT_TRAITS_MEMBER(v8_script_streaming_mode) IPC_STRUCT_TRAITS_MEMBER(slimming_paint_enabled) IPC_STRUCT_TRAITS_MEMBER(pepper_accelerated_video_decode_enabled) #if defined(OS_ANDROID)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 85083ae..2b9cf85 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -84,6 +84,12 @@ // users with many windows/tabs and lots of memory. const char kDisableBackingStoreLimit[] = "disable-backing-store-limit"; +// Disable one or more Blink runtime-enabled features. +// Use names from RuntimeEnabledFeatures.in, separated by commas. +// Applied after kEnableBlinkFeatures, and after other flags that change these +// features. +const char kDisableBlinkFeatures[] = "disable-blink-features"; + // Disable the Blink Scheduler. Ensures there's no reordering of blink tasks. // This switch is intended only for performance tests. const char kDisableBlinkScheduler[] = "disable-blink-scheduler"; @@ -285,6 +291,12 @@ const char kEnablePreferCompositingToLCDText[] = "enable-prefer-compositing-to-lcd-text"; +// Disable one or more Blink runtime-enabled features. +// Use names from RuntimeEnabledFeatures.in, separated by commas. +// Applied before kDisableBlinkFeatures, and after other flags that change these +// features. +const char kEnableBlinkFeatures[] = "enable-blink-features"; + // PlzNavigate: Use the experimental browser-side navigation path. const char kEnableBrowserSideNavigation[] = "enable-browser-side-navigation"; @@ -345,6 +357,9 @@ // Enables the memory benchmarking extension const char kEnableMemoryBenchmarking[] = "enable-memory-benchmarking"; +// Prefer the namespace sandbox over the setuid sandbox when possible. +const char kEnableNamespaceSandbox[] = "enable-namespace-sandbox"; + // Enables the network information API. const char kEnableNetworkInformation[] = "enable-network-information"; @@ -439,9 +454,6 @@ const char kEnableUserMediaScreenCapturing[] = "enable-usermedia-screen-capturing"; -// Enables streaming scripts to V8 while loading. -const char kEnableV8ScriptStreaming[] = "enable-v8-script-streaming"; - // Enables the use of the @viewport CSS rule, which allows // pages to control aspects of their own layout. This also turns on touch-screen // pinch gestures.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index fd66188..a2dabe8 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -19,7 +19,7 @@ CONTENT_EXPORT extern const char kAllowInsecureWebSocketFromHttpsOrigin[]; CONTENT_EXPORT extern const char kAllowLoopbackInPeerConnection[]; CONTENT_EXPORT extern const char kAllowNoSandboxJob[]; -extern const char kAllowSandboxDebugging[]; +CONTENT_EXPORT extern const char kAllowSandboxDebugging[]; extern const char kAuditAllHandles[]; extern const char kAuditHandles[]; CONTENT_EXPORT extern const char kBlinkPlatformLogChannels[]; @@ -31,6 +31,7 @@ CONTENT_EXPORT extern const char kDefaultTileHeight[]; CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[]; CONTENT_EXPORT extern const char kDisable3DAPIs[]; +CONTENT_EXPORT extern const char kDisableBlinkFeatures[]; CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[]; CONTENT_EXPORT extern const char kDisableAcceleratedJpegDecoding[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; @@ -90,6 +91,7 @@ CONTENT_EXPORT extern const char kEnableCredentialManagerAPI[]; CONTENT_EXPORT extern const char kEnableBeginFrameScheduling[]; CONTENT_EXPORT extern const char kEnablePreferCompositingToLCDText[]; +CONTENT_EXPORT extern const char kEnableBlinkFeatures[]; CONTENT_EXPORT extern const char kEnableBrowserSideNavigation[]; CONTENT_EXPORT extern const char kEnableDeferredImageDecoding[]; CONTENT_EXPORT extern const char kEnableDelayAgnosticAec[]; @@ -108,6 +110,7 @@ CONTENT_EXPORT extern const char kEnableLCDText[]; CONTENT_EXPORT extern const char kEnableLogging[]; extern const char kEnableMemoryBenchmarking[]; +CONTENT_EXPORT extern const char kEnableNamespaceSandbox[]; CONTENT_EXPORT extern const char kEnableNetworkInformation[]; CONTENT_EXPORT extern const char kEnableOneCopy[]; CONTENT_EXPORT extern const char kEnableOverlayFullscreenVideo[]; @@ -131,7 +134,6 @@ CONTENT_EXPORT extern const char kEnableTracing[]; CONTENT_EXPORT extern const char kEnableTracingOutput[]; CONTENT_EXPORT extern const char kEnableUserMediaScreenCapturing[]; -extern const char kEnableV8ScriptStreaming[]; CONTENT_EXPORT extern const char kEnableViewport[]; CONTENT_EXPORT extern const char kEnableViewportMeta[]; CONTENT_EXPORT extern const char kMainFrameResizesAreOrientationChanges[];
diff --git a/content/public/common/sandbox_linux.h b/content/public/common/sandbox_linux.h index c29c9f1..acee403 100644 --- a/content/public/common/sandbox_linux.h +++ b/content/public/common/sandbox_linux.h
@@ -14,10 +14,10 @@ // SUID sandbox active. kSandboxLinuxSUID = 1 << 0, - // SUID sandbox is using the PID namespace. + // Sandbox is using a new PID namespace. kSandboxLinuxPIDNS = 1 << 1, - // SUID sandbox is using the network namespace. + // Sandbox is using a new network namespace. kSandboxLinuxNetNS = 1 << 2, // seccomp-bpf sandbox active. @@ -29,6 +29,9 @@ // seccomp-bpf sandbox is active and the kernel supports TSYNC. kSandboxLinuxSeccompTSYNC = 1 << 5, + // User namespace sandbox active. + kSandboxLinuxUserNS = 1 << 6, + // A flag that denotes an invalid sandbox status. kSandboxLinuxInvalid = 1 << 31, };
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index 5563c00..93a10b3 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -59,18 +59,6 @@ STATIC_ASSERT_MATCHING_ENUMS(V8_CACHE_OPTIONS_LAST, WebSettings::V8CacheOptionsRecentSmall); -STATIC_ASSERT_MATCHING_ENUMS(V8_SCRIPT_STREAMING_MODE_ALL, - WebSettings::V8ScriptStreamingModeAll); -STATIC_ASSERT_MATCHING_ENUMS( - V8_SCRIPT_STREAMING_MODE_ONLY_ASYNC_AND_DEFER, - WebSettings::V8ScriptStreamingModeOnlyAsyncAndDefer); -STATIC_ASSERT_MATCHING_ENUMS( - V8_SCRIPT_STREAMING_MODE_ALL_PLUS_BLOCK_PARSER_BLOCKING, - WebSettings::V8ScriptStreamingModeAllPlusBlockParsingBlocking); -STATIC_ASSERT_MATCHING_ENUMS( - V8_SCRIPT_STREAMING_MODE_LAST, - WebSettings::V8ScriptStreamingModeAllPlusBlockParsingBlocking); - STATIC_ASSERT_MATCHING_ENUMS(ui::POINTER_TYPE_NONE, WebSettings::PointerTypeNone); STATIC_ASSERT_MATCHING_ENUMS(ui::POINTER_TYPE_COARSE, @@ -191,8 +179,6 @@ use_solid_color_scrollbars(false), navigate_on_drag_drop(true), v8_cache_options(V8_CACHE_OPTIONS_DEFAULT), - v8_script_streaming_enabled(false), - v8_script_streaming_mode(V8_SCRIPT_STREAMING_MODE_ALL), slimming_paint_enabled(false), cookie_enabled(true), pepper_accelerated_video_decode_enabled(false),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index ab43cd9..2b4eff3b 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -50,14 +50,6 @@ V8_CACHE_OPTIONS_LAST = V8_CACHE_OPTIONS_RECENT_SMALL }; -enum V8ScriptStreamingMode { - V8_SCRIPT_STREAMING_MODE_ALL, - V8_SCRIPT_STREAMING_MODE_ONLY_ASYNC_AND_DEFER, - V8_SCRIPT_STREAMING_MODE_ALL_PLUS_BLOCK_PARSER_BLOCKING, - V8_SCRIPT_STREAMING_MODE_LAST = - V8_SCRIPT_STREAMING_MODE_ALL_PLUS_BLOCK_PARSER_BLOCKING -}; - // The ISO 15924 script code for undetermined script aka Common. It's the // default used on WebKit's side to get/set a font setting when no script is // specified. @@ -180,8 +172,6 @@ bool use_solid_color_scrollbars; bool navigate_on_drag_drop; V8CacheOptions v8_cache_options; - bool v8_script_streaming_enabled; - V8ScriptStreamingMode v8_script_streaming_mode; bool slimming_paint_enabled; // This flags corresponds to a Page's Settings' setCookieEnabled state. It
diff --git a/content/public/renderer/plugin_instance_throttler.h b/content/public/renderer/plugin_instance_throttler.h index 5fa32767..376e6ab 100644 --- a/content/public/renderer/plugin_instance_throttler.h +++ b/content/public/renderer/plugin_instance_throttler.h
@@ -10,6 +10,7 @@ #include "content/common/content_export.h" class GURL; +class SkBitmap; namespace content { @@ -61,7 +62,15 @@ class Observer { public: - virtual void OnThrottleStateChange() = 0; + // Guaranteed to be called before the throttle is engaged. + virtual void OnKeyframeExtracted(const SkBitmap* bitmap) {} + + virtual void OnThrottleStateChange() {} + + // Called when the plugin should be hidden due to a placeholder. + virtual void OnHiddenForPlaceholder(bool hidden) {} + + virtual void OnThrottlerDestroyed() {} }; // Returns a nullptr if no throttler needed based on |power_saver_mode|. @@ -78,10 +87,14 @@ virtual void RemoveObserver(Observer* observer) = 0; virtual bool IsThrottled() const = 0; + virtual bool IsHiddenForPlaceholder() const = 0; // Marks the plugin as essential. Unthrottles the plugin if already throttled. virtual void MarkPluginEssential(PowerSaverUnthrottleMethod method) = 0; + // Called by the placeholder when the plugin should temporarily be hidden. + virtual void SetHiddenForPlaceholder(bool hidden) = 0; + protected: PluginInstanceThrottler() {}
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 20d6f6c9..5de8137 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -10,6 +10,7 @@ #include "base/process/kill.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_timeouts.h" @@ -240,9 +241,8 @@ return scoped_ptr<net::test_server::HttpResponse>(); // Replace the host of the URL with the one passed in the URL. - std::string host = params.substr(0, slash); GURL::Replacements replace_host; - replace_host.SetHostStr(host); + replace_host.SetHostStr(base::StringPiece(params).substr(0, slash)); GURL redirect_server = server_base_url.ReplaceComponents(replace_host); // Append the real part of the path to the new URL.
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index b0514a4..21f3140 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -172,9 +172,6 @@ void MockRenderProcessHost::RemovePendingView() { } -void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) { -} - bool MockRenderProcessHost::SuddenTerminationAllowed() const { return true; } @@ -248,6 +245,13 @@ unsigned int target, const gpu::ValueState& state) { } +#if defined(ENABLE_BROWSER_CDMS) +media::BrowserCdm* MockRenderProcessHost::GetBrowserCdm(int render_frame_id, + int cdm_id) const { + return nullptr; +} +#endif + void MockRenderProcessHost::FilterURL(bool empty_allowed, GURL* url) { RenderProcessHostImpl::FilterURL(this, empty_allowed, url); }
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 3286259..fe43817f 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -59,7 +59,6 @@ void Cleanup() override; void AddPendingView() override; void RemovePendingView() override; - void SetSuddenTerminationAllowed(bool allowed) override; bool SuddenTerminationAllowed() const override; BrowserContext* GetBrowserContext() const override; bool InSameStoragePartition(StoragePartition* partition) const override; @@ -88,6 +87,10 @@ void OnRemoveSubscription(unsigned int target) override; void SendUpdateValueState( unsigned int target, const gpu::ValueState& state) override; +#if defined(ENABLE_BROWSER_CDMS) + media::BrowserCdm* GetBrowserCdm(int render_frame_id, + int cdm_id) const override; +#endif // IPC::Sender via RenderProcessHost. bool Send(IPC::Message* msg) override;
diff --git a/content/public/test/nested_message_pump_android.h b/content/public/test/nested_message_pump_android.h index 4b7aebac..1f6eb0f 100644 --- a/content/public/test/nested_message_pump_android.h +++ b/content/public/test/nested_message_pump_android.h
@@ -17,17 +17,16 @@ public: NestedMessagePumpAndroid(); - virtual void Run(Delegate* delegate) override; - virtual void Quit() override; - virtual void ScheduleWork() override; - virtual void ScheduleDelayedWork( - const base::TimeTicks& delayed_work_time) override; - virtual void Start(Delegate* delegate) override; + void Run(Delegate* delegate) override; + void Quit() override; + void ScheduleWork() override; + void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) override; + void Start(Delegate* delegate) override; static bool RegisterJni(JNIEnv* env); protected: - virtual ~NestedMessagePumpAndroid(); + ~NestedMessagePumpAndroid() override; private: // We may make recursive calls to Run, so we save state that needs to be
diff --git a/content/renderer/android/address_detector.h b/content/renderer/android/address_detector.h index e612339..1db869e 100644 --- a/content/renderer/android/address_detector.h +++ b/content/renderer/android/address_detector.h
@@ -15,17 +15,17 @@ class AddressDetector : public ContentDetector { public: AddressDetector(); - virtual ~AddressDetector(); + ~AddressDetector() override; private: // Implementation of ContentDetector. - virtual bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - virtual GURL GetIntentURL(const std::string& content_text) override; - virtual size_t GetMaximumContentLength() override; + bool FindContent(const base::string16::const_iterator& begin, + const base::string16::const_iterator& end, + size_t* start_pos, + size_t* end_pos, + std::string* content_text) override; + GURL GetIntentURL(const std::string& content_text) override; + size_t GetMaximumContentLength() override; std::string GetContentText(const base::string16& text);
diff --git a/content/renderer/android/email_detector.h b/content/renderer/android/email_detector.h index 97b35c7..8d108492 100644 --- a/content/renderer/android/email_detector.h +++ b/content/renderer/android/email_detector.h
@@ -23,13 +23,13 @@ friend class EmailDetectorTest; // Implementation of ContentDetector. - virtual bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - virtual GURL GetIntentURL(const std::string& content_text) override; - virtual size_t GetMaximumContentLength() override; + bool FindContent(const base::string16::const_iterator& begin, + const base::string16::const_iterator& end, + size_t* start_pos, + size_t* end_pos, + std::string* content_text) override; + GURL GetIntentURL(const std::string& content_text) override; + size_t GetMaximumContentLength() override; DISALLOW_COPY_AND_ASSIGN(EmailDetector); };
diff --git a/content/renderer/android/phone_number_detector.h b/content/renderer/android/phone_number_detector.h index 3741315..6503eee 100644 --- a/content/renderer/android/phone_number_detector.h +++ b/content/renderer/android/phone_number_detector.h
@@ -18,19 +18,19 @@ public: PhoneNumberDetector(); explicit PhoneNumberDetector(const std::string& region); - virtual ~PhoneNumberDetector(); + ~PhoneNumberDetector() override; private: friend class PhoneNumberDetectorTest; // Implementation of ContentDetector. - virtual bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - virtual GURL GetIntentURL(const std::string& content_text) override; - virtual size_t GetMaximumContentLength() override; + bool FindContent(const base::string16::const_iterator& begin, + const base::string16::const_iterator& end, + size_t* start_pos, + size_t* end_pos, + std::string* content_text) override; + GURL GetIntentURL(const std::string& content_text) override; + size_t GetMaximumContentLength() override; const std::string region_code_;
diff --git a/content/renderer/android/renderer_date_time_picker.h b/content/renderer/android/renderer_date_time_picker.h index 481d288c..970f93b 100644 --- a/content/renderer/android/renderer_date_time_picker.h +++ b/content/renderer/android/renderer_date_time_picker.h
@@ -24,7 +24,7 @@ RenderViewImpl* sender, const blink::WebDateTimeChooserParams& params, blink::WebDateTimeChooserCompletion* completion); - virtual ~RendererDateTimePicker(); + ~RendererDateTimePicker() override; bool Open(); @@ -33,7 +33,7 @@ void OnCancel(); // RenderViewObserver - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; blink::WebDateTimeChooserParams chooser_params_; blink::WebDateTimeChooserCompletion* chooser_completion_; // Not owned by us
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index a4e8627..77df05f 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -41,6 +41,7 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebWidget.h" #include "ui/gfx/frame_time.h" +#include "ui/gfx/hud_font.h" #include "ui/gl/gl_switches.h" #include "ui/native_theme/native_theme_switches.h" @@ -433,6 +434,8 @@ compositor_deps_->CreateExternalBeginFrameSource(widget_->routing_id()); } + settings.hud_typeface = ui::GetHudTypeface(); + if (compositor_thread_task_runner.get()) { layer_tree_host_ = cc::LayerTreeHost::CreateThreaded( this, shared_bitmap_manager, gpu_memory_buffer_manager, settings, @@ -750,7 +753,11 @@ } void RenderWidgetCompositor::setTopControlsContentOffset(float offset) { - layer_tree_host_->SetTopControlsContentOffset(offset); + setTopControlsShownRatio(offset); +} + +void RenderWidgetCompositor::setTopControlsShownRatio(float ratio) { + layer_tree_host_->SetTopControlsShownRatio(ratio); } void RenderWidgetCompositor::WillBeginMainFrame() { @@ -781,8 +788,8 @@ } void RenderWidgetCompositor::ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) {
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 117cffaa..25d9f53 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -129,6 +129,9 @@ virtual void setShowDebugBorders(bool show); virtual void setContinuousPaintingEnabled(bool enabled); virtual void setShowScrollBottleneckRects(bool show); + virtual void setTopControlsShownRatio(float); + + // TODO(aelias): Delete after Blink roll virtual void setTopControlsContentOffset(float); // cc::LayerTreeHostClient implementation. @@ -136,8 +139,8 @@ void DidBeginMainFrame() override; void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override; - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override;
diff --git a/content/renderer/gpu/stream_texture_host_android.h b/content/renderer/gpu/stream_texture_host_android.h index 4bd8413..871cb63 100644 --- a/content/renderer/gpu/stream_texture_host_android.h +++ b/content/renderer/gpu/stream_texture_host_android.h
@@ -24,7 +24,7 @@ class StreamTextureHost : public IPC::Listener { public: explicit StreamTextureHost(GpuChannelHost* channel); - virtual ~StreamTextureHost(); + ~StreamTextureHost() override; // Listener class that is listening to the stream texture updates. It is // implemented by StreamTextureProxyImpl. @@ -38,8 +38,8 @@ bool BindToCurrentThread(int32 stream_id, Listener* listener); // IPC::Channel::Listener implementation: - virtual bool OnMessageReceived(const IPC::Message& message) override; - virtual void OnChannelError() override; + bool OnMessageReceived(const IPC::Message& message) override; + void OnChannelError() override; private: // Message handlers:
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc index 7f5c6925..b4e47a4 100644 --- a/content/renderer/input/input_handler_proxy.cc +++ b/content/renderer/input/input_handler_proxy.cc
@@ -558,9 +558,11 @@ for (size_t i = 0; i < touch_event.touchesLength; ++i) { if (touch_event.touches[i].state != WebTouchPoint::StatePressed) continue; - if (input_handler_->HaveTouchEventHandlersAt( + if (input_handler_->DoTouchEventsBlockScrollAt( gfx::Point(touch_event.touches[i].position.x, touch_event.touches[i].position.y))) { + // TODO(rbyers): We should consider still sending the touch events to + // main asynchronously (crbug.com/455539). return DID_NOT_HANDLE; } }
diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc index afb7c51..0a85206 100644 --- a/content/renderer/input/input_handler_proxy_unittest.cc +++ b/content/renderer/input/input_handler_proxy_unittest.cc
@@ -117,7 +117,7 @@ cc::InputHandler::ScrollInputType type)); MOCK_METHOD1(HaveWheelEventHandlersAt, bool(const gfx::Point& point)); - MOCK_METHOD1(HaveTouchEventHandlersAt, bool(const gfx::Point& point)); + MOCK_METHOD1(DoTouchEventsBlockScrollAt, bool(const gfx::Point& point)); virtual void SetRootLayerScrollOffsetDelegate( cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) @@ -1501,11 +1501,11 @@ VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, - HaveTouchEventHandlersAt( + DoTouchEventsBlockScrollAt( testing::Property(&gfx::Point::x, testing::Gt(0)))) .WillOnce(testing::Return(false)); EXPECT_CALL(mock_input_handler_, - HaveTouchEventHandlersAt( + DoTouchEventsBlockScrollAt( testing::Property(&gfx::Point::x, testing::Lt(0)))) .WillOnce(testing::Return(false)); @@ -1526,11 +1526,11 @@ VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, - HaveTouchEventHandlersAt( + DoTouchEventsBlockScrollAt( testing::Property(&gfx::Point::x, testing::Eq(0)))) .WillOnce(testing::Return(false)); EXPECT_CALL(mock_input_handler_, - HaveTouchEventHandlersAt( + DoTouchEventsBlockScrollAt( testing::Property(&gfx::Point::x, testing::Gt(0)))) .WillOnce(testing::Return(true)); // Since the second touch point hits a touch-region, there should be no
diff --git a/content/renderer/java/gin_java_bridge_dispatcher.h b/content/renderer/java/gin_java_bridge_dispatcher.h index f9d5f54..591d153a 100644 --- a/content/renderer/java/gin_java_bridge_dispatcher.h +++ b/content/renderer/java/gin_java_bridge_dispatcher.h
@@ -41,11 +41,11 @@ typedef ObjectMap::KeyType ObjectID; explicit GinJavaBridgeDispatcher(RenderFrame* render_frame); - virtual ~GinJavaBridgeDispatcher(); + ~GinJavaBridgeDispatcher() override; // RenderFrameObserver override: - virtual bool OnMessageReceived(const IPC::Message& message) override; - virtual void DidClearWindowObject() override; + bool OnMessageReceived(const IPC::Message& message) override; + void DidClearWindowObject() override; void GetJavaMethods(ObjectID object_id, std::set<std::string>* methods); bool HasJavaMethod(ObjectID object_id, const std::string& method_name);
diff --git a/content/renderer/java/gin_java_bridge_object.h b/content/renderer/java/gin_java_bridge_object.h index f3a4c7b..5c729b8 100644 --- a/content/renderer/java/gin_java_bridge_object.h +++ b/content/renderer/java/gin_java_bridge_object.h
@@ -31,13 +31,13 @@ GinJavaBridgeDispatcher::ObjectID object_id() const { return object_id_; } // gin::Wrappable. - virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate) override; // gin::NamedPropertyInterceptor - virtual v8::Local<v8::Value> GetNamedProperty( - v8::Isolate* isolate, const std::string& property) override; - virtual std::vector<std::string> EnumerateNamedProperties( + v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate, + const std::string& property) override; + std::vector<std::string> EnumerateNamedProperties( v8::Isolate* isolate) override; static GinJavaBridgeObject* InjectNamed( @@ -53,7 +53,7 @@ GinJavaBridgeObject(v8::Isolate* isolate, const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, GinJavaBridgeDispatcher::ObjectID object_id); - virtual ~GinJavaBridgeObject(); + ~GinJavaBridgeObject() override; v8::Handle<v8::Value> InvokeMethod(const std::string& name, gin::Arguments* args);
diff --git a/content/renderer/java/gin_java_bridge_value_converter.h b/content/renderer/java/gin_java_bridge_value_converter.h index fd343b9f..9053bfa 100644 --- a/content/renderer/java/gin_java_bridge_value_converter.h +++ b/content/renderer/java/gin_java_bridge_value_converter.h
@@ -14,7 +14,7 @@ class GinJavaBridgeValueConverter : public content::V8ValueConverter::Strategy { public: CONTENT_EXPORT GinJavaBridgeValueConverter(); - CONTENT_EXPORT virtual ~GinJavaBridgeValueConverter(); + CONTENT_EXPORT ~GinJavaBridgeValueConverter() override; CONTENT_EXPORT v8::Handle<v8::Value> ToV8Value( const base::Value* value, @@ -24,16 +24,16 @@ v8::Handle<v8::Context> context) const; // content::V8ValueConverter::Strategy - virtual bool FromV8Object(v8::Handle<v8::Object> value, - base::Value** out, - v8::Isolate* isolate, - const FromV8ValueCallback& callback) const override; - virtual bool FromV8ArrayBuffer(v8::Handle<v8::Object> value, - base::Value** out, - v8::Isolate* isolate) const override; - virtual bool FromV8Number(v8::Handle<v8::Number> value, - base::Value** out) const override; - virtual bool FromV8Undefined(base::Value** out) const override; + bool FromV8Object(v8::Handle<v8::Object> value, + base::Value** out, + v8::Isolate* isolate, + const FromV8ValueCallback& callback) const override; + bool FromV8ArrayBuffer(v8::Handle<v8::Object> value, + base::Value** out, + v8::Isolate* isolate) const override; + bool FromV8Number(v8::Handle<v8::Number> value, + base::Value** out) const override; + bool FromV8Undefined(base::Value** out) const override; private: scoped_ptr<V8ValueConverter> converter_;
diff --git a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc index 1a0812b..edffce7 100644 --- a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc +++ b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
@@ -20,15 +20,13 @@ } protected: - virtual void SetUp() { + void SetUp() override { v8::HandleScope handle_scope(isolate_); v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_); context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global)); } - virtual void TearDown() { - context_.Reset(); - } + void TearDown() override { context_.Reset(); } v8::Isolate* isolate_;
diff --git a/content/renderer/media/android/media_source_delegate.cc b/content/renderer/media/android/media_source_delegate.cc index f4732a0..a5bf0b61 100644 --- a/content/renderer/media/android/media_source_delegate.cc +++ b/content/renderer/media/android/media_source_delegate.cc
@@ -737,6 +737,13 @@ configs->is_audio_encrypted = config.is_encrypted(); configs->audio_extra_data = std::vector<uint8>( config.extra_data(), config.extra_data() + config.extra_data_size()); + configs->audio_codec_delay_ns = static_cast<int64_t>( + config.codec_delay() * + (static_cast<double>(base::Time::kNanosecondsPerSecond) / + config.samples_per_second())); + configs->audio_seek_preroll_ns = + config.seek_preroll().InMicroseconds() * + base::Time::kNanosecondsPerMicrosecond; return true; } if (!is_audio && video_stream_) {
diff --git a/content/renderer/media/android/media_source_delegate.h b/content/renderer/media/android/media_source_delegate.h index 5e55066..c8eaade 100644 --- a/content/renderer/media/android/media_source_delegate.h +++ b/content/renderer/media/android/media_source_delegate.h
@@ -52,7 +52,7 @@ int demuxer_client_id, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<media::MediaLog> media_log); - virtual ~MediaSourceDelegate(); + ~MediaSourceDelegate() override; // Initialize the MediaSourceDelegate. |media_source| will be owned by // this object after this call. @@ -105,13 +105,13 @@ private: // Methods inherited from DemuxerHost. - virtual void AddBufferedTimeRange(base::TimeDelta start, - base::TimeDelta end) override; - virtual void SetDuration(base::TimeDelta duration) override; - virtual void OnDemuxerError(media::PipelineStatus status) override; - virtual void AddTextStream(media::DemuxerStream* text_stream, - const media::TextTrackConfig& config) override; - virtual void RemoveTextStream(media::DemuxerStream* text_stream) override; + void AddBufferedTimeRange(base::TimeDelta start, + base::TimeDelta end) override; + void SetDuration(base::TimeDelta duration) override; + void OnDemuxerError(media::PipelineStatus status) override; + void AddTextStream(media::DemuxerStream* text_stream, + const media::TextTrackConfig& config) override; + void RemoveTextStream(media::DemuxerStream* text_stream) override; // Notifies |demuxer_client_| and fires |duration_changed_cb_|. void OnDurationChanged(const base::TimeDelta& duration);
diff --git a/content/renderer/media/android/renderer_demuxer_android.h b/content/renderer/media/android/renderer_demuxer_android.h index 2fddc86..29469ede 100644 --- a/content/renderer/media/android/renderer_demuxer_android.h +++ b/content/renderer/media/android/renderer_demuxer_android.h
@@ -44,7 +44,7 @@ void RemoveDelegate(int demuxer_client_id); // IPC::MessageFilter overrides. - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; // media::DemuxerAndroidClient "implementation". // @@ -61,7 +61,7 @@ protected: friend class base::RefCountedThreadSafe<RendererDemuxerAndroid>; - virtual ~RendererDemuxerAndroid(); + ~RendererDemuxerAndroid() override; private: void DispatchMessage(const IPC::Message& message);
diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h index 4a51829..aec4910 100644 --- a/content/renderer/media/android/renderer_media_player_manager.h +++ b/content/renderer/media/android/renderer_media_player_manager.h
@@ -34,11 +34,11 @@ public: // Constructs a RendererMediaPlayerManager object for the |render_frame|. explicit RendererMediaPlayerManager(RenderFrame* render_frame); - virtual ~RendererMediaPlayerManager(); + ~RendererMediaPlayerManager() override; // RenderFrameObserver overrides. - virtual bool OnMessageReceived(const IPC::Message& msg) override; - virtual void WasHidden() override; + bool OnMessageReceived(const IPC::Message& msg) override; + void WasHidden() override; // Initializes a MediaPlayerAndroid object in browser process. void Initialize(MediaPlayerHostMsg_Initialize_Type type, @@ -96,7 +96,7 @@ void RequestExternalSurface(int player_id, const gfx::RectF& geometry); // RenderFrameObserver overrides. - virtual void DidCommitCompositorFrame() override; + void DidCommitCompositorFrame() override; // Returns true if a media player should use video-overlay for the embedded // encrypted video.
diff --git a/content/renderer/media/android/stream_texture_factory_impl.cc b/content/renderer/media/android/stream_texture_factory_impl.cc index 9756f396..e67fee9a 100644 --- a/content/renderer/media/android/stream_texture_factory_impl.cc +++ b/content/renderer/media/android/stream_texture_factory_impl.cc
@@ -19,17 +19,17 @@ public StreamTextureHost::Listener { public: explicit StreamTextureProxyImpl(StreamTextureHost* host); - virtual ~StreamTextureProxyImpl(); + ~StreamTextureProxyImpl() override; // StreamTextureProxy implementation: - virtual void BindToLoop(int32 stream_id, - cc::VideoFrameProvider::Client* client, - scoped_refptr<base::MessageLoopProxy> loop) override; - virtual void Release() override; + void BindToLoop(int32 stream_id, + cc::VideoFrameProvider::Client* client, + scoped_refptr<base::MessageLoopProxy> loop) override; + void Release() override; // StreamTextureHost::Listener implementation: - virtual void OnFrameAvailable() override; - virtual void OnMatrixChanged(const float matrix[16]) override; + void OnFrameAvailable() override; + void OnMatrixChanged(const float matrix[16]) override; private: void BindOnThread(int32 stream_id);
diff --git a/content/renderer/media/android/stream_texture_factory_impl.h b/content/renderer/media/android/stream_texture_factory_impl.h index f5ded1c8..0374879 100644 --- a/content/renderer/media/android/stream_texture_factory_impl.h +++ b/content/renderer/media/android/stream_texture_factory_impl.h
@@ -29,17 +29,15 @@ int frame_id); // StreamTextureFactory implementation. - virtual StreamTextureProxy* CreateProxy() override; - virtual void EstablishPeer(int32 stream_id, int player_id) override; - virtual unsigned CreateStreamTexture(unsigned texture_target, - unsigned* texture_id, - gpu::Mailbox* texture_mailbox) override; - virtual void SetStreamTextureSize(int32 texture_id, - const gfx::Size& size) override; - virtual gpu::gles2::GLES2Interface* ContextGL() override; - virtual void AddObserver(StreamTextureFactoryContextObserver* obs) override; - virtual void RemoveObserver( - StreamTextureFactoryContextObserver* obs) override; + StreamTextureProxy* CreateProxy() override; + void EstablishPeer(int32 stream_id, int player_id) override; + unsigned CreateStreamTexture(unsigned texture_target, + unsigned* texture_id, + gpu::Mailbox* texture_mailbox) override; + void SetStreamTextureSize(int32 texture_id, const gfx::Size& size) override; + gpu::gles2::GLES2Interface* ContextGL() override; + void AddObserver(StreamTextureFactoryContextObserver* obs) override; + void RemoveObserver(StreamTextureFactoryContextObserver* obs) override; private: friend class base::RefCounted<StreamTextureFactoryImpl>; @@ -47,7 +45,7 @@ const scoped_refptr<cc::ContextProvider>& context_provider, GpuChannelHost* channel, int frame_id); - virtual ~StreamTextureFactoryImpl(); + ~StreamTextureFactoryImpl() override; scoped_refptr<cc::ContextProvider> context_provider_; scoped_refptr<GpuChannelHost> channel_;
diff --git a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc index c6eb63d9..9c0d61ab 100644 --- a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc +++ b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc
@@ -31,13 +31,13 @@ public: explicit StreamTextureProxyImpl( StreamTextureFactorySynchronousImpl::ContextProvider* provider); - virtual ~StreamTextureProxyImpl(); + ~StreamTextureProxyImpl() override; // StreamTextureProxy implementation: - virtual void BindToLoop(int32 stream_id, - cc::VideoFrameProvider::Client* client, - scoped_refptr<base::MessageLoopProxy> loop) override; - virtual void Release() override; + void BindToLoop(int32 stream_id, + cc::VideoFrameProvider::Client* client, + scoped_refptr<base::MessageLoopProxy> loop) override; + void Release() override; private: void BindOnThread(int32 stream_id);
diff --git a/content/renderer/media/android/stream_texture_factory_synchronous_impl.h b/content/renderer/media/android/stream_texture_factory_synchronous_impl.h index 3f33bd39..1e2db8a5 100644 --- a/content/renderer/media/android/stream_texture_factory_synchronous_impl.h +++ b/content/renderer/media/android/stream_texture_factory_synchronous_impl.h
@@ -47,24 +47,22 @@ const CreateContextProviderCallback& try_create_callback, int frame_id); - virtual StreamTextureProxy* CreateProxy() override; - virtual void EstablishPeer(int32 stream_id, int player_id) override; - virtual unsigned CreateStreamTexture(unsigned texture_target, - unsigned* texture_id, - gpu::Mailbox* texture_mailbox) override; - virtual void SetStreamTextureSize(int32 stream_id, - const gfx::Size& size) override; - virtual gpu::gles2::GLES2Interface* ContextGL() override; - virtual void AddObserver(StreamTextureFactoryContextObserver* obs) override; - virtual void RemoveObserver( - StreamTextureFactoryContextObserver* obs) override; + StreamTextureProxy* CreateProxy() override; + void EstablishPeer(int32 stream_id, int player_id) override; + unsigned CreateStreamTexture(unsigned texture_target, + unsigned* texture_id, + gpu::Mailbox* texture_mailbox) override; + void SetStreamTextureSize(int32 stream_id, const gfx::Size& size) override; + gpu::gles2::GLES2Interface* ContextGL() override; + void AddObserver(StreamTextureFactoryContextObserver* obs) override; + void RemoveObserver(StreamTextureFactoryContextObserver* obs) override; private: friend class base::RefCounted<StreamTextureFactorySynchronousImpl>; StreamTextureFactorySynchronousImpl( const CreateContextProviderCallback& try_create_callback, int frame_id); - virtual ~StreamTextureFactorySynchronousImpl(); + ~StreamTextureFactorySynchronousImpl() override; CreateContextProviderCallback create_context_provider_callback_; scoped_refptr<ContextProvider> context_provider_;
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index f685b22..e0b7706 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -125,11 +125,11 @@ explicit SyncPointClientImpl( blink::WebGraphicsContext3D* web_graphics_context) : web_graphics_context_(web_graphics_context) {} - virtual ~SyncPointClientImpl() {} - virtual uint32 InsertSyncPoint() override { + ~SyncPointClientImpl() override {} + uint32 InsertSyncPoint() override { return web_graphics_context_->insertSyncPoint(); } - virtual void WaitSyncPoint(uint32 sync_point) override { + void WaitSyncPoint(uint32 sync_point) override { web_graphics_context_->waitSyncPoint(sync_point); }
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index 3ff74e05..314d7ee 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -174,11 +174,10 @@ // cc::VideoFrameProvider implementation. These methods are running on the // compositor thread. - virtual void SetVideoFrameProviderClient( + void SetVideoFrameProviderClient( cc::VideoFrameProvider::Client* client) override; - virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() override; - virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) - override; + scoped_refptr<media::VideoFrame> GetCurrentFrame() override; + void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) override; // Media player callback handlers. void OnMediaMetadataChanged(const base::TimeDelta& duration, int width, @@ -205,7 +204,7 @@ void OnRemoteRouteAvailabilityChanged(bool routes_available); // StreamTextureFactoryContextObserver implementation. - virtual void ResetStreamTextureProxy() override; + void ResetStreamTextureProxy() override; // Called when the player is released. virtual void OnPlayerReleased(); @@ -216,7 +215,7 @@ virtual void ReleaseMediaResources(); // RenderFrameObserver implementation. - virtual void OnDestruct() override; + void OnDestruct() override; #if defined(VIDEO_HOLE) // Calculate the boundary rectangle of the media player (i.e. location and
diff --git a/content/renderer/media/webrtc_logging.cc b/content/renderer/media/webrtc_logging.cc index 17e5c57..204c2c9 100644 --- a/content/renderer/media/webrtc_logging.cc +++ b/content/renderer/media/webrtc_logging.cc
@@ -5,19 +5,22 @@ #include "content/renderer/media/webrtc_logging.h" #include "base/time/time.h" +#include "base/lazy_instance.h" +#include "base/threading/thread_local.h" #include "content/public/renderer/webrtc_log_message_delegate.h" #include "third_party/webrtc/overrides/webrtc/base/logging.h" namespace content { -// Shall only be set once and never go back to NULL. -WebRtcLogMessageDelegate* g_webrtc_logging_delegate = NULL; +// Shall only be set once within a RenderThread and never go back to NULL. +base::LazyInstance<base::ThreadLocalPointer<WebRtcLogMessageDelegate> >::Leaky + g_webrtc_logging_delegate_tls = LAZY_INSTANCE_INITIALIZER; void InitWebRtcLoggingDelegate(WebRtcLogMessageDelegate* delegate) { - CHECK(!g_webrtc_logging_delegate); + CHECK(!g_webrtc_logging_delegate_tls.Pointer()->Get()); CHECK(delegate); - g_webrtc_logging_delegate = delegate; + g_webrtc_logging_delegate_tls.Pointer()->Set(delegate); } void InitWebRtcLogging() { @@ -26,8 +29,8 @@ } void WebRtcLogMessage(const std::string& message) { - if (g_webrtc_logging_delegate) - g_webrtc_logging_delegate->LogMessage(message); + if (g_webrtc_logging_delegate_tls.Pointer()->Get()) + g_webrtc_logging_delegate_tls.Pointer()->Get()->LogMessage(message); } } // namespace content
diff --git a/content/renderer/notification_permission_dispatcher.cc b/content/renderer/notification_permission_dispatcher.cc index 45e8651..fae8aad 100644 --- a/content/renderer/notification_permission_dispatcher.cc +++ b/content/renderer/notification_permission_dispatcher.cc
@@ -8,9 +8,9 @@ #include "content/public/common/service_registry.h" #include "content/public/renderer/render_frame.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/web/WebNotificationPermissionCallback.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h" #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" +#include "third_party/WebKit/public/web/modules/notifications/WebNotificationPermissionCallback.h" namespace content {
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index cc76c79..6f5dafe5 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1959,6 +1959,8 @@ void PepperPluginInstanceImpl::UpdateLayer(bool device_changed) { if (!container_) return; + if (throttler_ && throttler_->IsHiddenForPlaceholder()) + return; gpu::Mailbox mailbox; uint32 sync_point = 0; @@ -2045,6 +2047,14 @@ SendDidChangeView(); } +void PepperPluginInstanceImpl::OnHiddenForPlaceholder(bool hidden) { + if (hidden) { + container_->setWebLayer(nullptr); + } else { + UpdateLayer(true /* device_changed */); + } +} + void PepperPluginInstanceImpl::AddLatencyInfo( const std::vector<ui::LatencyInfo>& latency_info) { if (render_frame_ && render_frame_->GetRenderWidget()) {
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 3a0a69a..6de1847 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -543,6 +543,7 @@ // PluginInstanceThrottler::Observer void OnThrottleStateChange() override; + void OnHiddenForPlaceholder(bool hidden) override; void AddLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
diff --git a/content/renderer/pepper/plugin_instance_throttler_impl.cc b/content/renderer/pepper/plugin_instance_throttler_impl.cc index a95f6db..f1fe7c4 100644 --- a/content/renderer/pepper/plugin_instance_throttler_impl.cc +++ b/content/renderer/pepper/plugin_instance_throttler_impl.cc
@@ -59,7 +59,9 @@ bool power_saver_enabled) : state_(power_saver_enabled ? POWER_SAVER_ENABLED_AWAITING_KEYFRAME : POWER_SAVER_DISABLED), + is_hidden_for_placeholder_(false), consecutive_interesting_frames_(0), + keyframe_extraction_timed_out_(false), weak_factory_(this) { // To collect UMAs, register peripheral content even if power saver disabled. if (frame) { @@ -71,13 +73,15 @@ if (power_saver_enabled) { base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&PluginInstanceThrottlerImpl::EngageThrottle, - weak_factory_.GetWeakPtr()), + FROM_HERE, + base::Bind(&PluginInstanceThrottlerImpl::TimeoutKeyframeExtraction, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kThrottleTimeout)); } } PluginInstanceThrottlerImpl::~PluginInstanceThrottlerImpl() { + FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottlerDestroyed()); if (state_ != PLUGIN_INSTANCE_MARKED_ESSENTIAL) RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_NEVER); } @@ -94,6 +98,10 @@ return state_ == POWER_SAVER_ENABLED_PLUGIN_THROTTLED; } +bool PluginInstanceThrottlerImpl::IsHiddenForPlaceholder() const { + return is_hidden_for_placeholder_; +} + void PluginInstanceThrottlerImpl::MarkPluginEssential( PowerSaverUnthrottleMethod method) { if (state_ == PLUGIN_INSTANCE_MARKED_ESSENTIAL) @@ -107,6 +115,11 @@ FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); } +void PluginInstanceThrottlerImpl::SetHiddenForPlaceholder(bool hidden) { + is_hidden_for_placeholder_ = hidden; + FOR_EACH_OBSERVER(Observer, observer_list_, OnHiddenForPlaceholder(hidden)); +} + void PluginInstanceThrottlerImpl::OnImageFlush(const SkBitmap* bitmap) { DCHECK(needs_representative_keyframe()); if (!bitmap) @@ -118,8 +131,11 @@ else consecutive_interesting_frames_ = 0; - if (consecutive_interesting_frames_ >= kMinimumConsecutiveInterestingFrames) + if (keyframe_extraction_timed_out_ || + consecutive_interesting_frames_ >= kMinimumConsecutiveInterestingFrames) { + FOR_EACH_OBSERVER(Observer, observer_list_, OnKeyframeExtracted(bitmap)); EngageThrottle(); + } } bool PluginInstanceThrottlerImpl::ConsumeInputEvent( @@ -150,4 +166,8 @@ FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); } +void PluginInstanceThrottlerImpl::TimeoutKeyframeExtraction() { + keyframe_extraction_timed_out_ = true; +} + } // namespace content
diff --git a/content/renderer/pepper/plugin_instance_throttler_impl.h b/content/renderer/pepper/plugin_instance_throttler_impl.h index 14352c1..c8cbb8b 100644 --- a/content/renderer/pepper/plugin_instance_throttler_impl.h +++ b/content/renderer/pepper/plugin_instance_throttler_impl.h
@@ -34,7 +34,9 @@ void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; bool IsThrottled() const override; + bool IsHiddenForPlaceholder() const override; void MarkPluginEssential(PowerSaverUnthrottleMethod method) override; + void SetHiddenForPlaceholder(bool hidden) override; bool needs_representative_keyframe() const { return state_ == POWER_SAVER_ENABLED_AWAITING_KEYFRAME; @@ -70,11 +72,18 @@ void EngageThrottle(); + void TimeoutKeyframeExtraction(); + State state_; + bool is_hidden_for_placeholder_; + // Number of consecutive interesting frames we've encountered. int consecutive_interesting_frames_; + // If true, take the next frame as the keyframe regardless of interestingness. + bool keyframe_extraction_timed_out_; + ObserverList<Observer> observer_list_; base::WeakPtrFactory<PluginInstanceThrottlerImpl> weak_factory_;
diff --git a/content/renderer/pepper/plugin_module.cc b/content/renderer/pepper/plugin_module.cc index e6576bee..40b42bb 100644 --- a/content/renderer/pepper/plugin_module.cc +++ b/content/renderer/pepper/plugin_module.cc
@@ -93,6 +93,7 @@ #include "ppapi/c/ppb_var_array_buffer.h" #include "ppapi/c/ppb_var_dictionary.h" #include "ppapi/c/ppb_video_decoder.h" +#include "ppapi/c/ppb_video_encoder.h" #include "ppapi/c/ppb_video_frame.h" #include "ppapi/c/ppb_view.h" #include "ppapi/c/ppp.h"
diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc index b5eaa51..94c8db9 100644 --- a/content/renderer/pepper/resource_creation_impl.cc +++ b/content/renderer/pepper/resource_creation_impl.cc
@@ -338,6 +338,10 @@ return 0; // Not supported in-process. } +PP_Resource ResourceCreationImpl::CreateVideoEncoder(PP_Instance instance) { + return 0; // Not supported in-process. +} + PP_Resource ResourceCreationImpl::CreateVideoSource(PP_Instance instance) { return 0; // Not supported in-process. }
diff --git a/content/renderer/pepper/resource_creation_impl.h b/content/renderer/pepper/resource_creation_impl.h index 52c44fc0..834b68a6 100644 --- a/content/renderer/pepper/resource_creation_impl.h +++ b/content/renderer/pepper/resource_creation_impl.h
@@ -127,6 +127,7 @@ PP_Resource graphics3d_id, PP_VideoDecoder_Profile profile) override; PP_Resource CreateVideoDestination(PP_Instance instance) override; + PP_Resource CreateVideoEncoder(PP_Instance instance) override; PP_Resource CreateVideoSource(PP_Instance instance) override; PP_Resource CreateWheelInputEvent(PP_Instance instance, PP_TimeTicks time_stamp,
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index da84db9..c3e7e78c 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -523,15 +523,21 @@ gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); gles2->ActiveTexture(GL_TEXTURE0); gles2->BindTexture(GL_TEXTURE_2D, local_texture_id); +#if !defined(OS_ANDROID) + // BGRA is the native texture format, except on Android, where textures + // would be uploaded as GL_RGBA. gles2->TexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, + GL_BGRA_EXT, texture_size_.width(), texture_size_.height(), 0, - GL_RGBA, + GL_BGRA_EXT, GL_UNSIGNED_BYTE, &frame->argb_pixels.front()); +#else +#error Not implemented. +#endif host_->PictureReady(media::Picture(texture_id, frame->decode_id, frame->visible_rect, false));
diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.cc b/content/renderer/push_messaging/push_messaging_dispatcher.cc index 99f790c..6ad41f6 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.cc +++ b/content/renderer/push_messaging/push_messaging_dispatcher.cc
@@ -10,10 +10,10 @@ #include "content/renderer/manifest/manifest_manager.h" #include "content/renderer/render_frame_impl.h" #include "ipc/ipc_message.h" -#include "third_party/WebKit/public/platform/WebPushError.h" -#include "third_party/WebKit/public/platform/WebPushRegistration.h" #include "third_party/WebKit/public/platform/WebServiceWorkerRegistration.h" #include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushRegistration.h" #include "url/gurl.h" using blink::WebString;
diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.h b/content/renderer/push_messaging/push_messaging_dispatcher.h index 67a32beb..06fc371 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.h +++ b/content/renderer/push_messaging/push_messaging_dispatcher.h
@@ -10,8 +10,8 @@ #include "base/id_map.h" #include "content/public/common/push_messaging_status.h" #include "content/public/renderer/render_frame_observer.h" -#include "third_party/WebKit/public/platform/WebPushClient.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushClient.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" class GURL;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b9c3fc7..b69dd37c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -385,7 +385,6 @@ WebURLRequest CreateURLRequestForNavigation( const CommonNavigationParams& common_params, - const RequestNavigationParams& request_params, scoped_ptr<StreamOverrideParameters> stream_override, bool is_view_source_mode_enabled) { WebURLRequest request(common_params.url); @@ -401,32 +400,6 @@ request.setHTTPReferrer(web_referrer, common_params.referrer.policy); } - if (!request_params.extra_headers.empty()) { - for (net::HttpUtil::HeadersIterator i(request_params.extra_headers.begin(), - request_params.extra_headers.end(), - "\n"); - i.GetNext();) { - request.addHTTPHeaderField(WebString::fromUTF8(i.name()), - WebString::fromUTF8(i.values())); - } - } - - if (request_params.is_post) { - request.setHTTPMethod(WebString::fromUTF8("POST")); - - // Set post data. - WebHTTPBody http_body; - http_body.initialize(); - const char* data = NULL; - if (request_params.browser_initiated_post_data.size()) { - data = reinterpret_cast<const char*>( - &request_params.browser_initiated_post_data.front()); - } - http_body.appendData( - WebData(data, request_params.browser_initiated_post_data.size())); - request.setHTTPBody(http_body); - } - RequestExtraData* extra_data = new RequestExtraData(); extra_data->set_stream_override(stream_override.Pass()); request.setExtraData(extra_data); @@ -469,18 +442,6 @@ } // PlzNavigate -FrameHostMsg_BeginNavigation_Params MakeBeginNavigationParams( - blink::WebURLRequest* request) { - FrameHostMsg_BeginNavigation_Params params; - params.method = request->httpMethod().latin1(); - params.headers = GetWebURLRequestHeaders(*request); - params.load_flags = GetLoadFlagsForWebURLRequest(*request); - params.request_body = GetRequestBodyForWebURLRequest(*request); - params.has_user_gesture = request->hasUserGesture(); - return params; -} - -// PlzNavigate CommonNavigationParams MakeCommonNavigationParams( blink::WebURLRequest* request) { const RequestExtraData kEmptyData; @@ -1030,6 +991,8 @@ OnJavaScriptExecuteRequest) IPC_MESSAGE_HANDLER(FrameMsg_JavaScriptExecuteRequestForTests, OnJavaScriptExecuteRequestForTests) + IPC_MESSAGE_HANDLER(FrameMsg_FlushVisualStateRequest, + OnFlushVisualStateRequest) IPC_MESSAGE_HANDLER(FrameMsg_SetEditableSelectionOffsets, OnSetEditableSelectionOffsets) IPC_MESSAGE_HANDLER(FrameMsg_SetupTransitionView, OnSetupTransitionView) @@ -1047,7 +1010,6 @@ IPC_MESSAGE_HANDLER(FrameMsg_SetAccessibilityMode, OnSetAccessibilityMode) IPC_MESSAGE_HANDLER(FrameMsg_DisownOpener, OnDisownOpener) - IPC_MESSAGE_HANDLER(FrameMsg_RequestNavigation, OnRequestNavigation) IPC_MESSAGE_HANDLER(FrameMsg_CommitNavigation, OnCommitNavigation) #if defined(OS_ANDROID) IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems) @@ -1150,10 +1112,35 @@ // Navigate to the given URL. WebURLRequest request = CreateURLRequestForNavigation(params.common_params, - params.request_params, scoped_ptr<StreamOverrideParameters>(), frame->isViewSourceModeEnabled()); + if (!params.extra_headers.empty()) { + for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(), + params.extra_headers.end(), + "\n"); + i.GetNext();) { + request.addHTTPHeaderField(WebString::fromUTF8(i.name()), + WebString::fromUTF8(i.values())); + } + } + + if (params.is_post) { + request.setHTTPMethod(WebString::fromUTF8("POST")); + + // Set post data. + WebHTTPBody http_body; + http_body.initialize(); + const char* data = NULL; + if (params.browser_initiated_post_data.size()) { + data = reinterpret_cast<const char*>( + ¶ms.browser_initiated_post_data.front()); + } + http_body.appendData( + WebData(data, params.browser_initiated_post_data.size())); + request.setHTTPBody(http_body); + } + // A session history navigation should have been accompanied by state. CHECK_EQ(params.page_id, -1); @@ -1498,6 +1485,12 @@ } } +void RenderFrameImpl::OnFlushVisualStateRequest(uint64 id) { + GetRenderWidget()->QueueMessage( + new FrameHostMsg_FlushVisualStateResponse(routing_id_, id), + MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE); +} + void RenderFrameImpl::OnSetEditableSelectionOffsets(int start, int end) { base::AutoReset<bool> handling_select_range(&handling_select_range_, true); if (!GetRenderWidget()->ShouldHandleImeEvent()) @@ -2531,7 +2524,8 @@ // UpdateSessionHistory and update page_id_ even in this case, so that // the current entry gets a state update and so that we don't send a // state update to the wrong entry when we swap back in. - if (GetLoadingUrl() != GURL(kSwappedOutURL)) { + if (GetLoadingUrl() != GURL(kSwappedOutURL) && + !navigation_state->should_replace_current_entry()) { // Advance our offset in session history, applying the length limit. // There is now no forward history. render_view_->history_list_offset_++; @@ -3608,6 +3602,23 @@ return true; } +void RenderFrameImpl::suddenTerminationDisablerChanged( + bool present, + blink::WebFrameClient::SuddenTerminationDisablerType type) { + switch (type) { + case blink::WebFrameClient::BeforeUnloadHandler: + Send(new FrameHostMsg_BeforeUnloadHandlersPresent( + routing_id_, present)); + break; + case blink::WebFrameClient::UnloadHandler: + Send(new FrameHostMsg_UnloadHandlersPresent( + routing_id_, present)); + break; + default: + NOTREACHED(); + } +} + void RenderFrameImpl::DidPlay(blink::WebMediaPlayer* player) { Send(new FrameHostMsg_MediaPlayingNotification( routing_id_, reinterpret_cast<int64>(player), player->hasVideo(), @@ -3886,20 +3897,6 @@ } // PlzNavigate -void RenderFrameImpl::OnRequestNavigation( - const CommonNavigationParams& common_params, - const RequestNavigationParams& request_params) { - CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableBrowserSideNavigation)); - WebURLRequest request = - CreateURLRequestForNavigation(common_params, - request_params, - scoped_ptr<StreamOverrideParameters>(), - frame_->isViewSourceModeEnabled()); - BeginNavigation(&request); -} - -// PlzNavigate void RenderFrameImpl::OnCommitNavigation( const ResourceResponseHead& response, const GURL& stream_url, @@ -3931,7 +3928,6 @@ stream_override->response = response; WebURLRequest request = CreateURLRequestForNavigation(common_params, - RequestNavigationParams(), stream_override.Pass(), frame_->isViewSourceModeEnabled()); @@ -4405,9 +4401,13 @@ // browser. // TODO(clamy): Data urls should not be sent back to the browser either. Send(new FrameHostMsg_DidStartLoading(routing_id_, true)); - Send(new FrameHostMsg_BeginNavigation(routing_id_, - MakeBeginNavigationParams(request), - MakeCommonNavigationParams(request))); + Send(new FrameHostMsg_BeginNavigation( + routing_id_, MakeCommonNavigationParams(request), + BeginNavigationParams(request->httpMethod().latin1(), + GetWebURLRequestHeaders(*request), + GetLoadFlagsForWebURLRequest(*request), + request->hasUserGesture()), + GetRequestBodyForWebURLRequest(*request))); } GURL RenderFrameImpl::GetLoadingUrl() const {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index f6784e7..7c56df7 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -521,6 +521,9 @@ virtual void didChangeManifest(blink::WebLocalFrame*); virtual bool enterFullscreen(); virtual bool exitFullscreen(); + void suddenTerminationDisablerChanged( + bool present, + blink::WebFrameClient::SuddenTerminationDisablerType type) override; // WebMediaPlayerDelegate implementation: void DidPlay(blink::WebMediaPlayer* player) override; @@ -607,6 +610,7 @@ void OnJavaScriptExecuteRequestForTests(const base::string16& javascript, int id, bool notify_result); + void OnFlushVisualStateRequest(uint64 key); void OnSetEditableSelectionOffsets(int start, int end); void OnSetCompositionFromExistingText( int start, int end, @@ -632,9 +636,6 @@ void OnCopyToFindPboard(); #endif - // PlzNavigate - void OnRequestNavigation(const CommonNavigationParams& common_params, - const RequestNavigationParams& request_params); void OnCommitNavigation(const ResourceResponseHead& response, const GURL& stream_url, const CommonNavigationParams& common_params,
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 2044f81..d96caefa 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -105,6 +105,7 @@ #include "content/renderer/render_view_impl.h" #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/scheduler/renderer_scheduler.h" +#include "content/renderer/scheduler/resource_dispatch_throttler.h" #include "content/renderer/service_worker/embedded_worker_context_message_filter.h" #include "content/renderer/service_worker/embedded_worker_dispatcher.h" #include "content/renderer/shared_worker/embedded_shared_worker_stub.h" @@ -196,6 +197,16 @@ const int64 kInitialIdleHandlerDelayMs = 1000; const int64 kLongIdleHandlerDelayMs = 30*1000; +#if defined(OS_ANDROID) +// On Android, resource messages can each take ~1.5ms to dispatch on the browser +// IO thread. Limiting the message rate to 3/frame at 60hz ensures that the +// induced work takes but a fraction (~1/4) of the overall frame budget. +const int kMaxResourceRequestsPerFlushWhenThrottled = 3; +#else +const int kMaxResourceRequestsPerFlushWhenThrottled = 8; +#endif +const double kThrottledResourceRequestFlushPeriodS = 1. / 60.; + // Maximum allocation size allowed for image scaling filters that // require pre-scaling. Skia will fallback to a filter that doesn't // require pre-scaling if the default filter would require an @@ -475,6 +486,14 @@ channel()->SetListenerTaskRunner(renderer_scheduler_->DefaultTaskRunner()); embedded_worker_dispatcher_.reset(new EmbeddedWorkerDispatcher()); + // Note: This may reorder messages from the ResourceDispatcher with respect to + // other subsystems. + resource_dispatch_throttler_.reset(new ResourceDispatchThrottler( + static_cast<RenderThread*>(this), renderer_scheduler_.get(), + base::TimeDelta::FromSecondsD(kThrottledResourceRequestFlushPeriodS), + kMaxResourceRequestsPerFlushWhenThrottled)); + resource_dispatcher()->set_message_sender(resource_dispatch_throttler_.get()); + media_stream_center_ = NULL; db_message_filter_ = new DBMessageFilter();
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 288f4ffd..26de62b 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -101,6 +101,7 @@ class RendererBlinkPlatformImpl; class RendererDemuxerAndroid; class RendererScheduler; +class ResourceDispatchThrottler; class ResourceSchedulingFilter; class V8SamplingProfiler; class VideoCaptureImplManager; @@ -476,6 +477,7 @@ scoped_ptr<IndexedDBDispatcher> main_thread_indexed_db_dispatcher_; scoped_ptr<RendererScheduler> renderer_scheduler_; scoped_ptr<RendererBlinkPlatformImpl> blink_platform_impl_; + scoped_ptr<ResourceDispatchThrottler> resource_dispatch_throttler_; scoped_ptr<EmbeddedWorkerDispatcher> embedded_worker_dispatcher_; // Used on the render thread and deleted by WebKit at shutdown.
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 23b586a5a..3922568 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -364,7 +364,7 @@ nav_params.common_params.navigation_type = FrameMsg_Navigate_Type::NORMAL; nav_params.common_params.transition = ui::PAGE_TRANSITION_TYPED; nav_params.page_id = -1; - nav_params.request_params.is_post = true; + nav_params.is_post = true; nav_params.commit_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1); @@ -373,7 +373,7 @@ "post \0\ndata"); const unsigned int length = 11; const std::vector<unsigned char> post_data(raw_data, raw_data + length); - nav_params.request_params.browser_initiated_post_data = post_data; + nav_params.browser_initiated_post_data = post_data; frame()->OnNavigate(nav_params); ProcessPendingMessages(); @@ -2248,7 +2248,7 @@ FrameMsg_Navigate_Type::NORMAL; early_nav_params.common_params.transition = ui::PAGE_TRANSITION_TYPED; early_nav_params.page_id = -1; - early_nav_params.request_params.is_post = true; + early_nav_params.is_post = true; early_nav_params.commit_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1); @@ -2269,7 +2269,7 @@ FrameMsg_Navigate_Type::NORMAL; late_nav_params.common_params.transition = ui::PAGE_TRANSITION_TYPED; late_nav_params.page_id = -1; - late_nav_params.request_params.is_post = true; + late_nav_params.is_post = true; late_nav_params.commit_params.browser_navigation_start = base::TimeTicks::Now() + base::TimeDelta::FromDays(42);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 4bd9146e..14901d8edd 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1065,10 +1065,10 @@ settings->setV8CacheOptions( static_cast<WebSettings::V8CacheOptions>(prefs.v8_cache_options)); - settings->setV8ScriptStreamingEnabled(prefs.v8_script_streaming_enabled); - settings->setV8ScriptStreamingMode( - static_cast<WebSettings::V8ScriptStreamingMode>( - prefs.v8_script_streaming_mode)); + // Needs to happen before setIgnoreVIewportTagScaleLimits below. + web_view->setDefaultPageScaleLimits( + prefs.default_minimum_page_scale_factor, + prefs.default_maximum_page_scale_factor); #if defined(OS_ANDROID) settings->setAllowCustomScrollbarInMainFrame(false); @@ -1132,9 +1132,9 @@ settings->setShowContextMenuOnMouseUp(true); #endif - web_view->setDefaultPageScaleLimits( - prefs.default_minimum_page_scale_factor, - prefs.default_maximum_page_scale_factor); +#if defined(OS_MACOSX) + settings->setDoubleTapToZoomEnabled(true); +#endif } /*static*/ @@ -2305,7 +2305,7 @@ navigation_state->set_transferred_request_request_id( params.transferred_request_request_id); navigation_state->set_allow_download(params.common_params.allow_download); - navigation_state->set_extra_headers(params.request_params.extra_headers); + navigation_state->set_extra_headers(params.extra_headers); } else { navigation_state = NavigationState::CreateContentInitiated(); }
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index e6f99ae..139ee82e 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -453,9 +453,9 @@ SSLStatus GetSSLStatusOfFrame(blink::WebFrame* frame) const override; const std::string& GetAcceptLanguages() const override; #if defined(OS_ANDROID) - virtual void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateTopControlsState(TopControlsState constraints, + TopControlsState current, + bool animate) override; #endif bool uses_temporary_zoom_level() const { return uses_temporary_zoom_level_; }
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 9cc9899..1b29380 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -808,8 +808,8 @@ WillToggleFullscreen(); is_fullscreen_ = is_fullscreen; - webwidget_->setTopControlsLayoutHeight(top_controls_shrink_blink_size_ - ? top_controls_height : 0.f); + webwidget_->setTopControlsHeight(top_controls_height, + top_controls_shrink_blink_size_); if (size_ != new_size) { size_ = new_size;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index d0c1d88..83a6ece 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -419,7 +419,7 @@ std::vector<std::string> strict_codecs; net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, true); - if (!media::IsSupportedKeySystemWithMediaMimeType( + if (!media::PrefixedIsSupportedKeySystemWithMediaMimeType( mime_type_ascii, strict_codecs, key_system_ascii)) { return IsNotSupported; } @@ -458,6 +458,9 @@ mime_type_ascii, parsed_codec_ids); } +// TODO(jrummell): This method is only used by unprefixed EME, and should not +// be called when http://crbug.com/385874 is fixed. Remove this method once +// that happens. bool RendererBlinkPlatformImpl::MimeRegistry::supportsEncryptedMediaMIMEType( const WebString& key_system, const WebString& mime_type, @@ -980,11 +983,27 @@ if (gpu_channel_host.get() && gl_info) { const gpu::GPUInfo& gpu_info = gpu_channel_host->gpu_info(); - gl_info->vendorInfo.assign(blink::WebString::fromUTF8(gpu_info.gl_vendor)); - gl_info->rendererInfo.assign( - blink::WebString::fromUTF8(gpu_info.gl_renderer)); - gl_info->driverVersion.assign( - blink::WebString::fromUTF8(gpu_info.gl_version)); + switch (gpu_info.context_info_state) { + case gpu::kCollectInfoSuccess: + case gpu::kCollectInfoNonFatalFailure: + gl_info->vendorInfo.assign( + blink::WebString::fromUTF8(gpu_info.gl_vendor)); + gl_info->rendererInfo.assign( + blink::WebString::fromUTF8(gpu_info.gl_renderer)); + gl_info->driverVersion.assign( + blink::WebString::fromUTF8(gpu_info.driver_version)); + gl_info->vendorId = gpu_info.gpu.vendor_id; + gl_info->deviceId = gpu_info.gpu.device_id; + break; + case gpu::kCollectInfoFatalFailure: + case gpu::kCollectInfoNone: + gl_info->contextInfoCollectionFailure.assign(blink::WebString::fromUTF8( + "GPUInfoCollectionFailure: GPU initialization Failed. GPU " + "Info not Collected.")); + break; + default: + NOTREACHED(); + }; } WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc index 694a5c79..dd749c2 100644 --- a/content/renderer/renderer_main_platform_delegate_win.cc +++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -18,12 +18,12 @@ #include "content/renderer/render_thread_impl.h" #include "sandbox/win/src/sandbox.h" #include "skia/ext/fontmgr_default_win.h" -#include "skia/ext/vector_platform_device_emf_win.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/win/WebFontRendering.h" #include "third_party/icu/source/i18n/unicode/timezone.h" #include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" +#include "ui/gfx/hud_font.h" #include "ui/gfx/win/direct_write.h" #include "ui/gfx/win/dpi.h" @@ -55,10 +55,17 @@ void WarmupDirectWrite() { // The objects used here are intentionally not freed as we want the Skia // code to use these objects after warmup. + SetDefaultSkiaFactory(GetPreSandboxWarmupFontMgr()); SkTypeface* typeface = GetPreSandboxWarmupFontMgr()->legacyCreateTypeface("Times New Roman", 0); DoPreSandboxWarmupForTypeface(typeface); - SetDefaultSkiaFactory(GetPreSandboxWarmupFontMgr()); + + // The CC HUD needs a debug font, we warm that up here and pass it down. + skia::RefPtr<SkTypeface> hud_typeface = + skia::AdoptRef(GetPreSandboxWarmupFontMgr()->legacyCreateTypeface( + "Consolas", SkTypeface::kBold)); + DoPreSandboxWarmupForTypeface(hud_typeface.get()); + ui::SetHudTypeface(hud_typeface); } } // namespace @@ -93,8 +100,6 @@ WarmupDirectWrite(); } else { SkTypeface_SetEnsureLOGFONTAccessibleProc(SkiaPreCacheFont); - skia::SetSkiaEnsureTypefaceCharactersAccessible( - SkiaPreCacheFontCharacters); } } blink::WebFontRendering::setUseDirectWrite(use_direct_write); @@ -116,6 +121,13 @@ ::GetUserDefaultLangID(); ::GetUserDefaultLCID(); +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + if (!LoadLibraryA("dbghelp.dll")) + return false; +#endif + target_services->LowerToken(); return true; }
diff --git a/content/renderer/scheduler/null_renderer_scheduler.cc b/content/renderer/scheduler/null_renderer_scheduler.cc index 2c35bd3..7df3ff7 100644 --- a/content/renderer/scheduler/null_renderer_scheduler.cc +++ b/content/renderer/scheduler/null_renderer_scheduler.cc
@@ -78,6 +78,10 @@ void NullRendererScheduler::DidAnimateForInputOnCompositorThread() { } +bool NullRendererScheduler::IsHighPriorityWorkAnticipated() { + return false; +} + bool NullRendererScheduler::ShouldYieldForHighPriorityWork() { return false; }
diff --git a/content/renderer/scheduler/null_renderer_scheduler.h b/content/renderer/scheduler/null_renderer_scheduler.h index 5c5cf83..ab0e58f4 100644 --- a/content/renderer/scheduler/null_renderer_scheduler.h +++ b/content/renderer/scheduler/null_renderer_scheduler.h
@@ -24,6 +24,7 @@ void DidReceiveInputEventOnCompositorThread( blink::WebInputEvent::Type type) override; void DidAnimateForInputOnCompositorThread() override; + bool IsHighPriorityWorkAnticipated() override; bool ShouldYieldForHighPriorityWork() override; void Shutdown() override;
diff --git a/content/renderer/scheduler/renderer_scheduler.h b/content/renderer/scheduler/renderer_scheduler.h index f8a2060..e1b5c57 100644 --- a/content/renderer/scheduler/renderer_scheduler.h +++ b/content/renderer/scheduler/renderer_scheduler.h
@@ -53,8 +53,16 @@ // a fling). Called by the compositor (impl) thread. virtual void DidAnimateForInputOnCompositorThread() = 0; + // Returns true if the scheduler has reason to believe that high priority work + // may soon arrive on the main thread, e.g., if gesture events were observed + // recently. + // Must be called from the main thread. + virtual bool IsHighPriorityWorkAnticipated() = 0; + // Returns true if there is high priority work pending on the main thread - // and the caller should yield to let the scheduler service that work. + // and the caller should yield to let the scheduler service that work. Note + // that this is a stricter condition than |IsHighPriorityWorkAnticipated|, + // restricted to the case where real work is pending. // Must be called from the main thread. virtual bool ShouldYieldForHighPriorityWork() = 0;
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.cc b/content/renderer/scheduler/renderer_scheduler_impl.cc index fbd8cbe6..f991820f 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl.cc +++ b/content/renderer/scheduler/renderer_scheduler_impl.cc
@@ -64,38 +64,38 @@ } void RendererSchedulerImpl::Shutdown() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); task_queue_manager_.reset(); } scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::DefaultTaskRunner() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); return default_task_runner_; } scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::CompositorTaskRunner() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); return compositor_task_runner_; } scoped_refptr<SingleThreadIdleTaskRunner> RendererSchedulerImpl::IdleTaskRunner() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); return idle_task_runner_; } scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::LoadingTaskRunner() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); return loading_task_runner_; } void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue()); - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (!task_queue_manager_) return; @@ -106,7 +106,7 @@ void RendererSchedulerImpl::DidCommitFrameToCompositor() { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererSchedulerImpl::DidCommitFrameToCompositor"); - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (!task_queue_manager_) return; @@ -147,8 +147,17 @@ last_input_time_ = Now(); } +bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { + DCHECK(main_thread_checker_.CalledOnValidThread()); + if (!task_queue_manager_) + return false; + + MaybeUpdatePolicy(); + return SchedulerPolicy() == COMPOSITOR_PRIORITY_POLICY; +} + bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (!task_queue_manager_) return false; @@ -157,23 +166,25 @@ // work outstanding. Note: even though the control queue is higher priority // we don't yield for it since these tasks are not user-provided work and they // are only intended to run before the next task, not interrupt the tasks. + // Note: This function could conceivably be implemented in terms of + // |IsHighPriorityWorkAnticipated|, but for clarity is not. return SchedulerPolicy() == COMPOSITOR_PRIORITY_POLICY && !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE); } void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback( base::TimeTicks* deadline_out) const { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); *deadline_out = estimated_next_frame_begin_; } RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); return current_policy_; } void RendererSchedulerImpl::MaybeUpdatePolicy() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (policy_may_need_update_.IsSet()) { UpdatePolicy(); } @@ -186,7 +197,7 @@ } void RendererSchedulerImpl::UpdatePolicy() { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (!task_queue_manager_) return; @@ -243,23 +254,33 @@ void RendererSchedulerImpl::StartIdlePeriod() { TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", "RendererSchedulerIdlePeriod", this); - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); renderer_task_queue_selector_->EnableQueue( IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); } void RendererSchedulerImpl::EndIdlePeriod() { + bool is_tracing; + TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); + if (is_tracing && base::TimeTicks::Now() > estimated_next_frame_begin_) { + TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( + "renderer.scheduler", + "RendererSchedulerIdlePeriod", + this, + "DeadlineOverrun", + estimated_next_frame_begin_.ToInternalValue()); + } TRACE_EVENT_ASYNC_END0("renderer.scheduler", "RendererSchedulerIdlePeriod", this); - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); end_idle_period_closure_.Cancel(); renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); } void RendererSchedulerImpl::SetTimeSourceForTesting( scoped_refptr<cc::TestNowSource> time_source) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); time_source_ = time_source; task_queue_manager_->SetTimeSourceForTesting(time_source); } @@ -282,7 +303,6 @@ } bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const { - thread_checker_.CalledOnValidThread(); return base::subtle::Acquire_Load(&flag_) != 0; } @@ -320,7 +340,7 @@ scoped_refptr<base::debug::ConvertableToTraceFormat> RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); incoming_signals_lock_.AssertAcquired(); if (optional_now.is_null())
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.h b/content/renderer/scheduler/renderer_scheduler_impl.h index 9b4fdcf..fcec44b8 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl.h +++ b/content/renderer/scheduler/renderer_scheduler_impl.h
@@ -15,10 +15,16 @@ #include "content/renderer/scheduler/task_queue_manager.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; } +} // namespace base namespace content { @@ -40,6 +46,7 @@ void DidReceiveInputEventOnCompositorThread( blink::WebInputEvent::Type type) override; void DidAnimateForInputOnCompositorThread() override; + bool IsHighPriorityWorkAnticipated() override; bool ShouldYieldForHighPriorityWork() override; void Shutdown() override; @@ -78,7 +85,6 @@ private: base::subtle::Atomic32 flag_; base::Lock* write_lock_; // Not owned. - base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(PollableNeedsUpdateFlag); };
diff --git a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc index ee16d04..7f49e51 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc +++ b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
@@ -36,6 +36,11 @@ } protected: + static base::TimeDelta compositor_priority_after_touch_duration() { + return base::TimeDelta::FromMilliseconds( + RendererSchedulerImpl::kCompositorPriorityAfterTouchMillis); + } + scoped_refptr<cc::TestNowSource> clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; @@ -132,6 +137,18 @@ *should_yield_after = scheduler->ShouldYieldForHighPriorityWork(); } +void AnticipationTestTask(RendererSchedulerImpl* scheduler, + bool simulate_input, + bool* is_anticipated_before, + bool* is_anticipated_after) { + *is_anticipated_before = scheduler->IsHighPriorityWorkAnticipated(); + if (simulate_input) { + scheduler->DidReceiveInputEventOnCompositorThread( + blink::WebInputEvent::GestureFlingStart); + } + *is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated(); +} + TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) { int result = 0; default_task_runner_->PostTask(FROM_HERE, @@ -499,6 +516,45 @@ std::string("D2"), std::string("C2"))); } +TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) { + bool is_anticipated_before = false; + bool is_anticipated_after = false; + + bool simulate_input = false; + default_task_runner_->PostTask( + FROM_HERE, + base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input, + &is_anticipated_before, &is_anticipated_after)); + RunUntilIdle(); + // In its default state, without input receipt, the scheduler should indicate + // that no high-priority is anticipated. + EXPECT_FALSE(is_anticipated_before); + EXPECT_FALSE(is_anticipated_after); + + simulate_input = true; + default_task_runner_->PostTask( + FROM_HERE, + base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input, + &is_anticipated_before, &is_anticipated_after)); + RunUntilIdle(); + // When input is received, the scheduler should indicate that high-priority + // work is anticipated. + EXPECT_FALSE(is_anticipated_before); + EXPECT_TRUE(is_anticipated_after); + + clock_->AdvanceNow(compositor_priority_after_touch_duration() * 2); + simulate_input = false; + default_task_runner_->PostTask( + FROM_HERE, + base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input, + &is_anticipated_before, &is_anticipated_after)); + RunUntilIdle(); + // Without additional input, the scheduler should indicate that high-priority + // work is no longer anticipated. + EXPECT_FALSE(is_anticipated_before); + EXPECT_FALSE(is_anticipated_after); +} + TEST_F(RendererSchedulerImplTest, TestShouldYield) { bool should_yield_before = false; bool should_yield_after = false;
diff --git a/content/renderer/scheduler/renderer_task_queue_selector.cc b/content/renderer/scheduler/renderer_task_queue_selector.cc index 5472220..cc4a7ce 100644 --- a/content/renderer/scheduler/renderer_task_queue_selector.cc +++ b/content/renderer/scheduler/renderer_task_queue_selector.cc
@@ -18,7 +18,7 @@ void RendererTaskQueueSelector::RegisterWorkQueues( const std::vector<const base::TaskQueue*>& work_queues) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); work_queues_ = work_queues; for (QueuePriority priority = FIRST_QUEUE_PRIORITY; priority < QUEUE_PRIORITY_COUNT; @@ -33,7 +33,7 @@ void RendererTaskQueueSelector::SetQueuePriority(size_t queue_index, QueuePriority priority) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_LT(queue_index, work_queues_.size()); DCHECK_LT(priority, QUEUE_PRIORITY_COUNT); DisableQueue(queue_index); @@ -46,7 +46,7 @@ } void RendererTaskQueueSelector::DisableQueue(size_t queue_index) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_LT(queue_index, work_queues_.size()); for (QueuePriority priority = FIRST_QUEUE_PRIORITY; priority < QUEUE_PRIORITY_COUNT; @@ -93,7 +93,7 @@ bool RendererTaskQueueSelector::SelectWorkQueueToService( size_t* out_queue_index) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(work_queues_.size()); // Always service the control queue if it has any work. if (ChooseOldestWithPriority(CONTROL_PRIORITY, out_queue_index)) { @@ -154,7 +154,7 @@ void RendererTaskQueueSelector::AsValueInto( base::debug::TracedValue* state) const { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); state->BeginDictionary("priorities"); for (QueuePriority priority = FIRST_QUEUE_PRIORITY; priority < QUEUE_PRIORITY_COUNT; priority = NextPriority(priority)) {
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.cc b/content/renderer/scheduler/resource_dispatch_throttler.cc new file mode 100644 index 0000000..927db73d --- /dev/null +++ b/content/renderer/scheduler/resource_dispatch_throttler.cc
@@ -0,0 +1,146 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/scheduler/resource_dispatch_throttler.h" + +#include "base/auto_reset.h" +#include "base/trace_event/trace_event.h" +#include "content/common/resource_messages.h" +#include "content/renderer/scheduler/renderer_scheduler.h" +#include "ipc/ipc_message_macros.h" + +namespace content { +namespace { + +bool IsResourceRequest(const IPC::Message& msg) { + return msg.type() == ResourceHostMsg_RequestResource::ID; +} + +} // namespace + +ResourceDispatchThrottler::ResourceDispatchThrottler( + IPC::Sender* proxied_sender, + RendererScheduler* scheduler, + base::TimeDelta flush_period, + uint32 max_requests_per_flush) + : proxied_sender_(proxied_sender), + scheduler_(scheduler), + flush_period_(flush_period), + max_requests_per_flush_(max_requests_per_flush), + flush_timer_( + FROM_HERE, + flush_period_, + base::Bind(&ResourceDispatchThrottler::Flush, base::Unretained(this)), + false /* is_repeating */), + sent_requests_since_last_flush_(0) { + DCHECK(proxied_sender); + DCHECK(scheduler); + DCHECK_NE(flush_period_, base::TimeDelta()); + DCHECK(max_requests_per_flush_); + flush_timer_.SetTaskRunner(scheduler->LoadingTaskRunner()); +} + +ResourceDispatchThrottler::~ResourceDispatchThrottler() { + FlushAll(); +} + +bool ResourceDispatchThrottler::Send(IPC::Message* msg) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (msg->is_sync()) { + // Flush any pending requests, preserving dispatch order between async and + // sync requests. + FlushAll(); + return ForwardMessage(msg); + } + + // Always defer message forwarding if there are pending messages, ensuring + // message dispatch ordering consistency. + if (!throttled_messages_.empty()) { + TRACE_EVENT_INSTANT0("loader", "ResourceDispatchThrottler::ThrottleMessage", + TRACE_EVENT_SCOPE_THREAD); + throttled_messages_.push_back(msg); + return true; + } + + if (!IsResourceRequest(*msg)) + return ForwardMessage(msg); + + if (!scheduler_->IsHighPriorityWorkAnticipated()) + return ForwardMessage(msg); + + if (Now() > (last_sent_request_time_ + flush_period_)) { + // If sufficient time has passed since the previous send, we can effectively + // mark the pipeline as flushed. + sent_requests_since_last_flush_ = 0; + return ForwardMessage(msg); + } + + if (sent_requests_since_last_flush_ < max_requests_per_flush_) + return ForwardMessage(msg); + + TRACE_EVENT_INSTANT0("loader", "ResourceDispatchThrottler::ThrottleRequest", + TRACE_EVENT_SCOPE_THREAD); + throttled_messages_.push_back(msg); + ScheduleFlush(); + return true; +} + +base::TimeTicks ResourceDispatchThrottler::Now() const { + return base::TimeTicks::Now(); +} + +void ResourceDispatchThrottler::ScheduleFlush() { + DCHECK(!flush_timer_.IsRunning()); + flush_timer_.Reset(); +} + +void ResourceDispatchThrottler::Flush() { + DCHECK(thread_checker_.CalledOnValidThread()); + TRACE_EVENT1("loader", "ResourceDispatchThrottler::Flush", + "total_throttled_messages", throttled_messages_.size()); + sent_requests_since_last_flush_ = 0; + + // If high-priority work is no longer anticipated, dispatch can be safely + // accelerated. Avoid completely flushing in such case in the event that + // a large number of requests have been throttled. + uint32 max_requests = scheduler_->IsHighPriorityWorkAnticipated() + ? max_requests_per_flush_ + : max_requests_per_flush_ * 2; + + while (!throttled_messages_.empty() && + (sent_requests_since_last_flush_ < max_requests || + !IsResourceRequest(*throttled_messages_.front()))) { + IPC::Message* msg = throttled_messages_.front(); + throttled_messages_.pop_front(); + ForwardMessage(msg); + } + + if (!throttled_messages_.empty()) + ScheduleFlush(); +} + +void ResourceDispatchThrottler::FlushAll() { + if (throttled_messages_.empty()) + return; + + TRACE_EVENT1("loader", "ResourceDispatchThrottler::FlushAll", + "total_throttled_messages", throttled_messages_.size()); + std::deque<IPC::Message*> throttled_messages; + throttled_messages.swap(throttled_messages_); + for (auto& message : throttled_messages) + ForwardMessage(message); + // There shouldn't be re-entrancy issues when forwarding an IPC, but validate + // as a safeguard. + DCHECK(throttled_messages_.empty()); +} + +bool ResourceDispatchThrottler::ForwardMessage(IPC::Message* msg) { + if (IsResourceRequest(*msg)) { + last_sent_request_time_ = Now(); + ++sent_requests_since_last_flush_; + } + return proxied_sender_->Send(msg); +} + +} // namespace content
diff --git a/content/renderer/scheduler/resource_dispatch_throttler.h b/content/renderer/scheduler/resource_dispatch_throttler.h new file mode 100644 index 0000000..233dea5a --- /dev/null +++ b/content/renderer/scheduler/resource_dispatch_throttler.h
@@ -0,0 +1,70 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_SCHEDULER_RESOURCE_DISPATCH_THROTTLER_H_ +#define CONTENT_RENDERER_SCHEDULER_RESOURCE_DISPATCH_THROTTLER_H_ + +#include <deque> + +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "content/common/content_export.h" +#include "ipc/ipc_sender.h" + +namespace content { + +class RendererScheduler; + +// Utility class for throttling a stream of resource requests targetted to a +// specific IPC sender. The throttling itself is very basic: +// * When there is no high-priority work imminent to the main thread, as +// indicated by the RendererScheduler, throttling is disabled. +// * When >= N requests have been sent in a given time window, requests are +// throttled. A timer periodically flushes a portion of the queued requests +// until all such requests have been flushed. +// TODO(jdduke): Remove this class after resource requests become sufficiently +// cheap on the IO thread, crbug.com/440037. +class CONTENT_EXPORT ResourceDispatchThrottler : public IPC::Sender { + public: + // |flush_period| and |max_requests_per_flush| must be strictly positive + // in duration/value. + ResourceDispatchThrottler(IPC::Sender* proxied_sender, + RendererScheduler* scheduler, + base::TimeDelta flush_period, + uint32 max_requests_per_flush); + ~ResourceDispatchThrottler() override; + + // IPC::Sender implementation: + bool Send(IPC::Message* msg) override; + + private: + friend class ResourceDispatchThrottlerForTest; + + // Virtual for testing. + virtual base::TimeTicks Now() const; + virtual void ScheduleFlush(); + + void Flush(); + void FlushAll(); + bool ForwardMessage(IPC::Message* msg); + + base::ThreadChecker thread_checker_; + + IPC::Sender* const proxied_sender_; + RendererScheduler* const scheduler_; + const base::TimeDelta flush_period_; + const uint32 max_requests_per_flush_; + + base::Timer flush_timer_; + base::TimeTicks last_sent_request_time_; + uint32 sent_requests_since_last_flush_; + std::deque<IPC::Message*> throttled_messages_; + + DISALLOW_COPY_AND_ASSIGN(ResourceDispatchThrottler); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_SCHEDULER_RESOURCE_DISPATCH_THROTTLER_H_
diff --git a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc new file mode 100644 index 0000000..8217f7a --- /dev/null +++ b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
@@ -0,0 +1,370 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/scheduler/resource_dispatch_throttler.h" + +#include "base/memory/scoped_vector.h" +#include "content/common/resource_messages.h" +#include "content/test/fake_renderer_scheduler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { +namespace { + +const uint32 kRequestsPerFlush = 4; +const double kFlushPeriodSeconds = 1.f / 60; +const int kRoutingId = 1; + +typedef ScopedVector<IPC::Message> ScopedMessages; + +int GetRequestId(const IPC::Message& msg) { + int request_id = -1; + switch (msg.type()) { + case ResourceHostMsg_RequestResource::ID: { + PickleIterator iter(msg); + int routing_id = -1; + if (!iter.ReadInt(&routing_id) || !iter.ReadInt(&request_id)) + NOTREACHED() << "Invalid id for resource request message."; + } break; + + case ResourceHostMsg_DidChangePriority::ID: + case ResourceHostMsg_ReleaseDownloadedFile::ID: + case ResourceHostMsg_CancelRequest::ID: + if (!PickleIterator(msg).ReadInt(&request_id)) + NOTREACHED() << "Invalid id for resource message."; + break; + + default: + NOTREACHED() << "Invalid message for resource throttling."; + break; + } + return request_id; +} + +class RendererSchedulerForTest : public FakeRendererScheduler { + public: + RendererSchedulerForTest() : high_priority_work_anticipated_(false) {} + ~RendererSchedulerForTest() override {} + + // RendererScheduler implementation: + bool IsHighPriorityWorkAnticipated() override { + return high_priority_work_anticipated_; + } + + void set_high_priority_work_anticipated(bool anticipated) { + high_priority_work_anticipated_ = anticipated; + } + + private: + bool high_priority_work_anticipated_; +}; + +} // namespace + +class ResourceDispatchThrottlerForTest : public ResourceDispatchThrottler { + public: + ResourceDispatchThrottlerForTest(IPC::Sender* sender, + RendererScheduler* scheduler) + : ResourceDispatchThrottler( + sender, + scheduler, + base::TimeDelta::FromSecondsD(kFlushPeriodSeconds), + kRequestsPerFlush), + flush_scheduled_(false) {} + ~ResourceDispatchThrottlerForTest() override {} + + void Advance(base::TimeDelta delta) { now_ += delta; } + + bool RunScheduledFlush() { + if (!flush_scheduled_) + return false; + + flush_scheduled_ = false; + Flush(); + return true; + } + + bool flush_scheduled() const { return flush_scheduled_; } + + private: + // ResourceDispatchThrottler overrides: + base::TimeTicks Now() const override { return now_; } + void ScheduleFlush() override { flush_scheduled_ = true; } + + base::TimeTicks now_; + bool flush_scheduled_; +}; + +class ResourceDispatchThrottlerTest : public testing::Test, public IPC::Sender { + public: + ResourceDispatchThrottlerTest() : last_request_id_(0) { + throttler_.reset(new ResourceDispatchThrottlerForTest(this, &scheduler_)); + } + ~ResourceDispatchThrottlerTest() override {} + + // IPC::Sender implementation: + bool Send(IPC::Message* msg) override { + sent_messages_.push_back(msg); + return true; + } + + protected: + void SetHighPriorityWorkAnticipated(bool anticipated) { + scheduler_.set_high_priority_work_anticipated(anticipated); + } + + void Advance(base::TimeDelta delta) { throttler_->Advance(delta); } + + bool RunScheduledFlush() { return throttler_->RunScheduledFlush(); } + + bool FlushScheduled() { return throttler_->flush_scheduled(); } + + bool RequestResource() { + ResourceHostMsg_Request request; + request.download_to_file = true; + return throttler_->Send(new ResourceHostMsg_RequestResource( + kRoutingId, ++last_request_id_, request)); + } + + bool RequestResourceSync() { + SyncLoadResult result; + return throttler_->Send(new ResourceHostMsg_SyncLoad( + kRoutingId, ++last_request_id_, ResourceHostMsg_Request(), &result)); + } + + void RequestResourcesUntilThrottled() { + SetHighPriorityWorkAnticipated(true); + GetAndResetSentMessageCount(); + RequestResource(); + while (GetAndResetSentMessageCount()) + RequestResource(); + } + + bool UpdateRequestPriority(int request_id, net::RequestPriority priority) { + return throttler_->Send( + new ResourceHostMsg_DidChangePriority(request_id, priority, 0)); + } + + bool ReleaseDownloadedFile(int request_id) { + return throttler_->Send( + new ResourceHostMsg_ReleaseDownloadedFile(request_id)); + } + + bool CancelRequest(int request_id) { + return throttler_->Send(new ResourceHostMsg_CancelRequest(request_id)); + } + + size_t GetAndResetSentMessageCount() { + size_t sent_message_count = sent_messages_.size(); + sent_messages_.clear(); + return sent_message_count; + } + + const IPC::Message* LastSentMessage() const { + return sent_messages_.empty() ? nullptr : sent_messages_.back(); + } + + int LastSentRequestId() const { + const IPC::Message* msg = LastSentMessage(); + if (!msg) + return -1; + + int routing_id = -1; + int request_id = -1; + PickleIterator iter(*msg); + CHECK(IPC::ReadParam(msg, &iter, &routing_id)); + CHECK(IPC::ReadParam(msg, &iter, &request_id)); + return request_id; + } + + int last_request_id() const { return last_request_id_; } + + ScopedMessages sent_messages_; + + private: + scoped_ptr<ResourceDispatchThrottlerForTest> throttler_; + RendererSchedulerForTest scheduler_; + int last_request_id_; + bool flush_scheduled_; + + DISALLOW_COPY_AND_ASSIGN(ResourceDispatchThrottlerTest); +}; + +TEST_F(ResourceDispatchThrottlerTest, NotThrottledByDefault) { + SetHighPriorityWorkAnticipated(false); + for (size_t i = 0; i < kRequestsPerFlush * 2; ++i) { + RequestResource(); + EXPECT_EQ(i + 1, sent_messages_.size()); + } +} + +TEST_F(ResourceDispatchThrottlerTest, NotThrottledIfSendLimitNotReached) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush; ++i) { + RequestResource(); + EXPECT_EQ(i + 1, sent_messages_.size()); + } +} + +TEST_F(ResourceDispatchThrottlerTest, ThrottledWhenHighPriorityWork) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + RequestResource(); + EXPECT_EQ(0U, sent_messages_.size()); + + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(1U, sent_messages_.size()); +} + +TEST_F(ResourceDispatchThrottlerTest, + ThrottledWhenDeferredMessageQueueNonEmpty) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + RequestResource(); + EXPECT_EQ(0U, sent_messages_.size()); + SetHighPriorityWorkAnticipated(false); + RequestResource(); + EXPECT_EQ(0U, sent_messages_.size()); + + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(2U, sent_messages_.size()); +} + +TEST_F(ResourceDispatchThrottlerTest, NotThrottledIfSufficientTimePassed) { + SetHighPriorityWorkAnticipated(true); + + for (size_t i = 0; i < kRequestsPerFlush * 2; ++i) { + Advance(base::TimeDelta::FromSecondsD(kFlushPeriodSeconds * 2)); + RequestResource(); + EXPECT_EQ(1U, GetAndResetSentMessageCount()); + EXPECT_FALSE(FlushScheduled()); + } +} + +TEST_F(ResourceDispatchThrottlerTest, NotThrottledIfSyncMessage) { + SetHighPriorityWorkAnticipated(true); + + RequestResourceSync(); + EXPECT_EQ(1U, GetAndResetSentMessageCount()); + + // Saturate the queue. + for (size_t i = 0; i < kRequestsPerFlush * 2; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + // Synchronous messages should flush any previously throttled messages. + RequestResourceSync(); + EXPECT_EQ(1U + kRequestsPerFlush, GetAndResetSentMessageCount()); + RequestResourceSync(); + EXPECT_EQ(1U, GetAndResetSentMessageCount()); + + // Previously throttled messages should already have been flushed. + RunScheduledFlush(); + EXPECT_EQ(0U, GetAndResetSentMessageCount()); +} + +TEST_F(ResourceDispatchThrottlerTest, MultipleFlushes) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush * 4; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + for (size_t i = 0; i < 3; ++i) { + SCOPED_TRACE(i); + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + } + + EXPECT_FALSE(FlushScheduled()); + EXPECT_EQ(0U, sent_messages_.size()); +} + +TEST_F(ResourceDispatchThrottlerTest, MultipleFlushesWhileReceiving) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush * 4; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + for (size_t i = 0; i < 3; ++i) { + SCOPED_TRACE(i); + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + for (size_t j = 0; j < kRequestsPerFlush; ++j) + RequestResource(); + EXPECT_EQ(0U, sent_messages_.size()); + } + + for (size_t i = 0; i < 3; ++i) { + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + } + + EXPECT_FALSE(FlushScheduled()); + EXPECT_EQ(0U, sent_messages_.size()); +} + +TEST_F(ResourceDispatchThrottlerTest, NonRequestsNeverTriggerThrottling) { + RequestResource(); + ASSERT_EQ(1U, GetAndResetSentMessageCount()); + + for (size_t i = 0; i < kRequestsPerFlush * 3; ++i) + UpdateRequestPriority(last_request_id(), net::HIGHEST); + EXPECT_EQ(kRequestsPerFlush * 3, sent_messages_.size()); + + RequestResource(); + EXPECT_EQ(1U + kRequestsPerFlush * 3, GetAndResetSentMessageCount()); +} + +TEST_F(ResourceDispatchThrottlerTest, NonRequestsDeferredWhenThrottling) { + RequestResource(); + ASSERT_EQ(1U, GetAndResetSentMessageCount()); + + RequestResourcesUntilThrottled(); + UpdateRequestPriority(last_request_id(), net::HIGHEST); + ReleaseDownloadedFile(last_request_id()); + CancelRequest(last_request_id()); + + EXPECT_TRUE(RunScheduledFlush()); + EXPECT_EQ(4U, GetAndResetSentMessageCount()); + EXPECT_FALSE(FlushScheduled()); +} + +TEST_F(ResourceDispatchThrottlerTest, MessageOrderingPreservedWhenThrottling) { + SetHighPriorityWorkAnticipated(true); + for (size_t i = 0; i < kRequestsPerFlush; ++i) + RequestResource(); + ASSERT_EQ(kRequestsPerFlush, GetAndResetSentMessageCount()); + + for (size_t i = 0; i < kRequestsPerFlush; ++i) { + RequestResource(); + UpdateRequestPriority(last_request_id(), net::HIGHEST); + CancelRequest(last_request_id() - 1); + } + ASSERT_EQ(0U, sent_messages_.size()); + + EXPECT_TRUE(RunScheduledFlush()); + ASSERT_EQ(kRequestsPerFlush * 3, sent_messages_.size()); + for (size_t i = 0; i < sent_messages_.size(); i += 3) { + SCOPED_TRACE(i); + const auto& request_msg = *sent_messages_[i]; + const auto& priority_msg = *sent_messages_[i + 1]; + const auto& cancel_msg = *sent_messages_[i + 2]; + + EXPECT_EQ(request_msg.type(), ResourceHostMsg_RequestResource::ID); + EXPECT_EQ(priority_msg.type(), ResourceHostMsg_DidChangePriority::ID); + EXPECT_EQ(cancel_msg.type(), ResourceHostMsg_CancelRequest::ID); + + EXPECT_EQ(GetRequestId(request_msg), GetRequestId(priority_msg)); + EXPECT_EQ(GetRequestId(request_msg) - 1, GetRequestId(cancel_msg)); + } + EXPECT_FALSE(FlushScheduled()); +} + +} // namespace content
diff --git a/content/renderer/scheduler/task_queue_manager.cc b/content/renderer/scheduler/task_queue_manager.cc index 083c773..12c4e18 100644 --- a/content/renderer/scheduler/task_queue_manager.cc +++ b/content/renderer/scheduler/task_queue_manager.cc
@@ -317,13 +317,13 @@ } void TaskQueueManager::SetAutoPump(size_t queue_index, bool auto_pump) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); internal::TaskQueue* queue = Queue(queue_index); queue->SetAutoPump(auto_pump); } void TaskQueueManager::PumpQueue(size_t queue_index) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); internal::TaskQueue* queue = Queue(queue_index); queue->PumpQueue(); } @@ -333,7 +333,7 @@ // TODO(skyostil): This is not efficient when the number of queues grows very // large due to the number of locks taken. Consider optimizing when we get // there. - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); bool has_work = false; for (auto& queue : queues_) { has_work |= queue->UpdateWorkQueue(next_pending_delayed_task); @@ -367,7 +367,7 @@ pending_dowork_count_--; DCHECK_GE(pending_dowork_count_, 0); } - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); base::TimeTicks next_pending_delayed_task( base::TimeTicks::FromInternalValue(kMaxTimeTicks)); @@ -404,7 +404,7 @@ } void TaskQueueManager::ProcessTaskFromWorkQueue(size_t queue_index) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); internal::TaskQueue* queue = Queue(queue_index); base::PendingTask pending_task = queue->TakeTaskFromWorkQueue(); if (!pending_task.nestable) { @@ -431,20 +431,20 @@ } void TaskQueueManager::SetQueueName(size_t queue_index, const char* name) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); internal::TaskQueue* queue = Queue(queue_index); queue->set_name(name); } void TaskQueueManager::SetWorkBatchSize(int work_batch_size) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_GE(work_batch_size, 1); work_batch_size_ = work_batch_size; } void TaskQueueManager::SetTimeSourceForTesting( scoped_refptr<cc::TestNowSource> time_source) { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); time_source_ = time_source; } @@ -455,7 +455,7 @@ scoped_refptr<base::debug::ConvertableToTraceFormat> TaskQueueManager::AsValueWithSelectorResult(bool should_run, size_t selected_queue) const { - main_thread_checker_.CalledOnValidThread(); + DCHECK(main_thread_checker_.CalledOnValidThread()); scoped_refptr<base::debug::TracedValue> state = new base::debug::TracedValue(); state->BeginArray("queues");
diff --git a/content/renderer/scheduler/task_queue_manager.h b/content/renderer/scheduler/task_queue_manager.h index a0a1a44..3112e698 100644 --- a/content/renderer/scheduler/task_queue_manager.h +++ b/content/renderer/scheduler/task_queue_manager.h
@@ -16,11 +16,18 @@ #include "content/common/content_export.h" namespace base { -namespace debug { +namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::ConvertableToTraceFormat; +using ::base::trace_event::TracedValue; } +} // namespace base namespace cc { class TestNowSource;
diff --git a/content/renderer/scheduler/task_queue_selector.h b/content/renderer/scheduler/task_queue_selector.h index fe20847..efe9bcf 100644 --- a/content/renderer/scheduler/task_queue_selector.h +++ b/content/renderer/scheduler/task_queue_selector.h
@@ -11,8 +11,14 @@ namespace base { class TaskQueue; -namespace debug { +namespace trace_event { class TracedValue; +} // namespace trace_event + +// TODO(ssid): remove these aliases after the tracing clients are moved to the +// new trace_event namespace. See crbug.com/451032. ETA: March 2015 +namespace debug { +using ::base::trace_event::TracedValue; } // namespace debug } // namespace base
diff --git a/content/renderer/scheduler/web_scheduler_impl.cc b/content/renderer/scheduler/web_scheduler_impl.cc index 1ca8a302..c7b6def 100644 --- a/content/renderer/scheduler/web_scheduler_impl.cc +++ b/content/renderer/scheduler/web_scheduler_impl.cc
@@ -5,6 +5,7 @@ #include "content/renderer/scheduler/web_scheduler_impl.h" #include "base/bind.h" +#include "base/single_thread_task_runner.h" #include "content/renderer/scheduler/renderer_scheduler.h" #include "third_party/WebKit/public/platform/WebTraceLocation.h" @@ -12,7 +13,8 @@ WebSchedulerImpl::WebSchedulerImpl(RendererScheduler* renderer_scheduler) : renderer_scheduler_(renderer_scheduler), - idle_task_runner_(renderer_scheduler_->IdleTaskRunner()) { + idle_task_runner_(renderer_scheduler_->IdleTaskRunner()), + loading_task_runner_(renderer_scheduler_->LoadingTaskRunner()) { } WebSchedulerImpl::~WebSchedulerImpl() { @@ -34,6 +36,7 @@ void WebSchedulerImpl::postIdleTask(const blink::WebTraceLocation& web_location, blink::WebScheduler::IdleTask* task) { + DCHECK(idle_task_runner_); scoped_ptr<blink::WebScheduler::IdleTask> scoped_task(task); tracked_objects::Location location(web_location.functionName(), web_location.fileName(), -1, nullptr); @@ -44,15 +47,18 @@ void WebSchedulerImpl::postLoadingTask( const blink::WebTraceLocation& web_location, blink::WebThread::Task* task) { + DCHECK(loading_task_runner_); scoped_ptr<blink::WebThread::Task> scoped_task(task); tracked_objects::Location location(web_location.functionName(), web_location.fileName(), -1, nullptr); - renderer_scheduler_->LoadingTaskRunner()->PostTask( + loading_task_runner_->PostTask( location, base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task))); } void WebSchedulerImpl::shutdown() { + idle_task_runner_ = nullptr; + loading_task_runner_ = nullptr; return renderer_scheduler_->Shutdown(); }
diff --git a/content/renderer/scheduler/web_scheduler_impl.h b/content/renderer/scheduler/web_scheduler_impl.h index 4f41002..4512d85 100644 --- a/content/renderer/scheduler/web_scheduler_impl.h +++ b/content/renderer/scheduler/web_scheduler_impl.h
@@ -12,6 +12,10 @@ #include "third_party/WebKit/public/platform/WebScheduler.h" #include "third_party/WebKit/public/platform/WebThread.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace content { class RendererScheduler; @@ -36,6 +40,7 @@ RendererScheduler* renderer_scheduler_; scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; }; } // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_context_client.cc b/content/renderer/service_worker/embedded_worker_context_client.cc index 958e8f1..050b996 100644 --- a/content/renderer/service_worker/embedded_worker_context_client.cc +++ b/content/renderer/service_worker/embedded_worker_context_client.cc
@@ -12,6 +12,7 @@ #include "base/pickle.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" #include "base/threading/thread_local.h" #include "base/trace_event/trace_event.h" #include "content/child/request_extra_data.h" @@ -20,10 +21,10 @@ #include "content/child/service_worker/service_worker_provider_context.h" #include "content/child/service_worker/service_worker_registration_handle_reference.h" #include "content/child/service_worker/web_service_worker_impl.h" +#include "content/child/service_worker/web_service_worker_provider_impl.h" #include "content/child/service_worker/web_service_worker_registration_impl.h" #include "content/child/thread_safe_sender.h" #include "content/child/worker_task_runner.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/devtools_messages.h" #include "content/common/service_worker/embedded_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" @@ -153,6 +154,13 @@ script_context_->GetClientDocuments(callbacks); } +void EmbeddedWorkerContextClient::openWindow( + const blink::WebURL& url, + blink::WebServiceWorkerClientCallbacks* callbacks) { + DCHECK(script_context_); + script_context_->OpenWindow(url, callbacks); +} + void EmbeddedWorkerContextClient::workerReadyForInspection() { Send(new EmbeddedWorkerHostMsg_WorkerReadyForInspection(embedded_worker_id_)); } @@ -170,9 +178,8 @@ void EmbeddedWorkerContextClient::workerContextStarted( blink::WebServiceWorkerContextProxy* proxy) { DCHECK(!worker_task_runner_.get()); - worker_task_runner_ = new WorkerThreadTaskRunner( - WorkerTaskRunner::Instance()->CurrentWorkerId()); DCHECK_NE(0, WorkerTaskRunner::Instance()->CurrentWorkerId()); + worker_task_runner_ = base::ThreadTaskRunnerHandle::Get(); // g_worker_client_tls.Pointer()->Get() could return NULL if this context // gets deleted before workerContextStarted() is called. DCHECK(g_worker_client_tls.Pointer()->Get() == NULL); @@ -362,6 +369,16 @@ return new WebServiceWorkerNetworkProviderImpl(); } +blink::WebServiceWorkerProvider* +EmbeddedWorkerContextClient::createServiceWorkerProvider() { + DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(provider_context_); + + // Blink is responsible for deleting the returned object. + return new WebServiceWorkerProviderImpl( + thread_safe_sender(), provider_context_.get()); +} + void EmbeddedWorkerContextClient::postMessageToClient( int client_id, const blink::WebString& message, @@ -381,7 +398,7 @@ } void EmbeddedWorkerContextClient::focus( - int client_id, blink::WebServiceWorkerClientFocusCallback* callback) { + int client_id, blink::WebServiceWorkerClientCallbacks* callback) { DCHECK(script_context_); script_context_->FocusClient(client_id, callback); }
diff --git a/content/renderer/service_worker/embedded_worker_context_client.h b/content/renderer/service_worker/embedded_worker_context_client.h index 9cf8595..1221f85a 100644 --- a/content/renderer/service_worker/embedded_worker_context_client.h +++ b/content/renderer/service_worker/embedded_worker_context_client.h
@@ -20,6 +20,7 @@ namespace blink { class WebDataSource; +class WebServiceWorkerProvider; } namespace content { @@ -29,9 +30,7 @@ class ThreadSafeSender; // This class provides access to/from an embedded worker's WorkerGlobalScope. -// All methods other than the constructor (it's created on the main thread) -// and createServiceWorkerNetworkProvider (also called on the main thread) -// are called on the worker thread. +// Unless otherwise noted, all methods are called on the worker thread. // // TODO(kinuko): Currently EW/SW separation is made a little hazily. // This should implement WebEmbeddedWorkerContextClient @@ -46,6 +45,7 @@ // new instance. static EmbeddedWorkerContextClient* ThreadSpecificInstance(); + // Called on the main thread. EmbeddedWorkerContextClient(int embedded_worker_id, int64 service_worker_version_id, const GURL& service_worker_scope, @@ -64,8 +64,13 @@ virtual blink::WebServiceWorkerCacheStorage* cacheStorage(); virtual void didPauseAfterDownload(); virtual void getClients(blink::WebServiceWorkerClientsCallbacks*); + virtual void openWindow(const blink::WebURL&, + blink::WebServiceWorkerClientCallbacks*); virtual void workerReadyForInspection(); + + // Called on the main thread. virtual void workerContextFailedToStart(); + virtual void workerContextStarted(blink::WebServiceWorkerContextProxy* proxy); virtual void didEvaluateWorkerScript(bool success); virtual void willDestroyWorkerContext(); @@ -98,8 +103,12 @@ virtual void didHandleSyncEvent(int request_id); virtual void didHandleCrossOriginConnectEvent(int request_id, bool accept_connection); + + // Called on the main thread. virtual blink::WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider(blink::WebDataSource* data_source); + virtual blink::WebServiceWorkerProvider* createServiceWorkerProvider(); + virtual void postMessageToClient( int client_id, const blink::WebString& message, @@ -109,7 +118,7 @@ const blink::WebString& message, blink::WebMessagePortChannelArray* channels); virtual void focus(int client_id, - blink::WebServiceWorkerClientFocusCallback*); + blink::WebServiceWorkerClientCallbacks*); virtual void skipWaiting( blink::WebServiceWorkerSkipWaitingCallbacks* callbacks); virtual void claim(blink::WebServiceWorkerClientsClaimCallbacks* callbacks);
diff --git a/content/renderer/service_worker/service_worker_script_context.cc b/content/renderer/service_worker/service_worker_script_context.cc index f68a0053..ef72a1ac 100644 --- a/content/renderer/service_worker/service_worker_script_context.cc +++ b/content/renderer/service_worker/service_worker_script_context.cc
@@ -17,11 +17,11 @@ #include "content/renderer/service_worker/embedded_worker_context_client.h" #include "ipc/ipc_message.h" #include "third_party/WebKit/public/platform/WebCrossOriginServiceWorkerClient.h" -#include "third_party/WebKit/public/platform/WebNotificationData.h" #include "third_party/WebKit/public/platform/WebReferrerPolicy.h" #include "third_party/WebKit/public/platform/WebServiceWorkerRequest.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h" #include "third_party/WebKit/public/web/WebServiceWorkerContextClient.h" #include "third_party/WebKit/public/web/WebServiceWorkerContextProxy.h" @@ -72,6 +72,21 @@ return static_cast<blink::WebURLRequest::FrameType>(frame_type); } +blink::WebServiceWorkerClientInfo +ToWebServiceWorkerClientInfo(const ServiceWorkerClientInfo& client_info) { + DCHECK(client_info.IsValid()); + + blink::WebServiceWorkerClientInfo web_client_info; + + web_client_info.clientID = client_info.client_id; + web_client_info.pageVisibilityState = client_info.page_visibility_state; + web_client_info.isFocused = client_info.is_focused; + web_client_info.url = client_info.url; + web_client_info.frameType = GetBlinkFrameType(client_info.frame_type); + + return web_client_info; +} + } // namespace ServiceWorkerScriptContext::ServiceWorkerScriptContext( @@ -103,6 +118,10 @@ OnCrossOriginMessageToWorker) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetClientDocuments, OnDidGetClientDocuments) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_OpenWindowResponse, + OnOpenWindowResponse) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_OpenWindowError, + OnOpenWindowError) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FocusClientResponse, OnFocusClientResponse) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidSkipWaiting, OnDidSkipWaiting) @@ -207,6 +226,13 @@ GetRoutingID(), request_id)); } +void ServiceWorkerScriptContext::OpenWindow( + const GURL& url, blink::WebServiceWorkerClientCallbacks* callbacks) { + DCHECK(callbacks); + int request_id = pending_client_callbacks_.Add(callbacks); + Send(new ServiceWorkerHostMsg_OpenWindow(GetRoutingID(), request_id, url)); +} + void ServiceWorkerScriptContext::PostMessageToDocument( int client_id, const base::string16& message, @@ -238,9 +264,9 @@ } void ServiceWorkerScriptContext::FocusClient( - int client_id, blink::WebServiceWorkerClientFocusCallback* callback) { + int client_id, blink::WebServiceWorkerClientCallbacks* callback) { DCHECK(callback); - int request_id = pending_focus_client_callbacks_.Add(callback); + int request_id = pending_client_callbacks_.Add(callback); Send(new ServiceWorkerHostMsg_FocusClient( GetRoutingID(), request_id, client_id)); } @@ -429,31 +455,76 @@ new blink::WebServiceWorkerClientsInfo); blink::WebVector<blink::WebServiceWorkerClientInfo> convertedClients( clients.size()); - for (size_t i = 0; i < clients.size(); ++i) { - convertedClients[i].clientID = clients[i].client_id; - convertedClients[i].pageVisibilityState = clients[i].page_visibility_state; - convertedClients[i].isFocused = clients[i].is_focused; - convertedClients[i].url = clients[i].url; - convertedClients[i].frameType = - static_cast<blink::WebURLRequest::FrameType>(clients[i].frame_type); - } + for (size_t i = 0; i < clients.size(); ++i) + convertedClients[i] = ToWebServiceWorkerClientInfo(clients[i]); info->clients.swap(convertedClients); callbacks->onSuccess(info.release()); pending_clients_callbacks_.Remove(request_id); } -void ServiceWorkerScriptContext::OnFocusClientResponse(int request_id, - bool result) { +void ServiceWorkerScriptContext::OnOpenWindowResponse( + int request_id, + const ServiceWorkerClientInfo& client) { + TRACE_EVENT0("ServiceWorker", + "ServiceWorkerScriptContext::OnOpenWindowResponse"); + blink::WebServiceWorkerClientCallbacks* callbacks = + pending_client_callbacks_.Lookup(request_id); + if (!callbacks) { + NOTREACHED() << "Got stray response: " << request_id; + return; + } + scoped_ptr<blink::WebServiceWorkerClientInfo> web_client; + if (!client.IsEmpty()) { + DCHECK(client.IsValid()); + web_client.reset(new blink::WebServiceWorkerClientInfo( + ToWebServiceWorkerClientInfo(client))); + } + callbacks->onSuccess(web_client.release()); + pending_client_callbacks_.Remove(request_id); +} + +void ServiceWorkerScriptContext::OnOpenWindowError(int request_id) { + TRACE_EVENT0("ServiceWorker", + "ServiceWorkerScriptContext::OnOpenWindowError"); + blink::WebServiceWorkerClientCallbacks* callbacks = + pending_client_callbacks_.Lookup(request_id); + if (!callbacks) { + NOTREACHED() << "Got stray response: " << request_id; + return; + } + scoped_ptr<blink::WebServiceWorkerError> error( + new blink::WebServiceWorkerError( + blink::WebServiceWorkerError::ErrorTypeUnknown, + "Something went wrong while trying to open the window.")); + callbacks->onError(error.release()); + pending_client_callbacks_.Remove(request_id); +} + +void ServiceWorkerScriptContext::OnFocusClientResponse( + int request_id, const ServiceWorkerClientInfo& client) { TRACE_EVENT0("ServiceWorker", "ServiceWorkerScriptContext::OnFocusClientResponse"); - blink::WebServiceWorkerClientFocusCallback* callback = - pending_focus_client_callbacks_.Lookup(request_id); + blink::WebServiceWorkerClientCallbacks* callback = + pending_client_callbacks_.Lookup(request_id); if (!callback) { NOTREACHED() << "Got stray response: " << request_id; return; } - callback->onSuccess(&result); - pending_focus_client_callbacks_.Remove(request_id); + if (!client.IsEmpty()) { + DCHECK(client.IsValid()); + scoped_ptr<blink::WebServiceWorkerClientInfo> web_client ( + new blink::WebServiceWorkerClientInfo( + ToWebServiceWorkerClientInfo(client))); + callback->onSuccess(web_client.release()); + } else { + scoped_ptr<blink::WebServiceWorkerError> error( + new blink::WebServiceWorkerError( + blink::WebServiceWorkerError::ErrorTypeNotFound, + "The WindowClient was not found.")); + callback->onError(error.release()); + } + + pending_client_callbacks_.Remove(request_id); } void ServiceWorkerScriptContext::OnDidSkipWaiting(int request_id) {
diff --git a/content/renderer/service_worker/service_worker_script_context.h b/content/renderer/service_worker/service_worker_script_context.h index 3259a4f2..d33e911 100644 --- a/content/renderer/service_worker/service_worker_script_context.h +++ b/content/renderer/service_worker/service_worker_script_context.h
@@ -19,7 +19,6 @@ #include "content/renderer/service_worker/service_worker_cache_storage_dispatcher.h" #include "third_party/WebKit/public/platform/WebGeofencingEventType.h" #include "third_party/WebKit/public/platform/WebMessagePortChannel.h" -#include "third_party/WebKit/public/platform/WebServiceWorkerClientFocusCallback.h" #include "third_party/WebKit/public/platform/WebServiceWorkerClientsClaimCallbacks.h" #include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h" #include "third_party/WebKit/public/platform/WebServiceWorkerError.h" @@ -42,6 +41,7 @@ class WebServiceWorkerRegistrationImpl; struct NavigatorConnectClient; struct PlatformNotificationData; +struct ServiceWorkerClientInfo; // TODO(kinuko): This should implement WebServiceWorkerContextClient // rather than having EmbeddedWorkerContextClient implement it. @@ -74,6 +74,8 @@ void DidHandleCrossOriginConnectEvent(int request_id, bool accept_connection); void GetClientDocuments( blink::WebServiceWorkerClientsCallbacks* callbacks); + void OpenWindow(const GURL& url, + blink::WebServiceWorkerClientCallbacks* callbacks); void PostMessageToDocument( int client_id, const base::string16& message, @@ -83,7 +85,7 @@ const base::string16& message, scoped_ptr<blink::WebMessagePortChannelArray> channels); void FocusClient(int client_id, - blink::WebServiceWorkerClientFocusCallback* callback); + blink::WebServiceWorkerClientCallbacks* callback); void SkipWaiting(blink::WebServiceWorkerSkipWaitingCallbacks* callbacks); void ClaimClients(blink::WebServiceWorkerClientsClaimCallbacks* callbacks); @@ -103,8 +105,8 @@ ClientsCallbacksMap; typedef IDMap<blink::WebServiceWorkerClientsClaimCallbacks, IDMapOwnPointer> ClaimClientsCallbacksMap; - typedef IDMap<blink::WebServiceWorkerClientFocusCallback, IDMapOwnPointer> - FocusClientCallbacksMap; + typedef IDMap<blink::WebServiceWorkerClientCallbacks, IDMapOwnPointer> + ClientCallbacksMap; typedef IDMap<blink::WebServiceWorkerSkipWaitingCallbacks, IDMapOwnPointer> SkipWaitingCallbacksMap; @@ -133,7 +135,11 @@ const std::vector<int>& new_routing_ids); void OnDidGetClientDocuments( int request_id, const std::vector<ServiceWorkerClientInfo>& clients); - void OnFocusClientResponse(int request_id, bool result); + void OnOpenWindowResponse(int request_id, + const ServiceWorkerClientInfo& client); + void OnOpenWindowError(int request_id); + void OnFocusClientResponse(int request_id, + const ServiceWorkerClientInfo& client); void OnDidSkipWaiting(int request_id); void OnDidClaimClients(int request_id); void OnClaimClientsError(int request_id, @@ -156,8 +162,8 @@ // Pending callbacks for GetClientDocuments(). ClientsCallbacksMap pending_clients_callbacks_; - // Pending callbacks for FocusClient(). - FocusClientCallbacksMap pending_focus_client_callbacks_; + // Pending callbacks for OpenWindow() and FocusClient(). + ClientCallbacksMap pending_client_callbacks_; // Pending callbacks for SkipWaiting(). SkipWaitingCallbacksMap pending_skip_waiting_callbacks_;
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index c1282aa..bfd8a85 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -259,6 +259,7 @@ "//third_party/WebKit/public:test_support", "//third_party/icu", "//ui/base", + "//ui/base/ime", "//ui/events:events_base", "//ui/gfx", "//ui/gfx/geometry",
diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java index e4194db..bb9a5d6 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java +++ b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java
@@ -99,6 +99,13 @@ } /** + * Get the ContentViewRenderView. + */ + public ContentViewRenderView getContentViewRenderView() { + return mContentViewRenderView; + } + + /** * Sets the startup URL for new shell windows. */ public void setStartupUrl(String url) {
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java index ee048ba..2d94b12 100644 --- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java +++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
@@ -73,6 +73,10 @@ mWindowAndroid = new ActivityWindowAndroid(this); mWindowAndroid.restoreInstanceState(savedInstanceState); mShellManager.setWindow(mWindowAndroid); + // Set up the animation placeholder to be the SurfaceView. This disables the + // SurfaceView's 'hole' clipping during animations that are notified to the window. + mWindowAndroid.setAnimationPlaceholderView( + mShellManager.getContentViewRenderView().getSurfaceView()); String startupUrl = getUrlFromIntent(getIntent()); if (!TextUtils.isEmpty(startupUrl)) {
diff --git a/content/shell/app/shell_crash_reporter_client.h b/content/shell/app/shell_crash_reporter_client.h index 4d783eb..5a211eb9 100644 --- a/content/shell/app/shell_crash_reporter_client.h +++ b/content/shell/app/shell_crash_reporter_client.h
@@ -40,7 +40,7 @@ #if defined(OS_ANDROID) // Returns the descriptor key of the android minidump global descriptor. - virtual int GetAndroidMinidumpDescriptor() override; + int GetAndroidMinidumpDescriptor() override; #endif bool EnableBreakpadForProcess(const std::string& process_type) override;
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.h b/content/shell/browser/layout_test/layout_test_notification_manager.h index e57da887..2adf39e8 100644 --- a/content/shell/browser/layout_test/layout_test_notification_manager.h +++ b/content/shell/browser/layout_test/layout_test_notification_manager.h
@@ -13,7 +13,7 @@ #include "base/synchronization/lock.h" #include "content/public/browser/platform_notification_service.h" #include "content/public/common/platform_notification_data.h" -#include "third_party/WebKit/public/platform/WebNotificationPermission.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h" #include "url/gurl.h" namespace content {
diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.h b/content/shell/browser/layout_test/layout_test_push_messaging_service.h index f4d6cf4..d0ed5f3b 100644 --- a/content/shell/browser/layout_test/layout_test_push_messaging_service.h +++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.h
@@ -10,7 +10,7 @@ #include "content/public/browser/push_messaging_service.h" #include "content/public/common/push_messaging_status.h" -#include "third_party/WebKit/public/platform/WebPushPermissionStatus.h" +#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" namespace content {
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index 1245315..c2cddf9 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -121,8 +121,7 @@ void LoadingStateChanged(WebContents* source, bool to_different_document) override; #if defined(OS_ANDROID) - virtual void LoadProgressChanged(WebContents* source, - double progress) override; + void LoadProgressChanged(WebContents* source, double progress) override; #endif void EnterFullscreenModeForTab(WebContents* web_contents, const GURL& origin) override;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index fce64075..9b8a2f45 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -10,6 +10,7 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "content/public/browser/page_navigator.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/storage_partition.h" @@ -302,6 +303,14 @@ return new ShellDevToolsManagerDelegate(browser_context()); } +WebContents* ShellContentBrowserClient::OpenURL(BrowserContext* browser_context, + const OpenURLParams& params) { + return Shell::CreateNewWindow(browser_context, + params.url, + nullptr, + gfx::Size())->web_contents(); +} + #if defined(OS_POSIX) && !defined(OS_MACOSX) void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line,
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 0bea257b..a2d8a9792 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -63,6 +63,9 @@ const GURL& new_url) override; DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; + WebContents* OpenURL(BrowserContext* browser_context, + const OpenURLParams& params) override; + #if defined(OS_POSIX) && !defined(OS_MACOSX) void GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line,
diff --git a/content/shell/browser/shell_devtools_manager_delegate.cc b/content/shell/browser/shell_devtools_manager_delegate.cc index d740326..2b52385e 100644 --- a/content/shell/browser/shell_devtools_manager_delegate.cc +++ b/content/shell/browser/shell_devtools_manager_delegate.cc
@@ -56,7 +56,7 @@ private: // DevToolsHttpHandler::ServerSocketFactory. - virtual scoped_ptr<net::ServerSocket> CreateForHttpServer() override { + scoped_ptr<net::ServerSocket> CreateForHttpServer() override { scoped_ptr<net::ServerSocket> socket( new net::UnixDomainServerSocket( base::Bind(&CanUserConnectToDevTools),
diff --git a/content/shell/renderer/test_runner/event_sender.cc b/content/shell/renderer/test_runner/event_sender.cc index e02fe0c..f4948b6 100644 --- a/content/shell/renderer/test_runner/event_sender.cc +++ b/content/shell/renderer/test_runner/event_sender.cc
@@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "content/public/common/page_zoom.h" #include "content/shell/renderer/test_runner/mock_spell_check.h" @@ -22,6 +23,7 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebPagePopup.h" #include "third_party/WebKit/public/web/WebView.h" +#include "ui/events/keycodes/dom4/keycode_converter.h" #include "ui/events/keycodes/keyboard_codes.h" #include "v8/include/v8.h" @@ -1269,52 +1271,75 @@ int code = 0; int text = 0; bool needs_shift_key_modifier = false; + std::string domString; if ("\n" == code_str) { generate_char = true; text = code = ui::VKEY_RETURN; + domString.assign("Enter"); } else if ("rightArrow" == code_str) { code = ui::VKEY_RIGHT; + domString.assign("ArrowRight"); } else if ("downArrow" == code_str) { code = ui::VKEY_DOWN; + domString.assign("ArrowDown"); } else if ("leftArrow" == code_str) { code = ui::VKEY_LEFT; + domString.assign("ArrowLeft"); } else if ("upArrow" == code_str) { code = ui::VKEY_UP; + domString.assign("ArrowUp"); } else if ("insert" == code_str) { code = ui::VKEY_INSERT; + domString.assign("Insert"); } else if ("delete" == code_str) { code = ui::VKEY_DELETE; + domString.assign("Delete"); } else if ("pageUp" == code_str) { code = ui::VKEY_PRIOR; + domString.assign("PageUp"); } else if ("pageDown" == code_str) { code = ui::VKEY_NEXT; + domString.assign("PageDown"); } else if ("home" == code_str) { code = ui::VKEY_HOME; + domString.assign("Home"); } else if ("end" == code_str) { code = ui::VKEY_END; + domString.assign("End"); } else if ("printScreen" == code_str) { code = ui::VKEY_SNAPSHOT; + domString.assign("PrintScreen"); } else if ("menu" == code_str) { code = ui::VKEY_APPS; + domString.assign("ContextMenu"); } else if ("leftControl" == code_str) { code = ui::VKEY_LCONTROL; + domString.assign("ControlLeft"); } else if ("rightControl" == code_str) { code = ui::VKEY_RCONTROL; + domString.assign("ControlRight"); } else if ("leftShift" == code_str) { code = ui::VKEY_LSHIFT; + domString.assign("ShiftLeft"); } else if ("rightShift" == code_str) { code = ui::VKEY_RSHIFT; + domString.assign("ShiftRight"); } else if ("leftAlt" == code_str) { code = ui::VKEY_LMENU; + domString.assign("AltLeft"); } else if ("rightAlt" == code_str) { code = ui::VKEY_RMENU; + domString.assign("AltRight"); } else if ("numLock" == code_str) { code = ui::VKEY_NUMLOCK; + domString.assign("NumLock"); } else if ("backspace" == code_str) { code = ui::VKEY_BACK; + domString.assign("Backspace"); } else if ("escape" == code_str) { code = ui::VKEY_ESCAPE; + domString.assign("Escape"); } else { // Compare the input string with the function-key names defined by the // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key @@ -1323,6 +1348,7 @@ std::string function_key_name = base::StringPrintf("F%d", i); if (function_key_name == code_str) { code = ui::VKEY_F1 + (i - 1); + domString = function_key_name; break; } } @@ -1334,6 +1360,17 @@ needs_shift_key_modifier = NeedsShiftModifier(code); if ((code & 0xFF) >= 'a' && (code & 0xFF) <= 'z') code -= 'a' - 'A'; + if ((code >= 'A' && code <= 'Z') || (code >= 'a' && code <= 'z')) { + domString.assign("Key"); + domString.push_back(base::ToUpperASCII(code)); + } else if (code >= '0' && code <= '9') { + domString.assign("Digit"); + domString.push_back(code); + } else if (code == ' ') { + domString.assign("Space"); + } else if (code == 9) { + domString.assign("Tab"); + } generate_char = true; } @@ -1352,6 +1389,8 @@ event_down.type = WebInputEvent::RawKeyDown; event_down.modifiers = modifiers; event_down.windowsKeyCode = code; + event_down.domCode = static_cast<int>( + ui::KeycodeConverter::CodeStringToDomCode(domString.c_str())); if (generate_char) { event_down.text[0] = text;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index e91d0d52..1512477b 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -34,6 +34,7 @@ "//testing/gtest", "//ui/accessibility:ax_gen", "//ui/base", + "//ui/base/ime", "//ui/base:test_support", "//ui/events:dom4_keycode_converter", "//ui/events:events_base", @@ -299,6 +300,7 @@ "//ui/accessibility", "//ui/accessibility:ax_gen", "//ui/base", + "//ui/base/ime", "//ui/gfx", "//ui/gfx/geometry", "//ui/gl",
diff --git a/content/test/browser_test_utils_browsertest.cc b/content/test/browser_test_utils_browsertest.cc index de64115f..15f65ae 100644 --- a/content/test/browser_test_utils_browsertest.cc +++ b/content/test/browser_test_utils_browsertest.cc
@@ -70,9 +70,8 @@ // hostname supplied in the URL and rewrite the URL. Build the // expected URL to ensure navigation was properly redirected. GURL::Replacements replace_host; - std::string foo_com("foo.com"); GURL expected_url(embedded_test_server()->GetURL("/title2.html")); - replace_host.SetHostStr(foo_com); + replace_host.SetHostStr("foo.com"); expected_url = expected_url.ReplaceComponents(replace_host); EXPECT_EQ(expected_url, observer.navigation_url());
diff --git a/content/test/data/accessibility/aria/aria-activedescendant-expected-mac.txt b/content/test/data/accessibility/aria/aria-activedescendant-expected-mac.txt index 14b25a3..71c3772 100644 --- a/content/test/data/accessibility/aria/aria-activedescendant-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-activedescendant-expected-mac.txt
@@ -1,3 +1,4 @@ +#<skip - need to rebaseline> AXWebArea AXGroup AXTitle='Inactive descendantActive descendantInactive descendant #2' AXGroup
diff --git a/content/test/fake_renderer_scheduler.cc b/content/test/fake_renderer_scheduler.cc index 2e20b7f..9c6d07e 100644 --- a/content/test/fake_renderer_scheduler.cc +++ b/content/test/fake_renderer_scheduler.cc
@@ -45,6 +45,10 @@ void FakeRendererScheduler::DidAnimateForInputOnCompositorThread() { } +bool FakeRendererScheduler::IsHighPriorityWorkAnticipated() { + return false; +} + bool FakeRendererScheduler::ShouldYieldForHighPriorityWork() { return false; }
diff --git a/content/test/fake_renderer_scheduler.h b/content/test/fake_renderer_scheduler.h index 8222314..1bcc31e 100644 --- a/content/test/fake_renderer_scheduler.h +++ b/content/test/fake_renderer_scheduler.h
@@ -24,6 +24,7 @@ void DidReceiveInputEventOnCompositorThread( blink::WebInputEvent::Type type) override; void DidAnimateForInputOnCompositorThread() override; + bool IsHighPriorityWorkAnticipated() override; bool ShouldYieldForHighPriorityWork() override; void Shutdown() override;
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc index b95ea89f..2d148878 100644 --- a/content/test/test_navigation_url_loader.cc +++ b/content/test/test_navigation_url_loader.cc
@@ -10,11 +10,9 @@ namespace content { TestNavigationURLLoader::TestNavigationURLLoader( - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, NavigationURLLoaderDelegate* delegate) - : common_params_(common_params), - request_info_(request_info.Pass()), + : request_info_(request_info.Pass()), delegate_(delegate), redirect_count_(0) { }
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h index 4dcc80fc..b598464 100644 --- a/content/test/test_navigation_url_loader.h +++ b/content/test/test_navigation_url_loader.h
@@ -28,14 +28,12 @@ : public NavigationURLLoader, public base::SupportsWeakPtr<TestNavigationURLLoader> { public: - TestNavigationURLLoader(const CommonNavigationParams& common_params, - scoped_ptr<NavigationRequestInfo> request_info, + TestNavigationURLLoader(scoped_ptr<NavigationRequestInfo> request_info, NavigationURLLoaderDelegate* delegate); // NavigationURLLoader implementation. void FollowRedirect() override; - const CommonNavigationParams& common_params() const { return common_params_; } NavigationRequestInfo* request_info() const { return request_info_.get(); } void CallOnRequestRedirected(const net::RedirectInfo& redirect_info, @@ -48,7 +46,6 @@ private: ~TestNavigationURLLoader() override; - CommonNavigationParams common_params_; scoped_ptr<NavigationRequestInfo> request_info_; NavigationURLLoaderDelegate* delegate_; int redirect_count_;
diff --git a/content/test/test_navigation_url_loader_factory.cc b/content/test/test_navigation_url_loader_factory.cc index 95eba54..9446df3 100644 --- a/content/test/test_navigation_url_loader_factory.cc +++ b/content/test/test_navigation_url_loader_factory.cc
@@ -20,12 +20,10 @@ scoped_ptr<NavigationURLLoader> TestNavigationURLLoaderFactory::CreateLoader( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate) { return scoped_ptr<NavigationURLLoader>(new TestNavigationURLLoader( - common_params, request_info.Pass(), delegate)); + request_info.Pass(), delegate)); } } // namespace content
diff --git a/content/test/test_navigation_url_loader_factory.h b/content/test/test_navigation_url_loader_factory.h index 14fbe1d..54f1f1f4 100644 --- a/content/test/test_navigation_url_loader_factory.h +++ b/content/test/test_navigation_url_loader_factory.h
@@ -27,9 +27,7 @@ scoped_ptr<NavigationURLLoader> CreateLoader( BrowserContext* browser_context, int64 frame_tree_node_id, - const CommonNavigationParams& common_params, scoped_ptr<NavigationRequestInfo> request_info, - ResourceRequestBody* request_body, NavigationURLLoaderDelegate* delegate) override; private:
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 3f72489..d629a9e 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -10,6 +10,7 @@ #include "content/browser/frame_host/navigator.h" #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_delegate.h" +#include "content/common/frame_messages.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/content_switches.h" #include "content/test/browser_side_navigation_test_utils.h" @@ -187,15 +188,14 @@ } void TestRenderFrameHost::SendBeginNavigationWithURL(const GURL& url) { - FrameHostMsg_BeginNavigation_Params begin_params; + BeginNavigationParams begin_params( + "GET", std::string(), net::LOAD_NORMAL, false); CommonNavigationParams common_params; - begin_params.method = "GET"; - begin_params.load_flags = net::LOAD_NORMAL; - begin_params.has_user_gesture = false; common_params.url = url; common_params.referrer = Referrer(GURL(), blink::WebReferrerPolicyDefault); common_params.transition = ui::PAGE_TRANSITION_LINK; - OnBeginNavigation(begin_params, common_params); + OnBeginNavigation(common_params, begin_params, + scoped_refptr<ResourceRequestBody>()); } void TestRenderFrameHost::DidDisownOpener() { @@ -226,7 +226,7 @@ // We may not have simulated the renderer response to the navigation request. // Do that now. if (request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE) - SendBeginNavigationWithURL(url); + SendBeforeUnloadACK(true); // We have already simulated the IO thread commit. Only the // DidCommitProvisionalLoad from the renderer is missing. @@ -241,4 +241,12 @@ url_loader->CallOnResponseStarted(response, MakeEmptyStream()); } +void TestRenderFrameHost::SendBeforeUnloadHandlersPresent(bool present) { + OnBeforeUnloadHandlersPresent(present); +} + +void TestRenderFrameHost::SendUnloadHandlersPresent(bool present) { + OnUnloadHandlersPresent(present); +} + } // namespace content
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index 227b5cf..78536c2 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -104,6 +104,12 @@ // interaction with the IO thread up until the response is ready to commit. void PrepareForCommit(const GURL& url); + // Simulate receiving a FrameHostMsg_BeforeUnloadHandlersPresent. + void SendBeforeUnloadHandlersPresent(bool present); + + // Simulate receiving a FrameHostMsg_UnloadHandlersPresent. + void SendUnloadHandlersPresent(bool present); + private: TestRenderFrameHostCreationObserver child_creation_observer_;
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index f71fc76..a7b7ce8 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -124,8 +124,8 @@ const NativeWebKeyboardEvent& event) override; #endif #if defined(OS_ANDROID) - virtual void LockCompositingSurface() override {} - virtual void UnlockCompositingSurface() override {} + void LockCompositingSurface() override {} + void UnlockCompositingSurface() override {} #endif void GetScreenInfo(blink::WebScreenInfo* results) override {} gfx::Rect GetBoundsInRootWindow() override;
diff --git a/content/test/web_layer_tree_view_impl_for_testing.cc b/content/test/web_layer_tree_view_impl_for_testing.cc index ae83d34..fb77dc1 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.cc +++ b/content/test/web_layer_tree_view_impl_for_testing.cc
@@ -141,8 +141,8 @@ } void WebLayerTreeViewImplForTesting::ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) {
diff --git a/content/test/web_layer_tree_view_impl_for_testing.h b/content/test/web_layer_tree_view_impl_for_testing.h index 904c985..3b21238b 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.h +++ b/content/test/web_layer_tree_view_impl_for_testing.h
@@ -69,8 +69,8 @@ void DidBeginMainFrame() override {} void BeginMainFrame(const cc::BeginFrameArgs& args) override {} void Layout() override; - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override;
diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc index 1be9918..4c6e7212 100644 --- a/content/utility/utility_main.cc +++ b/content/utility/utility_main.cc
@@ -46,6 +46,12 @@ parameters.sandbox_info->target_services; if (!target_services) return false; +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + if (!LoadLibraryA("dbghelp.dll")) + return false; +#endif target_services->LowerToken(); } #endif
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index 8f89580..d1bd8cc 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc
@@ -39,8 +39,10 @@ #include "content/public/common/zygote_fork_delegate_linux.h" #include "content/zygote/zygote_linux.h" #include "crypto/nss_util.h" +#include "sandbox/linux/services/credentials.h" #include "sandbox/linux/services/init_process_reaper.h" #include "sandbox/linux/services/libc_urandom_override.h" +#include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/suid/client/setuid_sandbox_client.h" #include "third_party/icu/source/i18n/unicode/timezone.h" #include "third_party/skia/include/ports/SkFontConfigInterface.h" @@ -399,6 +401,24 @@ return true; } +static bool MaybeSetProcessNonDumpable() { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kAllowSandboxDebugging)) { + // If sandbox debugging is allowed, install a handler for sandbox-related + // crash testing. + InstallSandboxCrashTestHandler(); + return true; + } + + if (prctl(PR_SET_DUMPABLE, 0) != 0) { + PLOG(ERROR) << "Failed to set non-dumpable flag"; + return false; + } + + return prctl(PR_GET_DUMPABLE) == 0; +} + // Enter the setuid sandbox. This requires the current process to have been // created through the setuid sandbox. static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, @@ -433,41 +453,27 @@ CHECK(CreateInitProcessReaper(post_fork_parent_callback)); } -#if !defined(OS_OPENBSD) - // Previously, we required that the binary be non-readable. This causes the - // kernel to mark the process as non-dumpable at startup. The thinking was - // that, although we were putting the renderers into a PID namespace (with - // the SUID sandbox), they would nonetheless be in the /same/ PID - // namespace. So they could ptrace each other unless they were non-dumpable. - // - // If the binary was readable, then there would be a window between process - // startup and the point where we set the non-dumpable flag in which a - // compromised renderer could ptrace attach. - // - // However, now that we have a zygote model, only the (trusted) zygote - // exists at this point and we can set the non-dumpable flag which is - // inherited by all our renderer children. - // - // Note: a non-dumpable process can't be debugged. To debug sandbox-related - // issues, one can specify --allow-sandbox-debugging to let the process be - // dumpable. - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (!command_line.HasSwitch(switches::kAllowSandboxDebugging)) { - prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); - if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { - LOG(ERROR) << "Failed to set non-dumpable flag"; - return false; - } - } else { - // If sandbox debugging is allowed, install a handler for sandbox-related - // crash testing. - InstallSandboxCrashTestHandler(); + CHECK(MaybeSetProcessNonDumpable()); + return true; +} + +static void EnterNamespaceSandbox(base::Closure* post_fork_parent_callback) { + pid_t pid = getpid(); + if (sandbox::NamespaceSandbox::InNewPidNamespace()) { + CHECK_EQ(1, pid); } -#endif + CHECK(sandbox::Credentials::MoveToNewUserNS()); + CHECK(sandbox::Credentials::DropFileSystemAccess()); + CHECK(sandbox::Credentials::DropAllCapabilities()); - return true; + // This needs to happen after moving to a new user NS, since doing so involves + // writing the UID/GID map. + CHECK(MaybeSetProcessNonDumpable()); + + if (pid == 1) { + CHECK(CreateInitProcessReaper(post_fork_parent_callback)); + } } #if defined(ADDRESS_SANITIZER) @@ -526,10 +532,8 @@ #endif // defined(ADDRESS_SANITIZER) -// If |is_suid_sandbox_child|, then make sure that the setuid sandbox is -// engaged. static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, - bool is_suid_sandbox_child, + const bool using_layer1_sandbox, base::Closure* post_fork_parent_callback) { DCHECK(linux_sandbox); @@ -542,10 +546,13 @@ sandbox::SetuidSandboxClient* setuid_sandbox = linux_sandbox->setuid_sandbox_client(); - - if (is_suid_sandbox_child) { + if (setuid_sandbox->IsSuidSandboxChild()) { CHECK(EnterSuidSandbox(setuid_sandbox, post_fork_parent_callback)) << "Failed to enter setuid sandbox"; + } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) { + EnterNamespaceSandbox(post_fork_parent_callback); + } else { + CHECK(!using_layer1_sandbox); } } @@ -583,9 +590,12 @@ linux_sandbox->PreinitializeSandbox(); } - const bool must_enable_setuid_sandbox = + const bool using_setuid_sandbox = linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); - if (must_enable_setuid_sandbox) { + const bool using_namespace_sandbox = + sandbox::NamespaceSandbox::InNewUserNamespace(); + + if (using_setuid_sandbox) { linux_sandbox->setuid_sandbox_client()->CloseDummyFile(); // Let the ZygoteHost know we're booting up. @@ -597,10 +607,10 @@ VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size() << " fork delegates"; - for (ScopedVector<ZygoteForkDelegate>::iterator i = fork_delegates.begin(); - i != fork_delegates.end(); - ++i) { - (*i)->Init(GetSandboxFD(), must_enable_setuid_sandbox); + const bool using_layer1_sandbox = + using_setuid_sandbox || using_namespace_sandbox; + for (ZygoteForkDelegate* fork_delegate : fork_delegates) { + fork_delegate->Init(GetSandboxFD(), using_layer1_sandbox); } const std::vector<int> sandbox_fds_to_close_post_fork = @@ -613,7 +623,7 @@ base::Bind(&CloseFds, fds_to_close_post_fork); // Turn on the first layer of the sandbox if the configuration warrants it. - EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox, + EnterLayerOneSandbox(linux_sandbox, using_layer1_sandbox, &post_fork_parent_callback); // Extra children and file descriptors created that the Zygote must have @@ -638,7 +648,7 @@ int sandbox_flags = linux_sandbox->GetStatus(); bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; - CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); + CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged); Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, extra_fds);
diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc index fca6a1dc..b4549c72 100644 --- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
@@ -1090,15 +1090,14 @@ GetHeartRateMeasurementPath().value()); ASSERT_TRUE(characteristic); EXPECT_EQ(1U, characteristic->GetDescriptors().size()); + EXPECT_FALSE(characteristic->IsNotifying()); BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0]; EXPECT_FALSE(descriptor->IsLocal()); EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(), descriptor->GetUUID()); - std::vector<uint8> desc_value; - desc_value.push_back(1); - desc_value.push_back(0); + std::vector<uint8_t> desc_value = {0x00, 0x00}; /* The cached value will be empty until the first read request */ EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); @@ -1139,7 +1138,7 @@ EXPECT_EQ(0, observer.gatt_service_changed_count_); EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_); - // Read new value. + // Read value. The value should remain unchanged. descriptor->ReadRemoteDescriptor( base::Bind(&BluetoothGattChromeOSTest::ValueCallback, base::Unretained(this)), @@ -1150,6 +1149,32 @@ EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); EXPECT_EQ(0, observer.gatt_service_changed_count_); + EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_); + + // Start notifications on the descriptor's characteristic. The descriptor + // value should change. + characteristic->StartNotifySession( + base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, + base::Unretained(this)), + base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback, + base::Unretained(this))); + base::MessageLoop::current()->Run(); + EXPECT_EQ(3, success_callback_count_); + EXPECT_EQ(1, error_callback_count_); + EXPECT_EQ(1U, update_sessions_.size()); + EXPECT_TRUE(characteristic->IsNotifying()); + + // Read the new descriptor value. We should receive a value updated event. + descriptor->ReadRemoteDescriptor( + base::Bind(&BluetoothGattChromeOSTest::ValueCallback, + base::Unretained(this)), + base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback, + base::Unretained(this))); + EXPECT_EQ(4, success_callback_count_); + EXPECT_EQ(1, error_callback_count_); + EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); + EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); + EXPECT_EQ(0, observer.gatt_service_changed_count_); EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count_); }
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc index 13a70ae..5be8c788 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
@@ -12,6 +12,7 @@ #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h" +#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -43,8 +44,6 @@ weak_ptr_factory_(this) { VLOG(1) << "Creating remote GATT characteristic with identifier: " << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()-> - AddObserver(this); DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()-> AddObserver(this); @@ -61,8 +60,6 @@ ~BluetoothRemoteGattCharacteristicChromeOS() { DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()-> RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()-> - RemoveObserver(this); // Clean up all the descriptors. There isn't much point in notifying service // observers for each descriptor that gets removed, so just delete them. @@ -97,7 +94,14 @@ const std::vector<uint8>& BluetoothRemoteGattCharacteristicChromeOS::GetValue() const { - return cached_value_; + BluetoothGattCharacteristicClient::Properties* properties = + DBusThreadManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->GetProperties(object_path_); + + DCHECK(properties); + + return properties->value.value(); } device::BluetoothGattService* @@ -198,13 +202,9 @@ << "."; DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->ReadValue( - object_path_, - base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess, - weak_ptr_factory_.GetWeakPtr(), - callback), + object_path_, callback, base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic( @@ -315,20 +315,6 @@ callback)); } -void BluetoothRemoteGattCharacteristicChromeOS::GattCharacteristicValueUpdated( - const dbus::ObjectPath& object_path, - const std::vector<uint8>& value) { - if (object_path != object_path_) - return; - - cached_value_ = value; - - VLOG(1) << "GATT characteristic value has changed: " << object_path.value() - << ": " << value; - DCHECK(service_); - service_->NotifyCharacteristicValueChanged(this, value); -} - void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded( const dbus::ObjectPath& object_path) { if (descriptors_.find(object_path) != descriptors_.end()) { @@ -380,16 +366,28 @@ delete descriptor; } -void BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess( - const ValueCallback& callback, - const std::vector<uint8>& value) { - VLOG(1) << "Characteristic value read: " << value; - cached_value_ = value; +void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + DescriptorMap::iterator iter = descriptors_.find(object_path); + if (iter == descriptors_.end()) { + VLOG(2) << "Unknown descriptor removed: " << object_path.value(); + return; + } + + BluetoothGattDescriptorClient::Properties* properties = + DBusThreadManager::Get() + ->GetBluetoothGattDescriptorClient() + ->GetProperties(object_path); + + DCHECK(properties); + + if (property_name != properties->value.name()) + return; DCHECK(service_); - service_->NotifyCharacteristicValueChanged(this, cached_value_); - - callback.Run(value); + service_->NotifyDescriptorValueChanged(this, iter->second, + properties->value.value()); } void BluetoothRemoteGattCharacteristicChromeOS::OnError(
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h index 12de00ec..077aff1 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
@@ -12,7 +12,6 @@ #include <vector> #include "base/memory/weak_ptr.h" -#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h" #include "chromeos/dbus/bluetooth_gatt_descriptor_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_gatt_characteristic.h" @@ -35,7 +34,6 @@ // platform. class BluetoothRemoteGattCharacteristicChromeOS : public device::BluetoothGattCharacteristic, - public BluetoothGattCharacteristicClient::Observer, public BluetoothGattDescriptorClient::Observer { public: // device::BluetoothGattCharacteristic overrides. @@ -77,18 +75,11 @@ const dbus::ObjectPath& object_path); ~BluetoothRemoteGattCharacteristicChromeOS() override; - // BluetoothGattCharacteristicClient::Observer overrides. - void GattCharacteristicValueUpdated(const dbus::ObjectPath& object_path, - const std::vector<uint8>& value) override; - // BluetoothGattDescriptorClient::Observer overrides. void GattDescriptorAdded(const dbus::ObjectPath& object_path) override; void GattDescriptorRemoved(const dbus::ObjectPath& object_path) override; - - // Called by dbus:: on successful completion of a request to read - // the characteristic value. - void OnValueSuccess(const ValueCallback& callback, - const std::vector<uint8>& value); + void GattDescriptorPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) override; // Called by dbus:: on unsuccessful completion of a request to read or write // the characteristic value. @@ -125,10 +116,6 @@ // The GATT service this GATT characteristic belongs to. BluetoothRemoteGattServiceChromeOS* service_; - // The cached characteristic value based on the most recent read or - // notification. - std::vector<uint8> cached_value_; - // The total number of currently active value update sessions. size_t num_notify_sessions_;
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc index 82a7f66..da38566 100644 --- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
@@ -60,7 +60,14 @@ const std::vector<uint8>& BluetoothRemoteGattDescriptorChromeOS::GetValue() const { - return cached_value_; + BluetoothGattDescriptorClient::Properties* properties = + DBusThreadManager::Get() + ->GetBluetoothGattDescriptorClient() + ->GetProperties(object_path_); + + DCHECK(properties); + + return properties->value.value(); } device::BluetoothGattCharacteristic* @@ -83,13 +90,9 @@ << GetUUID().canonical_value(); DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue( - object_path_, - base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess, - weak_ptr_factory_.GetWeakPtr(), - callback), + object_path_, callback, base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor( @@ -110,21 +113,6 @@ error_callback)); } -void BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess( - const ValueCallback& callback, - const std::vector<uint8>& value) { - VLOG(1) << "Descriptor value read: " << value; - cached_value_ = value; - - DCHECK(characteristic_); - BluetoothRemoteGattServiceChromeOS* service = - static_cast<BluetoothRemoteGattServiceChromeOS*>( - characteristic_->GetService()); - DCHECK(service); - service->NotifyDescriptorValueChanged(characteristic_, this, value); - callback.Run(value); -} - void BluetoothRemoteGattDescriptorChromeOS::OnError( const ErrorCallback& error_callback, const std::string& error_name,
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h index c2deed5..b32dd87 100644 --- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h +++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h
@@ -54,11 +54,6 @@ const dbus::ObjectPath& object_path); ~BluetoothRemoteGattDescriptorChromeOS() override; - // Called by dbus:: on successful completion of a request to read - // the descriptor value. - void OnValueSuccess(const ValueCallback& callback, - const std::vector<uint8>& value); - // Called by dbus:: on unsuccessful completion of a request to read or write // the descriptor value. void OnError(const ErrorCallback& error_callback, @@ -71,9 +66,6 @@ // The GATT characteristic this descriptor belongs to. BluetoothRemoteGattCharacteristicChromeOS* characteristic_; - // The cached characteristic value based on the most recent read request. - std::vector<uint8> cached_value_; - // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<BluetoothRemoteGattDescriptorChromeOS> weak_ptr_factory_;
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc index 8657abd..bd243d8 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
@@ -195,14 +195,6 @@ adapter_->NotifyGattServiceChanged(this); } -void BluetoothRemoteGattServiceChromeOS::NotifyCharacteristicValueChanged( - BluetoothRemoteGattCharacteristicChromeOS* characteristic, - const std::vector<uint8>& value) { - DCHECK(characteristic->GetService() == this); - DCHECK(adapter_); - adapter_->NotifyGattCharacteristicValueChanged(characteristic, value); -} - void BluetoothRemoteGattServiceChromeOS::NotifyDescriptorAddedOrRemoved( BluetoothRemoteGattCharacteristicChromeOS* characteristic, BluetoothRemoteGattDescriptorChromeOS* descriptor, @@ -311,7 +303,8 @@ void BluetoothRemoteGattServiceChromeOS::GattCharacteristicPropertyChanged( const dbus::ObjectPath& object_path, const std::string& property_name) { - if (characteristics_.find(object_path) == characteristics_.end()) { + CharacteristicMap::iterator iter = characteristics_.find(object_path); + if (iter == characteristics_.end()) { VLOG(3) << "Properties of unknown characteristic changed"; return; } @@ -324,11 +317,15 @@ BluetoothGattCharacteristicClient::Properties* properties = DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()-> GetProperties(object_path); - DCHECK(properties); - if (property_name != properties->flags.name()) - return; - NotifyServiceChanged(); + DCHECK(properties); + DCHECK(adapter_); + + if (property_name == properties->flags.name()) + NotifyServiceChanged(); + else if (property_name == properties->value.name()) + adapter_->NotifyGattCharacteristicValueChanged(iter->second, + properties->value.value()); } } // namespace chromeos
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h index a0373ae3..6694553 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h +++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
@@ -74,14 +74,6 @@ // service observers when characteristic descriptors get added and removed. void NotifyServiceChanged(); - // Notifies its observers that the value of a characteristic has changed. - // Called by BluetoothRemoteGattCharacteristicChromeOS instances to notify - // service observers when their cached value is updated after a successful - // read request or when a "ValueUpdated" signal is received. - void NotifyCharacteristicValueChanged( - BluetoothRemoteGattCharacteristicChromeOS* characteristic, - const std::vector<uint8>& value); - // Notifies its observers that a descriptor |descriptor| belonging to // characteristic |characteristic| has been added or removed. This is used // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service @@ -94,8 +86,8 @@ bool added); // Notifies its observers that the value of a descriptor has changed. Called - // by BluetoothRemoteGattDescriptorChromeOS instances to notify service - // observers when their cached value gets updated after a read request. + // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service + // observers. void NotifyDescriptorValueChanged( BluetoothRemoteGattCharacteristicChromeOS* characteristic, BluetoothRemoteGattDescriptorChromeOS* descriptor,
diff --git a/device/hid/hid_connection_win.cc b/device/hid/hid_connection_win.cc index a0c8a50..b453c2f 100644 --- a/device/hid/hid_connection_win.cc +++ b/device/hid/hid_connection_win.cc
@@ -91,7 +91,8 @@ void PendingHidTransfer::OnObjectSignaled(HANDLE event_handle) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("PendingHidTransfer_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 PendingHidTransfer::OnObjectSignaled")); callback_.Run(this, true); Release();
diff --git a/device/serial/data_receiver.cc b/device/serial/data_receiver.cc index fdc23caa..2f238e3 100644 --- a/device/serial/data_receiver.cc +++ b/device/serial/data_receiver.cc
@@ -107,16 +107,19 @@ bool dispatched; }; -DataReceiver::DataReceiver(mojo::InterfacePtr<serial::DataSource> source, - uint32_t buffer_size, - int32_t fatal_error_value) +DataReceiver::DataReceiver( + mojo::InterfacePtr<serial::DataSource> source, + mojo::InterfaceRequest<serial::DataSourceClient> client, + uint32_t buffer_size, + int32_t fatal_error_value) : source_(source.Pass()), + client_(this, client.Pass()), fatal_error_value_(fatal_error_value), shut_down_(false), weak_factory_(this) { - source_.set_client(this); source_.set_error_handler(this); source_->Init(buffer_size); + client_.set_error_handler(this); } bool DataReceiver::Receive(const ReceiveDataCallback& callback,
diff --git a/device/serial/data_receiver.h b/device/serial/data_receiver.h index 942bb5c..95be6402 100644 --- a/device/serial/data_receiver.h +++ b/device/serial/data_receiver.h
@@ -29,6 +29,7 @@ // size of |buffer_size|, with connection errors reported as // |fatal_error_value|. DataReceiver(mojo::InterfacePtr<serial::DataSource> source, + mojo::InterfaceRequest<serial::DataSourceClient> client, uint32_t buffer_size, int32_t fatal_error_value); @@ -72,6 +73,7 @@ // The control connection to the data source. mojo::InterfacePtr<serial::DataSource> source_; + mojo::Binding<serial::DataSourceClient> client_; // The error value to report in the event of a fatal error. const int32_t fatal_error_value_;
diff --git a/device/serial/data_sender.cc b/device/serial/data_sender.cc index 18b1a43e..dbd17760 100644 --- a/device/serial/data_sender.cc +++ b/device/serial/data_sender.cc
@@ -17,30 +17,21 @@ PendingSend(const base::StringPiece& data, const DataSentCallback& callback, const SendErrorCallback& error_callback, - int32_t fatal_error_value); - - // Invoked to report that |num_bytes| of data have been sent. Subtracts the - // number of bytes that were part of this send from |num_bytes|. Returns - // whether this send has been completed. If this send has been completed, this - // calls |callback_|. - bool ReportBytesSent(uint32_t* num_bytes); - - // Invoked to report that |num_bytes| of data have been sent and then an - // error, |error| was encountered. Subtracts the number of bytes that were - // part of this send from |num_bytes|. If this send was not completed before - // the error, this calls |error_callback_| to report the error. Otherwise, - // this calls |callback_|. Returns the number of bytes sent but not acked. - uint32_t ReportBytesSentAndError(uint32_t* num_bytes, int32_t error); + DataSender* sender); // Reports |fatal_error_value_| to |receive_error_callback_|. void DispatchFatalError(); // Attempts to send any data not yet sent to |sink|. - bool SendData(serial::DataSink* sink, uint32_t* available_buffer_size); + void SendData(); private: - // Invoked to update |bytes_acked_| and |num_bytes|. - void ReportBytesSentInternal(uint32_t* num_bytes); + // Invoked to report that |num_bytes| of data have been sent and then an + // error, |error| was encountered. Subtracts the number of bytes that were + // part of this send from |num_bytes|. If this send was not completed before + // the error, this calls |error_callback_| to report the error. Otherwise, + // this calls |callback_|. Returns the number of bytes sent but not acked. + void OnDataSent(uint32_t num_bytes, int32_t error); // The data to send. const base::StringPiece data_; @@ -51,14 +42,8 @@ // The callback to report errors. const SendErrorCallback error_callback_; - // The error value to report when DispatchFatalError() is called. - const int32_t fatal_error_value_; - - // The number of bytes sent to the DataSink. - uint32_t bytes_sent_; - - // The number of bytes acked. - uint32_t bytes_acked_; + // The DataSender that owns this PendingSend. + DataSender* sender_; }; DataSender::DataSender(mojo::InterfacePtr<serial::DataSink> sink, @@ -66,11 +51,8 @@ int32_t fatal_error_value) : sink_(sink.Pass()), fatal_error_value_(fatal_error_value), - available_buffer_capacity_(buffer_size), shut_down_(false) { sink_.set_error_handler(this); - sink_.set_client(this); - sink_->Init(buffer_size); } DataSender::~DataSender() { @@ -84,9 +66,10 @@ if (!pending_cancel_.is_null() || shut_down_) return false; - pending_sends_.push(linked_ptr<PendingSend>( - new PendingSend(data, callback, error_callback, fatal_error_value_))); - SendInternal(); + linked_ptr<PendingSend> pending_send( + new PendingSend(data, callback, error_callback, this)); + pending_send->SendData(); + sends_awaiting_ack_.push(pending_send); return true; } @@ -94,7 +77,7 @@ DCHECK(!callback.is_null()); if (!pending_cancel_.is_null() || shut_down_) return false; - if (pending_sends_.empty() && sends_awaiting_ack_.empty()) { + if (sends_awaiting_ack_.empty()) { base::MessageLoop::current()->PostTask(FROM_HERE, callback); return true; } @@ -104,52 +87,25 @@ return true; } -void DataSender::ReportBytesSent(uint32_t bytes_sent) { +void DataSender::SendComplete() { if (shut_down_) return; - available_buffer_capacity_ += bytes_sent; - while (bytes_sent != 0 && !sends_awaiting_ack_.empty() && - sends_awaiting_ack_.front()->ReportBytesSent(&bytes_sent)) { - sends_awaiting_ack_.pop(); - } - if (bytes_sent > 0 && !pending_sends_.empty()) { - bool finished = pending_sends_.front()->ReportBytesSent(&bytes_sent); - DCHECK(!finished); - if (finished) { - ShutDown(); - return; - } - } - if (bytes_sent != 0) { - ShutDown(); - return; - } - if (pending_sends_.empty() && sends_awaiting_ack_.empty()) + DCHECK(!sends_awaiting_ack_.empty()); + sends_awaiting_ack_.pop(); + if (sends_awaiting_ack_.empty()) RunCancelCallback(); - SendInternal(); } -void DataSender::ReportBytesSentAndError( - uint32_t bytes_sent, - int32_t error, - const mojo::Callback<void()>& callback) { +void DataSender::SendFailed(int32_t error) { if (shut_down_) return; - available_buffer_capacity_ += bytes_sent; - while (!sends_awaiting_ack_.empty()) { - available_buffer_capacity_ += - sends_awaiting_ack_.front()->ReportBytesSentAndError(&bytes_sent, - error); - sends_awaiting_ack_.pop(); - } - while (!pending_sends_.empty()) { - available_buffer_capacity_ += - pending_sends_.front()->ReportBytesSentAndError(&bytes_sent, error); - pending_sends_.pop(); - } - callback.Run(); + DCHECK(!sends_awaiting_ack_.empty()); + sends_awaiting_ack_.pop(); + if (!sends_awaiting_ack_.empty()) + return; + sink_->ClearError(); RunCancelCallback(); } @@ -157,18 +113,8 @@ ShutDown(); } -void DataSender::SendInternal() { - while (!pending_sends_.empty() && available_buffer_capacity_) { - if (pending_sends_.front()->SendData(sink_.get(), - &available_buffer_capacity_)) { - sends_awaiting_ack_.push(pending_sends_.front()); - pending_sends_.pop(); - } - } -} - void DataSender::RunCancelCallback() { - DCHECK(pending_sends_.empty() && sends_awaiting_ack_.empty()); + DCHECK(sends_awaiting_ack_.empty()); if (pending_cancel_.is_null()) return; @@ -179,10 +125,6 @@ void DataSender::ShutDown() { shut_down_ = true; - while (!pending_sends_.empty()) { - pending_sends_.front()->DispatchFatalError(); - pending_sends_.pop(); - } while (!sends_awaiting_ack_.empty()) { sends_awaiting_ack_.front()->DispatchFatalError(); sends_awaiting_ack_.pop(); @@ -193,64 +135,38 @@ DataSender::PendingSend::PendingSend(const base::StringPiece& data, const DataSentCallback& callback, const SendErrorCallback& error_callback, - int32_t fatal_error_value) + DataSender* sender) : data_(data), callback_(callback), error_callback_(error_callback), - fatal_error_value_(fatal_error_value), - bytes_sent_(0), - bytes_acked_(0) { + sender_(sender) { } -bool DataSender::PendingSend::ReportBytesSent(uint32_t* num_bytes) { - ReportBytesSentInternal(num_bytes); - if (bytes_acked_ < data_.size()) - return false; - - base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(callback_, bytes_acked_)); - return true; -} - -uint32_t DataSender::PendingSend::ReportBytesSentAndError(uint32_t* num_bytes, - int32_t error) { - ReportBytesSentInternal(num_bytes); - if (*num_bytes > 0) { +void DataSender::PendingSend::OnDataSent(uint32_t num_bytes, int32_t error) { + if (error) { + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(error_callback_, num_bytes, error)); + sender_->SendFailed(error); + } else { + DCHECK(num_bytes == data_.size()); base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(callback_, bytes_acked_)); - return 0; + base::Bind(callback_, num_bytes)); + sender_->SendComplete(); } - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(error_callback_, bytes_acked_, error)); - return bytes_sent_ - bytes_acked_; } void DataSender::PendingSend::DispatchFatalError() { base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(error_callback_, 0, fatal_error_value_)); + FROM_HERE, base::Bind(error_callback_, 0, sender_->fatal_error_value_)); } -bool DataSender::PendingSend::SendData(serial::DataSink* sink, - uint32_t* available_buffer_size) { - uint32_t num_bytes_to_send = - std::min(static_cast<uint32_t>(data_.size() - bytes_sent_), - *available_buffer_size); +void DataSender::PendingSend::SendData() { + uint32_t num_bytes_to_send = static_cast<uint32_t>(data_.size()); mojo::Array<uint8_t> bytes(num_bytes_to_send); - memcpy(&bytes[0], data_.data() + bytes_sent_, num_bytes_to_send); - bytes_sent_ += num_bytes_to_send; - *available_buffer_size -= num_bytes_to_send; - sink->OnData(bytes.Pass()); - return bytes_sent_ == data_.size(); -} - -void DataSender::PendingSend::ReportBytesSentInternal(uint32_t* num_bytes) { - bytes_acked_ += *num_bytes; - if (bytes_acked_ > bytes_sent_) { - *num_bytes = bytes_acked_ - bytes_sent_; - bytes_acked_ = bytes_sent_; - } else { - *num_bytes = 0; - } + memcpy(&bytes[0], data_.data(), num_bytes_to_send); + sender_->sink_->OnData( + bytes.Pass(), + base::Bind(&DataSender::PendingSend::OnDataSent, base::Unretained(this))); } } // namespace device
diff --git a/device/serial/data_sender.h b/device/serial/data_sender.h index f4db8bc..93b0644 100644 --- a/device/serial/data_sender.h +++ b/device/serial/data_sender.h
@@ -17,7 +17,7 @@ namespace device { // A DataSender sends data to a DataSink. -class DataSender : public serial::DataSinkClient, public mojo::ErrorHandler { +class DataSender : public mojo::ErrorHandler { public: typedef base::Callback<void(uint32_t bytes_sent)> DataSentCallback; typedef base::Callback<void(uint32_t bytes_sent, int32_t error)> @@ -49,21 +49,15 @@ private: class PendingSend; - // serial::DataSinkClient overrides. - void ReportBytesSent(uint32_t bytes_sent) override; - void ReportBytesSentAndError(uint32_t bytes_sent, - int32_t error, - const mojo::Callback<void()>& callback) override; + // Invoked when a PendingSend completes. + void SendComplete(); + + // Invoked when a PendingSend fails with |error|. + void SendFailed(int32_t error); // mojo::ErrorHandler override. void OnConnectionError() override; - // Sends up to |available_buffer_capacity_| bytes of data from - // |pending_sends_| to |sink_|. When a PendingSend in |pending_sends_| has - // been fully copied transmitted to |sink_|, it moves to - // |sends_awaiting_ack_|. - void SendInternal(); - // Dispatches a cancel callback if one is pending. void RunCancelCallback(); @@ -77,20 +71,14 @@ // The error value to report in the event of a fatal error. const int32_t fatal_error_value_; - // A queue of PendingSend that have not yet been fully sent to |sink_|. - std::queue<linked_ptr<PendingSend> > pending_sends_; - // A queue of PendingSend that have been sent to |sink_|, but have not yet // been acked by the DataSink. - std::queue<linked_ptr<PendingSend> > sends_awaiting_ack_; + std::queue<linked_ptr<PendingSend>> sends_awaiting_ack_; // The callback to report cancel completion if a cancel operation is in // progress. CancelCallback pending_cancel_; - // The number of bytes available for buffering in the DataSink. - uint32_t available_buffer_capacity_; - // Whether we have encountered a fatal error and shut down. bool shut_down_;
diff --git a/device/serial/data_sink_receiver.cc b/device/serial/data_sink_receiver.cc index 170f8b2c..ff66c1c 100644 --- a/device/serial/data_sink_receiver.cc +++ b/device/serial/data_sink_receiver.cc
@@ -45,9 +45,10 @@ // A frame of data received from the client. class DataSinkReceiver::DataFrame { public: - explicit DataFrame(mojo::Array<uint8_t> data); + explicit DataFrame(mojo::Array<uint8_t> data, + const mojo::Callback<void(uint32_t, int32_t)>& callback); - // Returns the number of uncomsumed bytes remaining of this data frame. + // Returns the number of unconsumed bytes remaining of this data frame. uint32_t GetRemainingBytes(); // Returns a pointer to the remaining data to be consumed. @@ -56,23 +57,29 @@ // Reports that |bytes_read| bytes have been consumed. void OnDataConsumed(uint32_t bytes_read); + // Reports that an error occurred. + void ReportError(uint32_t bytes_read, int32_t error); + private: mojo::Array<uint8_t> data_; uint32_t offset_; + const mojo::Callback<void(uint32_t, int32_t)> callback_; }; -DataSinkReceiver::DataSinkReceiver(const ReadyCallback& ready_callback, - const CancelCallback& cancel_callback, - const ErrorCallback& error_callback) - : ready_callback_(ready_callback), +DataSinkReceiver::DataSinkReceiver( + mojo::InterfaceRequest<serial::DataSink> request, + const ReadyCallback& ready_callback, + const CancelCallback& cancel_callback, + const ErrorCallback& error_callback) + : binding_(this, request.Pass()), + ready_callback_(ready_callback), cancel_callback_(cancel_callback), error_callback_(error_callback), - flush_pending_(false), + current_error_(0), buffer_in_use_(NULL), - initialized_(false), - available_buffer_capacity_(0), shut_down_(false), weak_factory_(this) { + binding_.set_error_handler(this); } void DataSinkReceiver::ShutDown() { @@ -82,21 +89,12 @@ DataSinkReceiver::~DataSinkReceiver() { } -void DataSinkReceiver::Init(uint32_t buffer_size) { - if (initialized_) { - ShutDown(); - return; - } - initialized_ = true; - available_buffer_capacity_ = buffer_size; -} - void DataSinkReceiver::Cancel(int32_t error) { // If we have sent a ReportBytesSentAndError but have not received the // response, that ReportBytesSentAndError message will appear to the // DataSinkClient to be caused by this Cancel message. In that case, we ignore // the cancel. - if (flush_pending_) + if (current_error_) return; // If there is a buffer is in use, mark the buffer as cancelled and notify the @@ -113,21 +111,19 @@ cancel_callback_.Run(error); return; } - ReportBytesSentAndError(0, error); + ReportError(0, error); } -void DataSinkReceiver::OnData(mojo::Array<uint8_t> data) { - if (!initialized_) { - ShutDown(); +void DataSinkReceiver::OnData( + mojo::Array<uint8_t> data, + const mojo::Callback<void(uint32_t, int32_t)>& callback) { + if (current_error_) { + callback.Run(0, current_error_); return; } - if (data.size() > available_buffer_capacity_) { - ShutDown(); - return; - } - available_buffer_capacity_ -= static_cast<uint32_t>(data.size()); - pending_data_buffers_.push(linked_ptr<DataFrame>(new DataFrame(data.Pass()))); - if (!buffer_in_use_ && !flush_pending_) + pending_data_buffers_.push( + linked_ptr<DataFrame>(new DataFrame(data.Pass(), callback))); + if (!buffer_in_use_) RunReadyCallback(); } @@ -136,7 +132,7 @@ } void DataSinkReceiver::RunReadyCallback() { - DCHECK(!shut_down_ && !flush_pending_); + DCHECK(!shut_down_ && !current_error_); // If data arrives while a call to RunReadyCallback() is posted, we can be // called with buffer_in_use_ already set. if (buffer_in_use_) @@ -151,7 +147,9 @@ void DataSinkReceiver::Done(uint32_t bytes_read) { if (!DoneInternal(bytes_read)) return; - client()->ReportBytesSent(bytes_read); + pending_data_buffers_.front()->OnDataConsumed(bytes_read); + if (pending_data_buffers_.front()->GetRemainingBytes() == 0) + pending_data_buffers_.pop(); if (!pending_data_buffers_.empty()) { base::MessageLoop::current()->PostTask( FROM_HERE, @@ -163,7 +161,7 @@ void DataSinkReceiver::DoneWithError(uint32_t bytes_read, int32_t error) { if (!DoneInternal(bytes_read)) return; - ReportBytesSentAndError(bytes_read, error); + ReportError(bytes_read, error); } bool DataSinkReceiver::DoneInternal(uint32_t bytes_read) { @@ -172,32 +170,23 @@ DCHECK(buffer_in_use_); buffer_in_use_ = NULL; - available_buffer_capacity_ += bytes_read; - pending_data_buffers_.front()->OnDataConsumed(bytes_read); - if (pending_data_buffers_.front()->GetRemainingBytes() == 0) - pending_data_buffers_.pop(); return true; } -void DataSinkReceiver::ReportBytesSentAndError(uint32_t bytes_read, - int32_t error) { +void DataSinkReceiver::ReportError(uint32_t bytes_read, int32_t error) { // When we encounter an error, we must discard the data from any send buffers - // transmitted by the DataSinkClient before it receives this error. - flush_pending_ = true; - client()->ReportBytesSentAndError( - bytes_read, - error, - base::Bind(&DataSinkReceiver::DoFlush, weak_factory_.GetWeakPtr())); + // transmitted by the DataSink client before it receives this error. + DCHECK(error); + current_error_ = error; + while (!pending_data_buffers_.empty()) { + pending_data_buffers_.front()->ReportError(bytes_read, error); + pending_data_buffers_.pop(); + bytes_read = 0; + } } -void DataSinkReceiver::DoFlush() { - DCHECK(flush_pending_); - flush_pending_ = false; - while (!pending_data_buffers_.empty()) { - available_buffer_capacity_ += - pending_data_buffers_.front()->GetRemainingBytes(); - pending_data_buffers_.pop(); - } +void DataSinkReceiver::ClearError() { + current_error_ = 0; } void DataSinkReceiver::DispatchFatalError() { @@ -261,8 +250,10 @@ buffer_size_ = 0; } -DataSinkReceiver::DataFrame::DataFrame(mojo::Array<uint8_t> data) - : data_(data.Pass()), offset_(0) { +DataSinkReceiver::DataFrame::DataFrame( + mojo::Array<uint8_t> data, + const mojo::Callback<void(uint32_t, int32_t)>& callback) + : data_(data.Pass()), offset_(0), callback_(callback) { DCHECK_LT(0u, data_.size()); } @@ -280,6 +271,14 @@ void DataSinkReceiver::DataFrame::OnDataConsumed(uint32_t bytes_read) { offset_ += bytes_read; DCHECK_LE(offset_, data_.size()); + if (offset_ == data_.size()) + callback_.Run(offset_, 0); +} +void DataSinkReceiver::DataFrame::ReportError(uint32_t bytes_read, + int32_t error) { + offset_ += bytes_read; + DCHECK_LE(offset_, data_.size()); + callback_.Run(offset_, error); } } // namespace device
diff --git a/device/serial/data_sink_receiver.h b/device/serial/data_sink_receiver.h index 2126cdd9..7a808ea 100644 --- a/device/serial/data_sink_receiver.h +++ b/device/serial/data_sink_receiver.h
@@ -18,7 +18,8 @@ namespace device { class DataSinkReceiver : public base::RefCounted<DataSinkReceiver>, - public mojo::InterfaceImpl<serial::DataSink> { + public serial::DataSink, + public mojo::ErrorHandler { public: typedef base::Callback<void(scoped_ptr<ReadOnlyBuffer>)> ReadyCallback; typedef base::Callback<void(int32_t error)> CancelCallback; @@ -29,9 +30,10 @@ // |ready_callback| will not be called again until the previous ReadOnlyBuffer // is destroyed. If a connection error occurs, |error_callback| will be called // and the DataSinkReceiver will act as if ShutDown() had been called. If - // |cancel_callback| is valid, it will be called when the DataSinkClient + // |cancel_callback| is valid, it will be called when the DataSink client // requests cancellation of the in-progress read. - DataSinkReceiver(const ReadyCallback& ready_callback, + DataSinkReceiver(mojo::InterfaceRequest<serial::DataSink> request, + const ReadyCallback& ready_callback, const CancelCallback& cancel_callback, const ErrorCallback& error_callback); @@ -47,9 +49,11 @@ ~DataSinkReceiver() override; // mojo::InterfaceImpl<serial::DataSink> overrides. - void Init(uint32_t buffer_size) override; void Cancel(int32_t error) override; - void OnData(mojo::Array<uint8_t> data) override; + void OnData(mojo::Array<uint8_t> data, + const mojo::Callback<void(uint32_t, int32_t)>& callback) override; + void ClearError() override; + void OnConnectionError() override; // Dispatches data to |ready_callback_|. @@ -65,16 +69,14 @@ // Marks |bytes_read| bytes as being read. bool DoneInternal(uint32_t bytes_read); - // Sends an ReportBytesSentAndError message to the client. - void ReportBytesSentAndError(uint32_t bytes_read, int32_t error); - - // Invoked in response to an ReportBytesSentAndError call to the client at - // the point in the data stream to flush. - void DoFlush(); + // Reports an error to the client. + void ReportError(uint32_t bytes_read, int32_t error); // Reports a fatal error to the client and shuts down. void DispatchFatalError(); + mojo::Binding<serial::DataSink> binding_; + // The callback to call when there is data ready to read. const ReadyCallback ready_callback_; @@ -84,19 +86,13 @@ // The callback to call if a fatal error occurs. const ErrorCallback error_callback_; - // Whether we are waiting for a flush. - bool flush_pending_; + // The current error that has not been cleared by a ClearError message.. + int32_t current_error_; // The buffer passed to |ready_callback_| if one exists. This is not owned, // but the Buffer will call Done or DoneWithError before being deleted. Buffer* buffer_in_use_; - // Whether this has received an Init() call from the client. - bool initialized_; - - // The remaining number of bytes of data that we can buffer. - uint32_t available_buffer_capacity_; - // The data we have received from the client that has not been passed to // |ready_callback_|. std::queue<linked_ptr<DataFrame>> pending_data_buffers_;
diff --git a/device/serial/data_sink_unittest.cc b/device/serial/data_sink_unittest.cc index 24843623..539cb6d 100644 --- a/device/serial/data_sink_unittest.cc +++ b/device/serial/data_sink_unittest.cc
@@ -38,12 +38,11 @@ void SetUp() override { message_loop_.reset(new base::MessageLoop); mojo::InterfacePtr<serial::DataSink> sink_handle; - sink_receiver_ = mojo::WeakBindToProxy( - new DataSinkReceiver( - base::Bind(&DataSinkTest::OnDataToRead, base::Unretained(this)), - base::Bind(&DataSinkTest::OnCancel, base::Unretained(this)), - base::Bind(&DataSinkTest::OnError, base::Unretained(this))), - &sink_handle); + sink_receiver_ = new DataSinkReceiver( + mojo::GetProxy(&sink_handle), + base::Bind(&DataSinkTest::OnDataToRead, base::Unretained(this)), + base::Bind(&DataSinkTest::OnCancel, base::Unretained(this)), + base::Bind(&DataSinkTest::OnError, base::Unretained(this))); sender_.reset(new DataSender(sink_handle.Pass(), kBufferSize, kFatalError)); }
diff --git a/device/serial/data_source_sender.cc b/device/serial/data_source_sender.cc index f9cc4f1..97029dda 100644 --- a/device/serial/data_source_sender.cc +++ b/device/serial/data_source_sender.cc
@@ -71,15 +71,22 @@ uint32_t buffer_size_; }; -DataSourceSender::DataSourceSender(const ReadyCallback& ready_callback, - const ErrorCallback& error_callback) - : ready_callback_(ready_callback), +DataSourceSender::DataSourceSender( + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> client, + const ReadyCallback& ready_callback, + const ErrorCallback& error_callback) + : binding_(this, source.Pass()), + client_(client.Pass()), + ready_callback_(ready_callback), error_callback_(error_callback), available_buffer_capacity_(0), paused_(false), shut_down_(false), weak_factory_(this) { DCHECK(!ready_callback.is_null() && !error_callback.is_null()); + binding_.set_error_handler(this); + client_.set_error_handler(this); } void DataSourceSender::ShutDown() { @@ -138,7 +145,7 @@ int32_t error) { DoneInternal(data); if (!shut_down_) - client()->OnError(error); + client_->OnError(error); paused_ = true; // We don't call GetMoreData here so we don't send any additional data until // Resume() is called. @@ -153,7 +160,7 @@ if (!data.empty()) { mojo::Array<uint8_t> data_to_send(data.size()); std::copy(data.begin(), data.end(), &data_to_send[0]); - client()->OnData(data_to_send.Pass()); + client_->OnData(data_to_send.Pass()); } pending_send_.reset(); }
diff --git a/device/serial/data_source_sender.h b/device/serial/data_source_sender.h index 3a90240f..a8c2c63 100644 --- a/device/serial/data_source_sender.h +++ b/device/serial/data_source_sender.h
@@ -19,7 +19,8 @@ // A DataSourceSender is an interface between a source of data and a // DataSourceClient. class DataSourceSender : public base::RefCounted<DataSourceSender>, - public mojo::InterfaceImpl<serial::DataSource> { + public serial::DataSource, + public mojo::ErrorHandler { public: typedef base::Callback<void(scoped_ptr<WritableBuffer>)> ReadyCallback; typedef base::Callback<void()> ErrorCallback; @@ -29,7 +30,9 @@ // |ready_callback| will not be called again until the previous WritableBuffer // is destroyed. If a connection error occurs, |error_callback| will be // called and the DataSourceSender will act as if ShutDown() had been called. - DataSourceSender(const ReadyCallback& ready_callback, + DataSourceSender(mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> client, + const ReadyCallback& ready_callback, const ErrorCallback& error_callback); // Shuts down this DataSourceSender. After shut down, |ready_callback| and @@ -65,6 +68,9 @@ // Reports a fatal error to the client and shuts down. void DispatchFatalError(); + mojo::Binding<serial::DataSource> binding_; + mojo::InterfacePtr<serial::DataSourceClient> client_; + // The callback to call when the client is ready for more data. ReadyCallback ready_callback_;
diff --git a/device/serial/data_source_unittest.cc b/device/serial/data_source_unittest.cc index 71dfa81..b725f35 100644 --- a/device/serial/data_source_unittest.cc +++ b/device/serial/data_source_unittest.cc
@@ -31,12 +31,18 @@ void SetUp() override { message_loop_.reset(new base::MessageLoop); mojo::InterfacePtr<serial::DataSource> source_sender_handle; - source_sender_ = mojo::WeakBindToProxy( - new DataSourceSender( - base::Bind(&DataSourceTest::CanWriteData, base::Unretained(this)), - base::Bind(&DataSourceTest::OnError, base::Unretained(this))), - &source_sender_handle); - receiver_ = new DataReceiver(source_sender_handle.Pass(), 100, kFatalError); + mojo::InterfacePtr<serial::DataSourceClient> source_sender_client_handle; + mojo::InterfaceRequest<serial::DataSourceClient> + source_sender_client_request = + mojo::GetProxy(&source_sender_client_handle); + source_sender_ = new DataSourceSender( + mojo::GetProxy(&source_sender_handle), + source_sender_client_handle.Pass(), + base::Bind(&DataSourceTest::CanWriteData, base::Unretained(this)), + base::Bind(&DataSourceTest::OnError, base::Unretained(this))); + receiver_ = + new DataReceiver(source_sender_handle.Pass(), + source_sender_client_request.Pass(), 100, kFatalError); } void TearDown() override {
diff --git a/device/serial/data_stream.mojom b/device/serial/data_stream.mojom index a288eb2..e8fd4ec 100644 --- a/device/serial/data_stream.mojom +++ b/device/serial/data_stream.mojom
@@ -4,7 +4,6 @@ module device.serial; -[Client=DataSourceClient] interface DataSource { // Initializes this DataSource with the amount of data its client will // buffer. @@ -27,27 +26,19 @@ OnData(array<uint8> data); }; -[Client=DataSinkClient] interface DataSink { - // Initializes this DataSink with the amount of data it is expected to - // buffer. - Init(uint32 buffer_size); - // Requests the cancellation of any data that has been written to the pipe, // but has not yet been sent to the sink. Cancel(int32 error); - // Invoked to pass |data| to the sink. - OnData(array<uint8> data); -}; + // Invoked to pass |data| to the sink. The response contains the number of + // bytes successfully sent and an optional error. If |error| is zero, + // |bytes_sent| will the size of |data|. + OnData(array<uint8> data) => (uint32 bytes_sent, int32 error); -interface DataSinkClient { - // Reports that the sink has successfully received |bytes_sent| bytes of data. - ReportBytesSent(uint32 bytes_sent); - - // Reports that the sink has received |bytes_sent| bytes of data (possibly 0) - // and encountered an error: |error|. Any OnData messages received by the - // DataSink before the response will be discarded. The client should respond - // when it is ready to resume sending data. - ReportBytesSentAndError(uint32 bytes_sent, int32 error) => (); + // Called to clear the error and resume data transmission after an error + // occurs. After an error is reported in response to an OnData until + // ClearError is called, any further OnData calls will report the same error + // as the first error response. + ClearError(); };
diff --git a/device/serial/data_stream_serialization.mojom b/device/serial/data_stream_serialization.mojom index 259be28..3112dd5 100644 --- a/device/serial/data_stream_serialization.mojom +++ b/device/serial/data_stream_serialization.mojom
@@ -13,9 +13,6 @@ // The error to report for sends in progress when a fatal error occurs. int32 fatal_error_value; - - // The size of the send buffer. - uint32 buffer_size; }; // A pending receive error. @@ -32,6 +29,8 @@ // The control channel to the DataSource from which this DataReceiver receives // data. DataSource source; + // DataSourceClient& + handle<message_pipe> source_client; // The error to report for a receive in progress when a fatal error occurs. int32 fatal_error_value;
diff --git a/device/serial/serial.mojom b/device/serial/serial.mojom index 6714a946..29adb97a 100644 --- a/device/serial/serial.mojom +++ b/device/serial/serial.mojom
@@ -94,7 +94,8 @@ ConnectionOptions? options, Connection& connection, DataSink& sink, - DataSource& source); + DataSource& source, + DataSourceClient source_client); }; interface Connection {
diff --git a/device/serial/serial_connection.cc b/device/serial/serial_connection.cc index 0d3e4171..30e8fa65 100644 --- a/device/serial/serial_connection.cc +++ b/device/serial/serial_connection.cc
@@ -15,20 +15,18 @@ SerialConnection::SerialConnection( scoped_refptr<SerialIoHandler> io_handler, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source) + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client) : io_handler_(io_handler) { - receiver_ = mojo::WeakBindToRequest( - new DataSinkReceiver(base::Bind(&SerialConnection::OnSendPipeReady, - base::Unretained(this)), - base::Bind(&SerialConnection::OnSendCancelled, - base::Unretained(this)), - base::Bind(base::DoNothing)), - &sink); - sender_ = mojo::WeakBindToRequest( - new DataSourceSender(base::Bind(&SerialConnection::OnReceivePipeReady, - base::Unretained(this)), - base::Bind(base::DoNothing)), - &source); + receiver_ = new DataSinkReceiver( + sink.Pass(), + base::Bind(&SerialConnection::OnSendPipeReady, base::Unretained(this)), + base::Bind(&SerialConnection::OnSendCancelled, base::Unretained(this)), + base::Bind(base::DoNothing)); + sender_ = new DataSourceSender( + source.Pass(), source_client.Pass(), + base::Bind(&SerialConnection::OnReceivePipeReady, base::Unretained(this)), + base::Bind(base::DoNothing)); } SerialConnection::~SerialConnection() {
diff --git a/device/serial/serial_connection.h b/device/serial/serial_connection.h index d0b940f..aad93fb2 100644 --- a/device/serial/serial_connection.h +++ b/device/serial/serial_connection.h
@@ -22,7 +22,8 @@ public: SerialConnection(scoped_refptr<SerialIoHandler> io_handler, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source); + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client); ~SerialConnection() override; // mojo::InterfaceImpl<serial::Connection> overrides.
diff --git a/device/serial/serial_connection_factory.cc b/device/serial/serial_connection_factory.cc index 6b01490..85a3e2e 100644 --- a/device/serial/serial_connection_factory.cc +++ b/device/serial/serial_connection_factory.cc
@@ -37,7 +37,8 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source); + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client); void Run(); private: @@ -52,6 +53,7 @@ mojo::InterfaceRequest<serial::Connection> connection_request_; mojo::InterfaceRequest<serial::DataSink> sink_; mojo::InterfaceRequest<serial::DataSource> source_; + mojo::InterfacePtr<serial::DataSourceClient> source_client_; scoped_refptr<SerialIoHandler> io_handler_; DISALLOW_COPY_AND_ASSIGN(ConnectTask); @@ -69,13 +71,11 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source) { - scoped_refptr<ConnectTask> task(new ConnectTask(this, - path, - options.Pass(), - connection_request.Pass(), - sink.Pass(), - source.Pass())); + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client) { + scoped_refptr<ConnectTask> task( + new ConnectTask(this, path, options.Pass(), connection_request.Pass(), + sink.Pass(), source.Pass(), source_client.Pass())); task->Run(); } @@ -88,13 +88,15 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source) + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client) : factory_(factory), path_(path), options_(options.Pass()), connection_request_(connection_request.Pass()), sink_(sink.Pass()), - source_(source.Pass()) { + source_(source.Pass()), + source_client_(source_client.Pass()) { if (!options_) { options_ = serial::ConnectionOptions::New(); } @@ -124,7 +126,8 @@ } mojo::BindToRequest( - new SerialConnection(io_handler_, sink_.Pass(), source_.Pass()), + new SerialConnection(io_handler_, sink_.Pass(), source_.Pass(), + source_client_.Pass()), &connection_request_); }
diff --git a/device/serial/serial_connection_factory.h b/device/serial/serial_connection_factory.h index 4200dca..befb209c 100644 --- a/device/serial/serial_connection_factory.h +++ b/device/serial/serial_connection_factory.h
@@ -32,7 +32,8 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source); + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client); private: friend class base::RefCountedThreadSafe<SerialConnectionFactory>;
diff --git a/device/serial/serial_connection_unittest.cc b/device/serial/serial_connection_unittest.cc index 151ed77..84ccf24 100644 --- a/device/serial/serial_connection_unittest.cc +++ b/device/serial/serial_connection_unittest.cc
@@ -74,17 +74,19 @@ scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)), &service); service.set_error_handler(this); - mojo::InterfacePtr<serial::DataSink> consumer; - mojo::InterfacePtr<serial::DataSource> producer; - service->Connect("device", - serial::ConnectionOptions::New(), - mojo::GetProxy(&connection_), - mojo::GetProxy(&consumer), - mojo::GetProxy(&producer)); - sender_.reset(new DataSender( - consumer.Pass(), kBufferSize, serial::SEND_ERROR_DISCONNECTED)); - receiver_ = new DataReceiver( - producer.Pass(), kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED); + mojo::InterfacePtr<serial::DataSink> sink; + mojo::InterfacePtr<serial::DataSource> source; + mojo::InterfacePtr<serial::DataSourceClient> source_client; + mojo::InterfaceRequest<serial::DataSourceClient> source_client_request = + mojo::GetProxy(&source_client); + service->Connect("device", serial::ConnectionOptions::New(), + mojo::GetProxy(&connection_), mojo::GetProxy(&sink), + mojo::GetProxy(&source), source_client.Pass()); + sender_.reset(new DataSender(sink.Pass(), kBufferSize, + serial::SEND_ERROR_DISCONNECTED)); + receiver_ = + new DataReceiver(source.Pass(), source_client_request.Pass(), + kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED); connection_.set_error_handler(this); connection_->GetInfo( base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this)));
diff --git a/device/serial/serial_service_impl.cc b/device/serial/serial_service_impl.cc index fceb448c..5fc886df 100644 --- a/device/serial/serial_service_impl.cc +++ b/device/serial/serial_service_impl.cc
@@ -61,14 +61,13 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source) { + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client) { if (!IsValidPath(path)) return; - connection_factory_->CreateConnection(path, - options.Pass(), - connection_request.Pass(), - sink.Pass(), - source.Pass()); + connection_factory_->CreateConnection(path, options.Pass(), + connection_request.Pass(), sink.Pass(), + source.Pass(), source_client.Pass()); } SerialDeviceEnumerator* SerialServiceImpl::GetDeviceEnumerator() {
diff --git a/device/serial/serial_service_impl.h b/device/serial/serial_service_impl.h index 0caf00e..b6387a8 100644 --- a/device/serial/serial_service_impl.h +++ b/device/serial/serial_service_impl.h
@@ -36,11 +36,13 @@ void GetDevices( const mojo::Callback<void(mojo::Array<serial::DeviceInfoPtr>)>& callback) override; - void Connect(const mojo::String& path, - serial::ConnectionOptionsPtr options, - mojo::InterfaceRequest<serial::Connection> connection_request, - mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSource> source) override; + void Connect( + const mojo::String& path, + serial::ConnectionOptionsPtr options, + mojo::InterfaceRequest<serial::Connection> connection_request, + mojo::InterfaceRequest<serial::DataSink> sink, + mojo::InterfaceRequest<serial::DataSource> source, + mojo::InterfacePtr<serial::DataSourceClient> source_client) override; private: SerialDeviceEnumerator* GetDeviceEnumerator();
diff --git a/device/serial/serial_service_unittest.cc b/device/serial/serial_service_unittest.cc index 7f8beb23..265b0b5 100644 --- a/device/serial/serial_service_unittest.cc +++ b/device/serial/serial_service_unittest.cc
@@ -85,11 +85,11 @@ mojo::InterfacePtr<serial::Connection> connection; mojo::InterfacePtr<serial::DataSink> sink; mojo::InterfacePtr<serial::DataSource> source; - service->Connect(path, - serial::ConnectionOptions::New(), - mojo::GetProxy(&connection), - mojo::GetProxy(&sink), - mojo::GetProxy(&source)); + mojo::InterfacePtr<serial::DataSourceClient> source_client; + mojo::GetProxy(&source_client); + service->Connect(path, serial::ConnectionOptions::New(), + mojo::GetProxy(&connection), mojo::GetProxy(&sink), + mojo::GetProxy(&source), source_client.Pass()); connection.set_error_handler(this); expecting_error_ = !expecting_success; connection->GetInfo(
diff --git a/device/usb/usb_service.cc b/device/usb/usb_service.cc index 70f054d..3faa3e5 100644 --- a/device/usb/usb_service.cc +++ b/device/usb/usb_service.cc
@@ -44,6 +44,10 @@ void UsbService::Observer::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { } +void UsbService::Observer::OnDeviceRemovedCleanup( + scoped_refptr<UsbDevice> device) { +} + // static UsbService* UsbService::GetInstance( scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { @@ -85,6 +89,7 @@ void UsbService::NotifyDeviceRemoved(scoped_refptr<UsbDevice> device) { DCHECK(CalledOnValidThread()); FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceRemoved(device)); + FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceRemovedCleanup(device)); } } // namespace device
diff --git a/device/usb/usb_service.h b/device/usb/usb_service.h index 4655bfd..a2dfa9e 100644 --- a/device/usb/usb_service.h +++ b/device/usb/usb_service.h
@@ -35,6 +35,9 @@ // was created. virtual void OnDeviceAdded(scoped_refptr<UsbDevice> device); virtual void OnDeviceRemoved(scoped_refptr<UsbDevice> device); + // For observers that need to process device removal after others have run. + // Should not depend on any other service's knowledge of connected devices. + virtual void OnDeviceRemovedCleanup(scoped_refptr<UsbDevice> device); }; // The UI task runner reference is used to talk to the PermissionBrokerClient
diff --git a/device/vibration/vibration_manager_impl_android.h b/device/vibration/vibration_manager_impl_android.h index 80d1c5be..a58df37 100644 --- a/device/vibration/vibration_manager_impl_android.h +++ b/device/vibration/vibration_manager_impl_android.h
@@ -23,7 +23,7 @@ private: VibrationManagerImplAndroid(); - virtual ~VibrationManagerImplAndroid(); + ~VibrationManagerImplAndroid() override; base::android::ScopedJavaGlobalRef<jobject> j_vibration_provider_; };
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn index d556280..13540c1 100644 --- a/extensions/BUILD.gn +++ b/extensions/BUILD.gn
@@ -67,6 +67,8 @@ source_set("test_support") { testonly = true sources = [ + "browser/api/cast_channel/test_util.cc", + "browser/api/cast_channel/test_util.h", "browser/api/dns/mock_host_resolver_creator.cc", "browser/api/dns/mock_host_resolver_creator.h", "browser/api/storage/settings_test_util.cc", @@ -132,6 +134,10 @@ "//testing/gtest", ] + public_deps = [ + "//extensions/common/api/cast_channel:cast_channel_proto", + ] + if (is_win) { cflags = [ "/wd4267" ] # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. } @@ -170,139 +176,153 @@ ] } -# TODO(GYP): Enable this link errors are fixed. -# This gives a link error in web_modal that is very mysterious. The GYP build -# doesn't seem to pull in web_content_modal_dialog_manager.o since the build -# does not have a reference to CreateNativeWebModalManager but it still links. -# The GN build fails with this symbol being undefined. -if (false) { - test("extensions_unittests") { - sources = [ - "browser/admin_policy_unittest.cc", - "browser/api/api_resource_manager_unittest.cc", - "browser/api/cast_channel/cast_auth_ica_unittest.cc", - "browser/api/cast_channel/cast_auth_util_unittest.cc", - "browser/api/cast_channel/cast_channel_api_unittest.cc", - "browser/api/cast_channel/cast_framer_unittest.cc", - "browser/api/cast_channel/cast_socket_unittest.cc", - "browser/api/cast_channel/cast_transport_unittest.cc", - "browser/api/cast_channel/keep_alive_delegate_unittest.cc", - "browser/api/cast_channel/logger_unittest.cc", - "browser/api/declarative/declarative_rule_unittest.cc", - "browser/api/declarative/deduping_factory_unittest.cc", - "browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc", - "browser/api/declarative_webrequest/webrequest_condition_unittest.cc", - "browser/api/idle/idle_api_unittest.cc", - "browser/api/mime_handler_private/mime_handler_private_unittest.cc", - "browser/api/sockets_tcp/sockets_tcp_api_unittest.cc", - "browser/api/sockets_udp/sockets_udp_api_unittest.cc", - "browser/api/storage/settings_quota_unittest.cc", - "browser/api/storage/storage_api_unittest.cc", - "browser/api/storage/storage_frontend_unittest.cc", - "browser/api/web_request/form_data_parser_unittest.cc", - "browser/api/web_request/upload_data_presenter_unittest.cc", - "browser/api/web_request/web_request_time_tracker_unittest.cc", - "browser/computed_hashes_unittest.cc", - "browser/content_hash_tree_unittest.cc", - "browser/event_listener_map_unittest.cc", - "browser/event_router_unittest.cc", - "browser/extension_pref_value_map_unittest.cc", - "browser/extension_registry_unittest.cc", - "browser/file_highlighter_unittest.cc", - "browser/file_reader_unittest.cc", - "browser/guest_view/guest_view_manager_unittest.cc", - "browser/image_loader_unittest.cc", - "browser/info_map_unittest.cc", - "browser/lazy_background_task_queue_unittest.cc", - "browser/management_policy_unittest.cc", - "browser/mojo/keep_alive_impl_unittest.cc", - "browser/process_manager_unittest.cc", - "browser/process_map_unittest.cc", - "browser/quota_service_unittest.cc", - "browser/runtime_data_unittest.cc", - "browser/sandboxed_unpacker_unittest.cc", - "browser/value_store/leveldb_value_store_unittest.cc", - "browser/value_store/testing_value_store_unittest.cc", - "browser/value_store/value_store_change_unittest.cc", - "browser/value_store/value_store_frontend_unittest.cc", - "browser/value_store/value_store_unittest.cc", - "browser/value_store/value_store_unittest.h", - "browser/verified_contents_unittest.cc", - "browser/warning_service_unittest.cc", - "common/api/sockets/sockets_manifest_permission_unittest.cc", - "common/csp_validator_unittest.cc", - "common/event_filter_unittest.cc", - "common/extension_l10n_util_unittest.cc", - "common/extension_resource_unittest.cc", - "common/extension_set_unittest.cc", - "common/file_util_unittest.cc", - "common/image_util_unittest.cc", - "common/manifest_handlers/content_capabilities_manifest_unittest.cc", - "common/manifest_handlers/oauth2_manifest_unittest.cc", - "common/manifest_handlers/shared_module_manifest_unittest.cc", - "common/manifest_handler_unittest.cc", - "common/message_bundle_unittest.cc", - "common/one_shot_event_unittest.cc", - "common/permissions/manifest_permission_set_unittest.cc", - "common/stack_frame_unittest.cc", - "common/url_pattern_set_unittest.cc", - "common/url_pattern_unittest.cc", - "common/user_script_unittest.cc", - "renderer/activity_log_converter_strategy_unittest.cc", - "renderer/api/mojo_private/mojo_private_unittest.cc", - "renderer/api/serial/data_receiver_unittest.cc", - "renderer/api/serial/data_sender_unittest.cc", - "renderer/api/serial/serial_api_unittest.cc", - "renderer/api_test_base.cc", - "renderer/api_test_base.h", - "renderer/api_test_base_unittest.cc", - "renderer/event_unittest.cc", - "renderer/json_schema_unittest.cc", - "renderer/messaging_utils_unittest.cc", - "renderer/module_system_test.cc", - "renderer/module_system_test.h", - "renderer/module_system_unittest.cc", - "renderer/mojo/keep_alive_client_unittest.cc", - "renderer/safe_builtins_unittest.cc", - "renderer/script_context_set_unittest.cc", - "renderer/script_context_unittest.cc", - "renderer/utils_unittest.cc", - "test/extensions_unittests_main.cc", - "utility/unpacker_unittest.cc", - ] +test("extensions_unittests") { + sources = [ + # TODO(rockot|jamescook): This list is out of date. Move the files into + # gypi source lists. + "browser/api/api_resource_manager_unittest.cc", + "browser/api/cast_channel/cast_auth_ica_unittest.cc", + "browser/api/cast_channel/cast_auth_util_unittest.cc", + "browser/api/cast_channel/cast_channel_api_unittest.cc", + "browser/api/cast_channel/cast_framer_unittest.cc", + "browser/api/cast_channel/cast_socket_unittest.cc", + "browser/api/cast_channel/cast_transport_unittest.cc", + "browser/api/cast_channel/keep_alive_delegate_unittest.cc", + "browser/api/cast_channel/logger_unittest.cc", + "browser/api/declarative/declarative_rule_unittest.cc", + "browser/api/declarative/deduping_factory_unittest.cc", + "browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc", + "browser/api/declarative_webrequest/webrequest_condition_unittest.cc", + "browser/api/idle/idle_api_unittest.cc", + "browser/api/mime_handler_private/mime_handler_private_unittest.cc", + "browser/api/sockets_tcp/sockets_tcp_api_unittest.cc", + "browser/api/sockets_udp/sockets_udp_api_unittest.cc", + "browser/api/storage/settings_quota_unittest.cc", + "browser/api/storage/storage_api_unittest.cc", + "browser/api/storage/storage_frontend_unittest.cc", + "browser/api/web_request/form_data_parser_unittest.cc", + "browser/api/web_request/upload_data_presenter_unittest.cc", + "browser/api/web_request/web_request_time_tracker_unittest.cc", + "browser/computed_hashes_unittest.cc", + "browser/content_hash_tree_unittest.cc", + "browser/event_listener_map_unittest.cc", + "browser/event_router_unittest.cc", + "browser/extension_pref_value_map_unittest.cc", + "browser/extension_registry_unittest.cc", + "browser/file_highlighter_unittest.cc", + "browser/file_reader_unittest.cc", + "browser/guest_view/guest_view_manager_unittest.cc", + "browser/image_loader_unittest.cc", + "browser/info_map_unittest.cc", + "browser/lazy_background_task_queue_unittest.cc", + "browser/management_policy_unittest.cc", + "browser/mojo/keep_alive_impl_unittest.cc", + "browser/process_manager_unittest.cc", + "browser/process_map_unittest.cc", + "browser/quota_service_unittest.cc", + "browser/runtime_data_unittest.cc", + "browser/sandboxed_unpacker_unittest.cc", + "browser/value_store/leveldb_value_store_unittest.cc", + "browser/value_store/testing_value_store_unittest.cc", + "browser/value_store/value_store_change_unittest.cc", + "browser/value_store/value_store_frontend_unittest.cc", + "browser/value_store/value_store_unittest.cc", + "browser/value_store/value_store_unittest.h", + "browser/verified_contents_unittest.cc", + "browser/warning_service_unittest.cc", + "common/api/sockets/sockets_manifest_permission_unittest.cc", + "common/csp_validator_unittest.cc", + "common/event_filter_unittest.cc", + "common/extension_l10n_util_unittest.cc", + "common/extension_resource_unittest.cc", + "common/extension_set_unittest.cc", + "common/file_util_unittest.cc", + "common/image_util_unittest.cc", + "common/manifest_handlers/content_capabilities_manifest_unittest.cc", + "common/manifest_handlers/oauth2_manifest_unittest.cc", + "common/manifest_handlers/shared_module_manifest_unittest.cc", + "common/manifest_handler_unittest.cc", + "common/message_bundle_unittest.cc", + "common/one_shot_event_unittest.cc", + "common/permissions/manifest_permission_set_unittest.cc", + "common/stack_frame_unittest.cc", + "common/url_pattern_set_unittest.cc", + "common/url_pattern_unittest.cc", + "common/user_script_unittest.cc", + "renderer/activity_log_converter_strategy_unittest.cc", + "renderer/api/mojo_private/mojo_private_unittest.cc", + "renderer/api/serial/data_receiver_unittest.cc", + "renderer/api/serial/data_sender_unittest.cc", + "renderer/api/serial/serial_api_unittest.cc", + "renderer/api_test_base.cc", + "renderer/api_test_base.h", + "renderer/api_test_base_unittest.cc", + "renderer/event_unittest.cc", + "renderer/json_schema_unittest.cc", + "renderer/messaging_utils_unittest.cc", + "renderer/module_system_test.cc", + "renderer/module_system_test.h", + "renderer/module_system_unittest.cc", + "renderer/mojo/keep_alive_client_unittest.cc", + "renderer/safe_builtins_unittest.cc", + "renderer/script_context_set_unittest.cc", + "renderer/script_context_unittest.cc", + "renderer/utils_unittest.cc", + "test/extensions_unittests_main.cc", + "utility/unpacker_unittest.cc", - deps = [ - ":extensions_resources", - ":shell_and_test_pak", - ":test_support", - "//base", - "//base:prefs_test_support", - "//base/test:test_support", - "//components/keyed_service/content", - "//content/test:test_support", - "//device/serial", - "//device/serial:test_util", - "//extensions/common", - "//extensions/renderer", - "//extensions/strings", - "//mojo/environment:chromium", - "//testing/gmock", - "//testing/gtest", - "//third_party/leveldatabase", - "//third_party/mojo/src/mojo/edk/js", - "//third_party/mojo/src/mojo/edk/system", - "//third_party/mojo/src/mojo/public/cpp/bindings", - ] + # TODO(rockot): DisplayInfoProvider::Create() is only implemented in Chrome + # and app_shell. This is wrong. + "shell/browser/shell_display_info_provider.cc", - if (is_win) { - deps += [ "//base/allocator" ] - } + # TODO(rockot): See above, but the header is in //components. + "shell/browser/shell_web_contents_modal_dialog_manager.cc", + ] + + deps = [ + ":extensions_resources", + ":shell_and_test_pak", + ":test_support", + "//base", + "//base:prefs_test_support", + "//base/test:test_support", + "//components/keyed_service/content", + "//components/user_prefs", + "//content/test:test_support", + "//device/serial", + "//device/serial:test_support", + "//extensions/common", + "//extensions/common/api/cast_channel:cast_channel_proto", + "//extensions/renderer", + "//extensions/strings", + "//extensions/utility", + "//mojo/environment:chromium", + "//testing/gmock", + "//testing/gtest", + "//third_party/leveldatabase", + "//third_party/mojo/src/mojo/edk/js", + "//third_party/mojo/src/mojo/edk/system", + "//third_party/mojo/src/mojo/public/cpp/bindings", + "//third_party/mojo/src/mojo/public/interfaces/application", + ] + + if (is_win) { + deps += [ "//base/allocator" ] + } + + if (is_chromeos) { + sources += [ + # TODO(rockot): There are two implementations of VpnServiceFactory, a + # stub in app_shell and a real one in Chrome. This is wrong. + "shell/browser/api/vpn_provider/vpn_service_factory.cc", + ] } } test("extensions_browsertests") { sources = [ "browser/api/audio/audio_apitest.cc", + "browser/api/bluetooth_socket/bluetooth_socket_apitest.cc", "browser/api/dns/dns_apitest.cc", "browser/api/hid/hid_apitest.cc", "browser/api/socket/socket_apitest.cc", @@ -345,6 +365,7 @@ "//base/test:test_support", "//components/storage_monitor:test_support", "//content/test:test_support", + "//device/bluetooth:mocks", "//mojo/environment:chromium", "//testing/gmock", "//testing/gtest",
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 17d6563b..b29dea26 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -554,6 +554,7 @@ deps += [ "//components/onc", "//components/storage_monitor", + "//components/update_client", "//crypto:platform", "//device/bluetooth", "//device/core",
diff --git a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc index d6e8aad1..530e96a 100644 --- a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc +++ b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc
@@ -6,10 +6,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/test/base/ui_test_utils.h" +#include "base/run_loop.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_uuid.h" #include "device/bluetooth/test/mock_bluetooth_adapter.h" @@ -17,6 +14,7 @@ #include "device/bluetooth/test/mock_bluetooth_socket.h" #include "extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h" #include "extensions/common/test_util.h" +#include "extensions/shell/test/shell_apitest.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "testing/gmock/include/gmock/gmock.h" @@ -36,12 +34,12 @@ namespace { -class BluetoothSocketApiTest : public ExtensionApiTest { +class BluetoothSocketApiTest : public extensions::ShellApiTest { public: BluetoothSocketApiTest() {} void SetUpOnMainThread() override { - ExtensionApiTest::SetUpOnMainThread(); + ShellApiTest::SetUpOnMainThread(); empty_extension_ = extensions::test_util::CreateEmptyExtension(); SetUpMockAdapter(); } @@ -101,7 +99,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, Connect) { ResultCatcher catcher; - catcher.RestrictToBrowserContext(browser()->profile()); + catcher.RestrictToBrowserContext(browser_context()); // Return the right mock device object for the address used by the test, // return NULL for the "Device not found" test. @@ -130,7 +128,7 @@ // Run the test. ExtensionTestMessageListener listener("ready", true); scoped_refptr<const Extension> extension( - LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/connect"))); + LoadApp("api_test/bluetooth_socket/connect")); ASSERT_TRUE(extension.get()); EXPECT_TRUE(listener.WaitUntilSatisfied()); @@ -146,7 +144,7 @@ #endif IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, MAYBE_Listen) { ResultCatcher catcher; - catcher.RestrictToBrowserContext(browser()->profile()); + catcher.RestrictToBrowserContext(browser_context()); // Return a mock socket object as a successful result to the create service // call. @@ -180,7 +178,7 @@ // a client connection to it. ExtensionTestMessageListener socket_listening("ready", true); scoped_refptr<const Extension> extension( - LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/listen"))); + LoadApp("api_test/bluetooth_socket/listen")); ASSERT_TRUE(extension.get()); EXPECT_TRUE(socket_listening.WaitUntilSatisfied()); @@ -208,12 +206,11 @@ IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, PermissionDenied) { ResultCatcher catcher; - catcher.RestrictToBrowserContext(browser()->profile()); + catcher.RestrictToBrowserContext(browser_context()); // Run the test. scoped_refptr<const Extension> extension( - LoadExtension(test_data_dir_.AppendASCII( - "bluetooth_socket/permission_denied"))); + LoadApp("api_test/bluetooth_socket/permission_denied")); ASSERT_TRUE(extension.get()); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc index baa3c04b..17e3eab 100644 --- a/extensions/browser/api/device_permissions_manager.cc +++ b/extensions/browser/api/device_permissions_manager.cc
@@ -398,7 +398,7 @@ } private: - void OnDeviceRemoved(scoped_refptr<UsbDevice> device) override { + void OnDeviceRemovedCleanup(scoped_refptr<UsbDevice> device) override { DCHECK_CURRENTLY_ON(BrowserThread::FILE); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE,
diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc index fbfed8d3..08700dcb0 100644 --- a/extensions/browser/api/management/management_api.cc +++ b/extensions/browser/api/management/management_api.cc
@@ -514,9 +514,10 @@ return false; } - if (!ExtensionSystem::Get(browser_context()) - ->management_policy() - ->UserMayModifySettings(target_extension, NULL)) { + ManagementPolicy* policy = + ExtensionSystem::Get(browser_context())->management_policy(); + if (!policy->UserMayModifySettings(target_extension, nullptr) || + policy->MustRemainInstalled(target_extension, nullptr)) { error_ = ErrorUtils::FormatErrorMessage(keys::kUserCantModifyError, extension_id_); return false;
diff --git a/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc b/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc index 5ef1851..f35aa259 100644 --- a/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc +++ b/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc
@@ -5,7 +5,7 @@ #include "base/memory/scoped_ptr.h" #include "content/public/browser/stream_handle.h" #include "content/public/browser/stream_info.h" -#include "extensions/browser/api/mime_handler_private/mime_handler_private.cc" +#include "extensions/browser/api/mime_handler_private/mime_handler_private.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/extensions/browser/api/printer_provider/printer_provider_api.h b/extensions/browser/api/printer_provider/printer_provider_api.h index 04fde74b..a6da0a9 100644 --- a/extensions/browser/api/printer_provider/printer_provider_api.h +++ b/extensions/browser/api/printer_provider/printer_provider_api.h
@@ -209,6 +209,7 @@ }; // BrowserContextKeyedAPI implementation. + static const bool kServiceRedirectedInIncognito = true; static const char* service_name() { return "PrinterProvider"; } // PrinterProviderInternalAPIObserver implementation:
diff --git a/extensions/browser/api/printer_provider/printer_provider_apitest.cc b/extensions/browser/api/printer_provider/printer_provider_apitest.cc index 0dd8df0c..30840b3b 100644 --- a/extensions/browser/api/printer_provider/printer_provider_apitest.cc +++ b/extensions/browser/api/printer_provider/printer_provider_apitest.cc
@@ -267,18 +267,18 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id.c_str())); + extension_id.c_str(), extension_id.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printerNoDesc\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", - extension_id.c_str())); + extension_id.c_str(), extension_id.c_str())); ValidatePrinterListValue(printers, expected_printers); } @@ -305,11 +305,11 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id.c_str())); + extension_id.c_str(), extension_id.c_str())); ValidatePrinterListValue(printers, expected_printers); } @@ -343,33 +343,33 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id_1.c_str())); + extension_id_1.c_str(), extension_id_1.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printerNoDesc\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", - extension_id_1.c_str())); + extension_id_1.c_str(), extension_id_1.c_str())); expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printerNoDesc\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); ValidatePrinterListValue(printers, expected_printers); } @@ -404,18 +404,18 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printerNoDesc\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); ValidatePrinterListValue(printers, expected_printers); } @@ -450,18 +450,18 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printer1\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printer1\"," "\"name\":\"Printer 1\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%1$s\"," - "\"id\":\"%1$s:printerNoDesc\"," + "\"extensionId\":\"%s\"," + "\"id\":\"%s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", - extension_id_2.c_str())); + extension_id_2.c_str(), extension_id_2.c_str())); ValidatePrinterListValue(printers, expected_printers); }
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h index ac34c50..703ffb5 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h +++ b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h
@@ -46,6 +46,10 @@ friend class PrinterProviderInternalReportPrinterCapabilityFunction; friend class PrinterProviderInternalReportPrintResultFunction; + // BrowserContextKeyedAPI implementation. + static const bool kServiceRedirectedInIncognito = true; + static const char* service_name() { return "PrinterProviderInternal"; } + // Notifies observers that a printerProvider.onGetPrintersRequested callback // has been called. Called from // |PrinterProviderInternalReportPrintersFunction|. @@ -68,9 +72,6 @@ int request_id, core_api::printer_provider_internal::PrintError error); - // BrowserContextKeyedAPI implementation. - static const char* service_name() { return "PrinterProviderInternal"; } - ObserverList<PrinterProviderInternalAPIObserver> observers_; DISALLOW_COPY_AND_ASSIGN(PrinterProviderInternalAPI);
diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc index 29060b2a..f436f38 100644 --- a/extensions/browser/api/usb/usb_apitest.cc +++ b/extensions/browser/api/usb/usb_apitest.cc
@@ -6,7 +6,9 @@ #include "content/public/browser/browser_thread.h" #include "content/public/test/test_utils.h" #include "device/usb/usb_service.h" +#include "extensions/browser/api/device_permissions_prompt.h" #include "extensions/browser/api/usb/usb_api.h" +#include "extensions/shell/browser/shell_extensions_api_client.h" #include "extensions/shell/test/shell_apitest.h" #include "extensions/test/extension_test_message_listener.h" #include "net/base/io_buffer.h" @@ -42,6 +44,38 @@ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); } +class TestDevicePermissionsPrompt + : public DevicePermissionsPrompt, + public DevicePermissionsPrompt::Prompt::Observer { + public: + TestDevicePermissionsPrompt(content::WebContents* web_contents) + : DevicePermissionsPrompt(web_contents) {} + + void ShowDialog() override { prompt()->SetObserver(this); } + + void OnDevicesChanged() override { + std::vector<scoped_refptr<UsbDevice>> devices; + for (size_t i = 0; i < prompt()->GetDeviceCount(); ++i) { + prompt()->GrantDevicePermission(i); + devices.push_back(prompt()->GetDevice(i)); + if (!prompt()->multiple()) { + break; + } + } + delegate()->OnUsbDevicesChosen(devices); + } +}; + +class TestExtensionsAPIClient : public ShellExtensionsAPIClient { + public: + TestExtensionsAPIClient() : ShellExtensionsAPIClient() {} + + scoped_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt( + content::WebContents* web_contents) const override { + return make_scoped_ptr(new TestDevicePermissionsPrompt(web_contents)); + } +}; + class MockUsbDeviceHandle : public UsbDeviceHandle { public: MockUsbDeviceHandle() : UsbDeviceHandle() {} @@ -157,6 +191,10 @@ ShellApiTest::SetUpOnMainThread(); mock_device_ = new MockUsbDevice(0, 0, 0); + EXPECT_CALL(*mock_device_.get(), GetManufacturer(_)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_device_.get(), GetProduct(_)) + .WillRepeatedly(Return(false)); EXPECT_CALL(*mock_device_.get(), GetSerialNumber(_)) .WillRepeatedly(Return(false)); @@ -298,7 +336,6 @@ run_loop.Run(); ASSERT_TRUE(result_listener.WaitUntilSatisfied()); - ASSERT_EQ("success", result_listener.message()); } IN_PROC_BROWSER_TEST_F(UsbApiTest, OnDeviceRemoved) { @@ -318,7 +355,28 @@ run_loop.Run(); ASSERT_TRUE(result_listener.WaitUntilSatisfied()); - ASSERT_EQ("success", result_listener.message()); +} + +IN_PROC_BROWSER_TEST_F(UsbApiTest, GetUserSelectedDevices) { + ExtensionTestMessageListener ready_listener("opened_device", false); + ExtensionTestMessageListener result_listener("success", false); + result_listener.set_failure_message("failure"); + + EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(1); + + TestExtensionsAPIClient test_api_client; + ASSERT_TRUE(LoadApp("api_test/usb/get_user_selected_devices")); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + + base::RunLoop run_loop; + BrowserThread::PostTaskAndReply( + BrowserThread::FILE, FROM_HERE, + base::Bind(&MockUsbService::NotifyDeviceRemoved, + base::Unretained(mock_service_), mock_device_), + run_loop.QuitClosure()); + run_loop.Run(); + + ASSERT_TRUE(result_listener.WaitUntilSatisfied()); } } // namespace extensions
diff --git a/extensions/browser/api/vpn_provider/vpn_service_factory.h b/extensions/browser/api/vpn_provider/vpn_service_factory.h index 84bceb3..51ee00b 100644 --- a/extensions/browser/api/vpn_provider/vpn_service_factory.h +++ b/extensions/browser/api/vpn_provider/vpn_service_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_VPN_VPN_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_VPN_VPN_SERVICE_FACTORY_H_ +#ifndef EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_SERVICE_FACTORY_H_ +#define EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_SERVICE_FACTORY_H_ #include "base/macros.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" @@ -44,4 +44,4 @@ } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_VPN_VPN_SERVICE_FACTORY_H_ +#endif // EXTENSIONS_BROWSER_API_VPN_PROVIDER_VPN_SERVICE_FACTORY_H_
diff --git a/extensions/browser/api/web_view/web_view_internal_api.cc b/extensions/browser/api/web_view/web_view_internal_api.cc index a7da3bd..6270ec1 100644 --- a/extensions/browser/api/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/web_view/web_view_internal_api.cc
@@ -244,7 +244,7 @@ params->options->match_case ? *params->options->match_case : false; } - guest->StartFinding(search_text, options, this); + guest->StartFindInternal(search_text, options, this); return true; } @@ -275,7 +275,7 @@ action = content::STOP_FIND_ACTION_KEEP_SELECTION; } - guest->StopFinding(action); + guest->StopFindingInternal(action); return true; }
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index ab2f8af..b7a999e5 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1015,6 +1015,7 @@ EXTENSIONVIEWINTERNAL_NAVIGATE, NETWORKING_CONFIG_SETNETWORKFILTER, NETWORKING_CONFIG_FINISHAUTHENTICATION, + PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES, // Last entry: Add new entries above and ensure to update // tools/metrics/histograms/histograms.xml. ENUM_BOUNDARY
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc index 7874528..3d03eb8 100644 --- a/extensions/browser/extension_host.cc +++ b/extensions/browser/extension_host.cc
@@ -12,7 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" -#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_context.h" @@ -152,9 +152,10 @@ ExtensionHost::~ExtensionHost() { if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && - extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) { - UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime", - since_created_.Elapsed()); + extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) && + load_start_.get()) { + UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime2", + load_start_->Elapsed()); } content::NotificationService::current()->Notify( extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, @@ -179,7 +180,7 @@ } void ExtensionHost::CreateRenderViewSoon() { - if ((render_process_host() && render_process_host()->HasConnection())) { + if (render_process_host() && render_process_host()->HasConnection()) { // If the process is already started, go ahead and initialize the RenderView // synchronously. The process creation is the real meaty part that we want // to defer. @@ -238,6 +239,7 @@ } void ExtensionHost::LoadInitialURL() { + load_start_.reset(new base::ElapsedTimer()); host_contents_->GetController().LoadURL( initial_url_, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); @@ -306,23 +308,18 @@ did_stop_loading_ = true; OnDidStopLoading(); if (notify) { + CHECK(load_start_.get()); if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { if (extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) { - UMA_HISTOGRAM_TIMES("Extensions.EventPageLoadTime", - since_created_.Elapsed()); + UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.EventPageLoadTime2", + load_start_->Elapsed()); } else { - UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime", - since_created_.Elapsed()); + UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.BackgroundPageLoadTime2", + load_start_->Elapsed()); } - } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_DIALOG) { - UMA_HISTOGRAM_TIMES("Extensions.DialogLoadTime", - since_created_.Elapsed()); } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_POPUP) { - UMA_HISTOGRAM_TIMES("Extensions.PopupLoadTime", - since_created_.Elapsed()); - } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_INFOBAR) { - UMA_HISTOGRAM_TIMES("Extensions.InfobarLoadTime", - since_created_.Elapsed()); + UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.PopupLoadTime2", + load_start_->Elapsed()); } // Send the notification last, because it might result in this being
diff --git a/extensions/browser/extension_host.h b/extensions/browser/extension_host.h index 567499b..cd7e6ae78 100644 --- a/extensions/browser/extension_host.h +++ b/extensions/browser/extension_host.h
@@ -197,8 +197,8 @@ // The type of view being hosted. ViewType extension_host_type_; - // Used to measure how long it's been since the host was created. - base::ElapsedTimer since_created_; + // Measures how long since the initial URL started loading. + scoped_ptr<base::ElapsedTimer> load_start_; ObserverList<ExtensionHostObserver> observer_list_;
diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index 0a816ae..ba13edd 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc
@@ -75,9 +75,12 @@ // ExtensionDispatcher knows what Extension is active, not just its ID. // This is important for classifying the Extension's JavaScript context // correctly (see ExtensionDispatcher::ClassifyJavaScriptContext). + // We also have to include the tab-specific permissions here, since it's + // an extension process. render_view_host->Send( new ExtensionMsg_Loaded(std::vector<ExtensionMsg_Loaded_Params>( - 1, ExtensionMsg_Loaded_Params(extension)))); + 1, ExtensionMsg_Loaded_Params( + extension, true /* include tab permissions */)))); render_view_host->Send( new ExtensionMsg_ActivateExtension(extension->id())); break;
diff --git a/extensions/browser/guest_view/guest_view_base.h b/extensions/browser/guest_view/guest_view_base.h index 54ba4b6..ef3d855 100644 --- a/extensions/browser/guest_view/guest_view_base.h +++ b/extensions/browser/guest_view/guest_view_base.h
@@ -318,7 +318,7 @@ const content::FileChooserParams& params) override; bool ShouldFocusPageAfterCrash() final; bool PreHandleGestureEvent(content::WebContents* source, - const blink::WebGestureEvent& event) final; + const blink::WebGestureEvent& event) override; void UpdatePreferredSize(content::WebContents* web_contents, const gfx::Size& pref_size) final; void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index 8f10a0b..927c00f 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -26,6 +26,7 @@ #include "extensions/strings/grit/extensions_strings.h" #include "ipc/ipc_message_macros.h" #include "net/base/url_util.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" using content::WebContents; @@ -172,6 +173,14 @@ return false; } +bool MimeHandlerViewGuest::StopFinding(content::StopFindAction action) { + if (is_full_page_plugin()) { + web_contents()->StopFinding(action); + return true; + } + return false; +} + content::WebContents* MimeHandlerViewGuest::OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) { @@ -187,6 +196,19 @@ return false; } +bool MimeHandlerViewGuest::PreHandleGestureEvent( + content::WebContents* source, + const blink::WebGestureEvent& event) { + if (event.type == blink::WebGestureEvent::GesturePinchBegin || + event.type == blink::WebGestureEvent::GesturePinchUpdate || + event.type == blink::WebGestureEvent::GesturePinchEnd) { + // If we're an embedded plugin we drop pinch-gestures to avoid zooming the + // guest. + return !is_full_page_plugin(); + } + return false; +} + void MimeHandlerViewGuest::FindReply(content::WebContents* web_contents, int request_id, int number_of_matches,
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index 65084b5a..823f68cd 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -74,12 +74,15 @@ bool Find(int request_id, const base::string16& search_text, const blink::WebFindOptions& options) override; + bool StopFinding(content::StopFindAction action) override; // WebContentsDelegate implementation. content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; bool HandleContextMenu(const content::ContextMenuParams& params) override; + bool PreHandleGestureEvent(content::WebContents* source, + const blink::WebGestureEvent& event) override; void FindReply(content::WebContents* web_contents, int request_id, int number_of_matches,
diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc index 2e63b79..ff9869f 100644 --- a/extensions/browser/guest_view/web_view/web_view_apitest.cc +++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -636,8 +636,7 @@ LaunchApp("web_view/apitest"); GURL::Replacements replace_host; - std::string host_str("localhost"); // Must stay in scope with replace_host. - replace_host.SetHostStr(host_str); + replace_host.SetHostStr("localhost"); // Run the test and wait until the guest WebContents is available and has // finished loading.
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 3641898..717770fe 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -557,14 +557,14 @@ } } -void WebViewGuest::StartFinding( +void WebViewGuest::StartFindInternal( const base::string16& search_text, const blink::WebFindOptions& options, scoped_refptr<WebViewInternalFindFunction> find_function) { find_helper_.Find(web_contents(), search_text, options, find_function); } -void WebViewGuest::StopFinding(content::StopFindAction action) { +void WebViewGuest::StopFindingInternal(content::StopFindAction action) { find_helper_.CancelAllFindSessions(); web_contents()->StopFinding(action); }
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index a7ccfff..2e399ea9 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -169,12 +169,13 @@ double zoom() const { return current_zoom_factor_; } // Begin or continue a find request. - void StartFinding(const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr<WebViewInternalFindFunction> find_function); + void StartFindInternal( + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr<WebViewInternalFindFunction> find_function); // Conclude a find request to clear highlighting. - void StopFinding(content::StopFindAction); + void StopFindingInternal(content::StopFindAction); // If possible, navigate the guest to |relative_index| entries away from the // current navigation entry. Returns true on success.
diff --git a/extensions/browser/mojo/stash_backend.cc b/extensions/browser/mojo/stash_backend.cc index da4842d..5bab69c3 100644 --- a/extensions/browser/mojo/stash_backend.cc +++ b/extensions/browser/mojo/stash_backend.cc
@@ -4,51 +4,36 @@ #include "extensions/browser/mojo/stash_backend.h" +#include "base/bind.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" +#include "third_party/mojo/src/mojo/public/cpp/environment/async_waiter.h" + namespace extensions { +namespace { // An implementation of StashService that forwards calls to a StashBackend. -class StashServiceImpl : public mojo::InterfaceImpl<StashService> { +class StashServiceImpl : public StashService { public: - explicit StashServiceImpl(base::WeakPtr<StashBackend> backend); + StashServiceImpl(mojo::InterfaceRequest<StashService> request, + base::WeakPtr<StashBackend> backend); ~StashServiceImpl() override; - // mojo::InterfaceImpl<StashService> overrides. + // StashService overrides. void AddToStash(mojo::Array<StashedObjectPtr> stash) override; void RetrieveStash( const mojo::Callback<void(mojo::Array<StashedObjectPtr> stash)>& callback) override; private: + mojo::StrongBinding<StashService> binding_; base::WeakPtr<StashBackend> backend_; DISALLOW_COPY_AND_ASSIGN(StashServiceImpl); }; -StashBackend::StashBackend() : weak_factory_(this) { -} - -StashBackend::~StashBackend() { -} - -void StashBackend::AddToStash(mojo::Array<StashedObjectPtr> stashed_objects) { - for (size_t i = 0; i < stashed_objects.size(); i++) { - stashed_objects_.push_back(stashed_objects[i].Pass()); - } -} - -mojo::Array<StashedObjectPtr> StashBackend::RetrieveStash() { - if (stashed_objects_.is_null()) - stashed_objects_.resize(0); - return stashed_objects_.Pass(); -} - -void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) { - mojo::BindToRequest(new StashServiceImpl(weak_factory_.GetWeakPtr()), - &request); -} - -StashServiceImpl::StashServiceImpl(base::WeakPtr<StashBackend> backend) - : backend_(backend) { +StashServiceImpl::StashServiceImpl(mojo::InterfaceRequest<StashService> request, + base::WeakPtr<StashBackend> backend) + : binding_(this, request.Pass()), backend_(backend) { } StashServiceImpl::~StashServiceImpl() { @@ -70,4 +55,113 @@ callback.Run(backend_->RetrieveStash()); } +} // namespace + +// A stash entry for a stashed object. This handles notifications if a handle +// within the stashed object is readable. +class StashBackend::StashEntry { + public: + // Construct a StashEntry for |stashed_object|. If |on_handle_readable| is + // non-null, it will be invoked when any handle on |stashed_object| is + // readable. + StashEntry(StashedObjectPtr stashed_object, + const base::Closure& on_handle_readable); + ~StashEntry(); + + // Returns the stashed object. + StashedObjectPtr Release(); + + // Cancels notifications for handles becoming readable. + void CancelHandleNotifications(); + + private: + // Invoked when a handle within |stashed_object_| is readable. + void OnHandleReady(MojoResult result); + + // The waiters that are waiting for handles to be readable. + ScopedVector<mojo::AsyncWaiter> waiters_; + + StashedObjectPtr stashed_object_; + + // If non-null, a callback to call when a handle contained within + // |stashed_object_| is readable. + const base::Closure on_handle_readable_; +}; + +StashBackend::StashBackend(const base::Closure& on_handle_readable) + : on_handle_readable_(on_handle_readable), + has_notified_(false), + weak_factory_(this) { +} + +StashBackend::~StashBackend() { +} + +void StashBackend::AddToStash(mojo::Array<StashedObjectPtr> stashed_objects) { + for (size_t i = 0; i < stashed_objects.size(); i++) { + stashed_objects_.push_back( + new StashEntry(stashed_objects[i].Pass(), + has_notified_ ? base::Closure() + : base::Bind(&StashBackend::OnHandleReady, + weak_factory_.GetWeakPtr()))); + } +} + +mojo::Array<StashedObjectPtr> StashBackend::RetrieveStash() { + has_notified_ = false; + mojo::Array<StashedObjectPtr> result(0); + for (auto& entry : stashed_objects_) { + result.push_back(entry->Release()); + } + stashed_objects_.clear(); + return result.Pass(); +} + +void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) { + new StashServiceImpl(request.Pass(), weak_factory_.GetWeakPtr()); +} + +void StashBackend::OnHandleReady() { + DCHECK(!has_notified_); + has_notified_ = true; + for (auto& entry : stashed_objects_) { + entry->CancelHandleNotifications(); + } + if (!on_handle_readable_.is_null()) + on_handle_readable_.Run(); +} + +StashBackend::StashEntry::StashEntry(StashedObjectPtr stashed_object, + const base::Closure& on_handle_readable) + : stashed_object_(stashed_object.Pass()), + on_handle_readable_(on_handle_readable) { + if (on_handle_readable_.is_null() || !stashed_object_->monitor_handles) + return; + + for (size_t i = 0; i < stashed_object_->stashed_handles.size(); i++) { + waiters_.push_back(new mojo::AsyncWaiter( + stashed_object_->stashed_handles[i].get(), MOJO_HANDLE_SIGNAL_READABLE, + base::Bind(&StashBackend::StashEntry::OnHandleReady, + base::Unretained(this)))); + } +} + +StashBackend::StashEntry::~StashEntry() { +} + +StashedObjectPtr StashBackend::StashEntry::Release() { + waiters_.clear(); + return stashed_object_.Pass(); +} + +void StashBackend::StashEntry::CancelHandleNotifications() { + waiters_.clear(); +} + +void StashBackend::StashEntry::OnHandleReady(MojoResult result) { + if (result != MOJO_RESULT_OK) + return; + on_handle_readable_.Run(); +} + } // namespace extensions
diff --git a/extensions/browser/mojo/stash_backend.h b/extensions/browser/mojo/stash_backend.h index 2aff1349..abd0e269 100644 --- a/extensions/browser/mojo/stash_backend.h +++ b/extensions/browser/mojo/stash_backend.h
@@ -5,9 +5,8 @@ #ifndef EXTENSIONS_BROWSER_MOJO_STASH_BACKEND_H_ #define EXTENSIONS_BROWSER_MOJO_STASH_BACKEND_H_ -#include <vector> - -#include "base/memory/linked_ptr.h" +#include "base/callback.h" +#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "extensions/common/mojo/stash.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" @@ -17,7 +16,7 @@ // A backend that provides access to StashService for a single extension. class StashBackend { public: - StashBackend(); + explicit StashBackend(const base::Closure& on_handle_readable); ~StashBackend(); // Creates a StashService that forwards calls to this StashBackend and bind it @@ -32,8 +31,19 @@ mojo::Array<StashedObjectPtr> RetrieveStash(); private: + class StashEntry; + + // Invoked when a handle is readable. + void OnHandleReady(); + // The objects that have been stashed. - mojo::Array<StashedObjectPtr> stashed_objects_; + ScopedVector<StashEntry> stashed_objects_; + + // The callback to call when a handle is readable. + const base::Closure on_handle_readable_; + + // Whether a handle has become readable since the last RetrieveStash() call. + bool has_notified_; base::WeakPtrFactory<StashBackend> weak_factory_;
diff --git a/extensions/browser/mojo/stash_backend_unittest.cc b/extensions/browser/mojo/stash_backend_unittest.cc index 9d7f0947..de8abf44 100644 --- a/extensions/browser/mojo/stash_backend_unittest.cc +++ b/extensions/browser/mojo/stash_backend_unittest.cc
@@ -7,14 +7,38 @@ #include "base/run_loop.h" #include "extensions/browser/mojo/stash_backend.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom.h" namespace extensions { +namespace { + +// Create a data pipe, write some data to the producer handle and return the +// consumer handle. +mojo::ScopedHandle CreateReadableHandle() { + mojo::ScopedDataPipeConsumerHandle consumer_handle; + mojo::ScopedDataPipeProducerHandle producer_handle; + MojoCreateDataPipeOptions options = { + sizeof(options), MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, 1, + }; + MojoResult result = + mojo::CreateDataPipe(&options, &producer_handle, &consumer_handle); + EXPECT_EQ(MOJO_RESULT_OK, result); + uint32_t num_bytes = 1; + result = mojo::WriteDataRaw(producer_handle.get(), "a", &num_bytes, + MOJO_WRITE_DATA_FLAG_NONE); + EXPECT_EQ(MOJO_RESULT_OK, result); + EXPECT_EQ(1u, num_bytes); + return mojo::ScopedHandle::From(consumer_handle.Pass()); +} + +} // namespace class StashServiceTest : public testing::Test, public mojo::ErrorHandler { public: enum Event { EVENT_NONE, EVENT_STASH_RETRIEVED, + EVENT_HANDLE_READY, }; StashServiceTest() {} @@ -22,9 +46,11 @@ void SetUp() override { expecting_error_ = false; expected_event_ = EVENT_NONE; - stash_backend_.reset(new StashBackend); + stash_backend_.reset(new StashBackend(base::Bind( + &StashServiceTest::OnHandleReadyToRead, base::Unretained(this)))); stash_backend_->BindToRequest(mojo::GetProxy(&stash_service_)); stash_service_.set_error_handler(this); + handles_ready_ = 0; } void OnConnectionError() override { FAIL() << "Unexpected connection error"; } @@ -55,6 +81,11 @@ stop_run_loop_.Run(); } + void OnHandleReadyToRead() { + handles_ready_++; + EventReceived(EVENT_HANDLE_READY); + } + protected: base::MessageLoop message_loop_; base::Closure stop_run_loop_; @@ -62,6 +93,7 @@ Event expected_event_; bool expecting_error_; mojo::InterfacePtr<StashService> stash_service_; + int handles_ready_; private: DISALLOW_COPY_AND_ASSIGN(StashServiceTest); @@ -147,6 +179,94 @@ EXPECT_EQ(0u, stashed_objects.size()); } +TEST_F(StashServiceTest, NotifyOnReadableHandle) { + mojo::Array<StashedObjectPtr> stash_entries; + StashedObjectPtr stashed_object(StashedObject::New()); + stashed_object->id = "test type"; + stashed_object->data.push_back(0); + stashed_object->monitor_handles = true; + mojo::ServiceProviderPtr service_provider; + + // Stash the ServiceProvider request. When we make a call on + // |service_provider|, the stashed handle will become readable. + stashed_object->stashed_handles.push_back(mojo::ScopedHandle::From( + mojo::GetProxy(&service_provider).PassMessagePipe())); + + stash_entries.push_back(stashed_object.Pass()); + stash_service_->AddToStash(stash_entries.Pass()); + + mojo::MessagePipe pipe; + service_provider->ConnectToService("", pipe.handle0.Pass()); + + WaitForEvent(EVENT_HANDLE_READY); + EXPECT_EQ(1, handles_ready_); +} + +TEST_F(StashServiceTest, NotifyOnReadableDataPipeHandle) { + mojo::Array<StashedObjectPtr> stash_entries; + StashedObjectPtr stashed_object(StashedObject::New()); + stashed_object->id = "test type"; + stashed_object->monitor_handles = true; + + MojoCreateDataPipeOptions options = { + sizeof(options), MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, 1, + }; + mojo::ScopedDataPipeConsumerHandle consumer_handle; + mojo::ScopedDataPipeProducerHandle producer_handle; + uint32_t num_bytes = 1; + MojoResult result = + mojo::CreateDataPipe(&options, &producer_handle, &consumer_handle); + ASSERT_EQ(MOJO_RESULT_OK, result); + result = mojo::WriteDataRaw(producer_handle.get(), "a", &num_bytes, + MOJO_WRITE_DATA_FLAG_NONE); + ASSERT_EQ(MOJO_RESULT_OK, result); + ASSERT_EQ(1u, num_bytes); + stashed_object->stashed_handles.push_back( + mojo::ScopedHandle::From(producer_handle.Pass())); + stashed_object->stashed_handles.push_back( + mojo::ScopedHandle::From(consumer_handle.Pass())); + stashed_object->data.push_back(1); + + stash_entries.push_back(stashed_object.Pass()); + stash_service_->AddToStash(stash_entries.Pass()); + WaitForEvent(EVENT_HANDLE_READY); + EXPECT_EQ(1, handles_ready_); +} + +TEST_F(StashServiceTest, NotifyOncePerStashOnReadableHandles) { + mojo::Array<StashedObjectPtr> stash_entries; + StashedObjectPtr stashed_object(StashedObject::New()); + stashed_object->id = "test type"; + stashed_object->data.push_back(1); + stashed_object->monitor_handles = true; + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stash_entries.push_back(stashed_object.Pass()); + stashed_object = StashedObject::New(); + stashed_object->id = "another test type"; + stashed_object->data.push_back(2); + stashed_object->monitor_handles = true; + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stash_entries.push_back(stashed_object.Pass()); + stash_service_->AddToStash(stash_entries.Pass()); + WaitForEvent(EVENT_HANDLE_READY); + EXPECT_EQ(1, handles_ready_); + + stashed_object = StashedObject::New(); + stashed_object->id = "yet another test type"; + stashed_object->data.push_back(3); + stashed_object->monitor_handles = true; + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stashed_object->stashed_handles.push_back(CreateReadableHandle()); + stash_entries.push_back(stashed_object.Pass()); + stash_service_->AddToStash(stash_entries.Pass()); + + stash_service_->AddToStash(RetrieveStash()); + WaitForEvent(EVENT_HANDLE_READY); + EXPECT_EQ(2, handles_ready_); +} + // Test that a stash service discards stashed objects when the backend no longer // exists. TEST_F(StashServiceTest, ServiceWithDeletedBackend) {
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index 83bd2cd..449e33c 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc
@@ -9,7 +9,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" -#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" @@ -378,9 +378,9 @@ const std::string& extension_id) { std::set<RenderViewHost*> result; - SiteInstance* site_instance = GetSiteInstanceForURL( - Extension::GetBaseURLFromExtensionId(extension_id)); - if (!site_instance) + scoped_refptr<SiteInstance> site_instance(GetSiteInstanceForURL( + Extension::GetBaseURLFromExtensionId(extension_id))); + if (!site_instance.get()) return result; // Gather up all the views for that site. @@ -757,7 +757,10 @@ case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: { // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead // of a notification. + const base::TimeTicks start_time = base::TimeTicks::Now(); MaybeCreateStartupBackgroundHosts(); + UMA_HISTOGRAM_TIMES("Extensions.ProcessManagerStartupHostsTime", + base::TimeTicks::Now() - start_time); break; }
diff --git a/extensions/browser/process_manager.h b/extensions/browser/process_manager.h index 658fcd3..2bfcb60e4 100644 --- a/extensions/browser/process_manager.h +++ b/extensions/browser/process_manager.h
@@ -73,6 +73,10 @@ ExtensionHost* GetBackgroundHostForExtension(const std::string& extension_id); // Returns the SiteInstance that the given URL belongs to. + // Callers should wrap the result in a scoped_refptr to ensure the + // SiteInstance becomes refcounted. + // TODO(devlin): The above comment clearly indicates that this should just + // return a refptr. Update callers. // TODO(aa): This only returns correct results for extensions and packaged // apps, not hosted apps. virtual content::SiteInstance* GetSiteInstanceForURL(const GURL& url);
diff --git a/extensions/browser/renderer_startup_helper.cc b/extensions/browser/renderer_startup_helper.cc index 5cdd8b1..111c5e27 100644 --- a/extensions/browser/renderer_startup_helper.cc +++ b/extensions/browser/renderer_startup_helper.cc
@@ -64,8 +64,11 @@ for (ExtensionSet::const_iterator iter = extensions.begin(); iter != extensions.end(); ++iter) { // Renderers don't need to know about themes. - if (!(*iter)->is_theme()) - loaded_extensions.push_back(ExtensionMsg_Loaded_Params(iter->get())); + if (!(*iter)->is_theme()) { + // Don't need to include tab permissions for new tabs. + loaded_extensions.push_back(ExtensionMsg_Loaded_Params( + iter->get(), false /* no tab permissions */)); + } } process->Send(new ExtensionMsg_Loaded(loaded_extensions)); break;
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index c42f525..efcb46e 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -203,10 +203,16 @@ "dependencies": ["permission:networking.config"], "contexts": ["blessed_extension"] }, - "networkingPrivate": { + "networkingPrivate": [{ "dependencies": ["permission:networkingPrivate"], "contexts": ["blessed_extension"] - }, + }, { + "channel": "stable", + "contexts": ["webui"], + "matches": [ + "chrome://network/*" + ] + }], "power": { "dependencies": ["permission:power"], "contexts": ["blessed_extension"]
diff --git a/extensions/common/extension_messages.cc b/extensions/common/extension_messages.cc index ce572112..94a6bd0a 100644 --- a/extensions/common/extension_messages.cc +++ b/extensions/common/extension_messages.cc
@@ -49,7 +49,8 @@ ExtensionMsg_Loaded_Params::~ExtensionMsg_Loaded_Params() {} ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params( - const Extension* extension) + const Extension* extension, + bool include_tab_permissions) : manifest(extension->manifest()->value()->DeepCopy()), location(extension->location()), path(extension->path()), @@ -58,6 +59,14 @@ *extension->permissions_data()->withheld_permissions()), id(extension->id()), creation_flags(extension->creation_flags()) { + if (include_tab_permissions) { + const extensions::PermissionsData::TabPermissionsMap& tab_permissions = + extension->permissions_data()->tab_specific_permissions(); + for (const auto& pair : tab_permissions) { + tab_specific_permissions[pair.first] = + ExtensionMsg_PermissionSetStruct(*pair.second); + } + } } scoped_refptr<Extension> ExtensionMsg_Loaded_Params::ConvertToExtension( @@ -65,9 +74,14 @@ scoped_refptr<Extension> extension = Extension::Create(path, location, *manifest, creation_flags, error); if (extension.get()) { - extension->permissions_data()->SetPermissions( - active_permissions.ToPermissionSet(), - withheld_permissions.ToPermissionSet()); + const extensions::PermissionsData* permissions_data = + extension->permissions_data(); + permissions_data->SetPermissions(active_permissions.ToPermissionSet(), + withheld_permissions.ToPermissionSet()); + for (const auto& pair : tab_specific_permissions) { + permissions_data->UpdateTabSpecificPermissions( + pair.first, pair.second.ToPermissionSet()); + } } return extension; }
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index cb96ceb..aee505c 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -258,7 +258,8 @@ struct ExtensionMsg_Loaded_Params { ExtensionMsg_Loaded_Params(); ~ExtensionMsg_Loaded_Params(); - explicit ExtensionMsg_Loaded_Params(const extensions::Extension* extension); + ExtensionMsg_Loaded_Params(const extensions::Extension* extension, + bool include_tab_permissions); // Creates a new extension from the data in this object. scoped_refptr<extensions::Extension> ConvertToExtension( @@ -277,6 +278,7 @@ // The extension's active and withheld permissions. ExtensionMsg_PermissionSetStruct active_permissions; ExtensionMsg_PermissionSetStruct withheld_permissions; + std::map<int, ExtensionMsg_PermissionSetStruct> tab_specific_permissions; // We keep this separate so that it can be used in logging. std::string id; @@ -469,14 +471,18 @@ ExtensionMsg_UpdatePermissions_Params) // Tell the render view about new tab-specific permissions for an extension. -IPC_MESSAGE_ROUTED3(ExtensionMsg_UpdateTabSpecificPermissions, - GURL /* url */, - std::string /* extension_id */, - extensions::URLPatternSet /* hosts */) +IPC_MESSAGE_CONTROL5(ExtensionMsg_UpdateTabSpecificPermissions, + GURL /* url */, + std::string /* extension_id */, + extensions::URLPatternSet /* hosts */, + bool /* update origin whitelist */, + int /* tab_id */) // Tell the render view to clear tab-specific permissions for some extensions. -IPC_MESSAGE_ROUTED1(ExtensionMsg_ClearTabSpecificPermissions, - std::vector<std::string> /* extension_ids */) +IPC_MESSAGE_CONTROL3(ExtensionMsg_ClearTabSpecificPermissions, + std::vector<std::string> /* extension_ids */, + bool /* update origin whitelist */, + int /* tab_id */) // Tell the renderer which type this view is. IPC_MESSAGE_ROUTED1(ExtensionMsg_NotifyRenderViewType,
diff --git a/extensions/common/mojo/stash.mojom b/extensions/common/mojo/stash.mojom index 6cc4908..5c1e68bd 100644 --- a/extensions/common/mojo/stash.mojom +++ b/extensions/common/mojo/stash.mojom
@@ -17,6 +17,10 @@ // The handles contained within the serialization struct. array<handle> stashed_handles; + + // Whether to monitor |stashed_handles| and relaunch the client when a handle + // becomes readable. + bool monitor_handles = false; }; interface StashService {
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index caa28af..c7acd83 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h
@@ -150,6 +150,7 @@ kOverrideEscFullscreen, kPageCapture, kPointerLock, + kPlatformKeys, kPlugin, kPower, kPreferencesPrivate,
diff --git a/extensions/common/permissions/permission_message.h b/extensions/common/permissions/permission_message.h index aa3239e..94781bd 100644 --- a/extensions/common/permissions/permission_message.h +++ b/extensions/common/permissions/permission_message.h
@@ -101,6 +101,7 @@ kHostsAllReadOnly, kInterceptAllKeys, kNetworkingConfig, + kPlatformKeys, // Last entry: Add new entries above and ensure to update the // "ExtensionPermission2" enum in tools/metrics/histograms/histograms.xml. kEnumBoundary,
diff --git a/extensions/common/permissions/permission_set.cc b/extensions/common/permissions/permission_set.cc index ee21137..65236ac 100644 --- a/extensions/common/permissions/permission_set.cc +++ b/extensions/common/permissions/permission_set.cc
@@ -4,13 +4,8 @@ #include "extensions/common/permissions/permission_set.h" -#include <algorithm> -#include <iterator> -#include <string> - #include "extensions/common/permissions/permissions_info.h" #include "extensions/common/url_pattern.h" -#include "extensions/common/url_pattern_set.h" #include "url/gurl.h" namespace extensions {
diff --git a/extensions/common/permissions/permission_set.h b/extensions/common/permissions/permission_set.h index 3afd799..aee9cb9 100644 --- a/extensions/common/permissions/permission_set.h +++ b/extensions/common/permissions/permission_set.h
@@ -5,16 +5,11 @@ #ifndef EXTENSIONS_COMMON_PERMISSIONS_PERMISSION_SET_H_ #define EXTENSIONS_COMMON_PERMISSIONS_PERMISSION_SET_H_ -#include <map> #include <set> #include <string> -#include <vector> #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" -#include "base/strings/string16.h" -#include "extensions/common/manifest.h" #include "extensions/common/permissions/api_permission.h" #include "extensions/common/permissions/api_permission_set.h" #include "extensions/common/permissions/manifest_permission.h" @@ -22,7 +17,6 @@ #include "extensions/common/url_pattern_set.h" namespace extensions { -class Extension; // The PermissionSet is an immutable class that encapsulates an // extension's permissions. The class exposes set operations for combining and
diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc index af405273..693a39e 100644 --- a/extensions/common/permissions/permissions_data.cc +++ b/extensions/common/permissions/permissions_data.cc
@@ -8,14 +8,13 @@ #include "content/public/common/url_constants.h" #include "extensions/common/constants.h" #include "extensions/common/error_utils.h" +#include "extensions/common/extension.h" #include "extensions/common/extensions_client.h" -#include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/permissions_parser.h" #include "extensions/common/permissions/permission_message_provider.h" #include "extensions/common/switches.h" #include "extensions/common/url_pattern_set.h" -#include "extensions/common/user_script.h" #include "url/gurl.h" #include "url/url_constants.h" @@ -170,8 +169,12 @@ return active_permissions()->CheckAPIPermissionWithParam(permission, param); } -const URLPatternSet& PermissionsData::GetEffectiveHostPermissions() const { - return active_permissions()->effective_hosts(); +URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { + base::AutoLock auto_lock(runtime_lock_); + URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); + for (const auto& val : tab_specific_permissions_) + effective_hosts.AddPatterns(val.second->effective_hosts()); + return effective_hosts; } bool PermissionsData::HasHostPermission(const GURL& url) const {
diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h index ba2f3c3..38f7266 100644 --- a/extensions/common/permissions/permissions_data.h +++ b/extensions/common/permissions/permissions_data.h
@@ -10,10 +10,8 @@ #include <vector> #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "base/synchronization/lock.h" -#include "extensions/common/extension.h" #include "extensions/common/manifest.h" #include "extensions/common/permissions/api_permission.h" #include "extensions/common/permissions/permission_message.h" @@ -22,17 +20,11 @@ class GURL; namespace extensions { - -class PermissionSet; class Extension; class URLPatternSet; -class UserScript; -// A container for the active permissions of an extension. -// TODO(rdevlin.cronin): For the love of everything good, rename this class to -// ActivePermissions. We do *not* need PermissionsParser, PermissionSet, -// PermissionInfo, and PermissionsData. No one will be able to keep them -// straight. +// A container for the permissions state of an extension, including active, +// withheld, and tab-specific permissions. class PermissionsData { public: // The possible types of access for a given frame. @@ -43,6 +35,8 @@ // the given page. }; + using TabPermissionsMap = std::map<int, scoped_refptr<const PermissionSet>>; + // Delegate class to allow different contexts (e.g. browser vs renderer) to // have control over policy decisions. class PolicyDelegate { @@ -115,15 +109,17 @@ APIPermission::ID permission, const APIPermission::CheckParam* param) const; - // TODO(rdevlin.cronin): GetEffectiveHostPermissions(), HasHostPermission(), - // and HasEffectiveAccessToAllHosts() are just forwards for the active + // Returns the hosts this extension effectively has access to, including + // explicit and scriptable hosts, and any hosts on tabs the extension has + // active tab permissions for. + URLPatternSet GetEffectiveHostPermissions() const; + + // TODO(rdevlin.cronin): HasHostPermission() and + // HasEffectiveAccessToAllHosts() are just forwards for the active // permissions. We should either get rid of these, and have callers use // active_permissions(), or should get rid of active_permissions(), and make // callers use PermissionsData for everything. We should not do both. - // Returns the effective hosts associated with the active permissions. - const URLPatternSet& GetEffectiveHostPermissions() const; - // Whether the extension has access to the given |url|. bool HasHostPermission(const GURL& url) const; @@ -201,16 +197,23 @@ bool CanCaptureVisiblePage(int tab_id, std::string* error) const; const scoped_refptr<const PermissionSet>& active_permissions() const { - // TODO(dcheng): What is the point of this lock? + // We lock so that we can't also be setting the permissions while returning. base::AutoLock auto_lock(runtime_lock_); return active_permissions_unsafe_; } const scoped_refptr<const PermissionSet>& withheld_permissions() const { - // TODO(dcheng): What is the point of this lock? + // We lock so that we can't also be setting the permissions while returning. + base::AutoLock auto_lock(runtime_lock_); return withheld_permissions_unsafe_; } + const TabPermissionsMap& tab_specific_permissions() const { + // We lock so that we can't also be setting the permissions while returning. + base::AutoLock auto_lock(runtime_lock_); + return tab_specific_permissions_; + } + #if defined(UNIT_TEST) scoped_refptr<const PermissionSet> GetTabSpecificPermissionsForTesting( int tab_id) const { @@ -219,8 +222,6 @@ #endif private: - typedef std::map<int, scoped_refptr<const PermissionSet> > TabPermissionsMap; - // Gets the tab-specific host permissions of |tab_id|, or NULL if there // aren't any. scoped_refptr<const PermissionSet> GetTabSpecificPermissions(
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index ac43483..ace05eaf 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp
@@ -1088,6 +1088,8 @@ 'renderer/set_icon_natives.h', 'renderer/static_v8_external_one_byte_string_resource.cc', 'renderer/static_v8_external_one_byte_string_resource.h', + 'renderer/tab_finder.cc', + 'renderer/tab_finder.h', 'renderer/test_features_native_handler.cc', 'renderer/test_features_native_handler.h', 'renderer/user_gestures_native_handler.cc', @@ -1142,6 +1144,7 @@ '../net/net.gyp:net_test_support', '../testing/gtest.gyp:gtest', 'browser/api/api_registration.gyp:extensions_api_registration', + 'common/api/api.gyp:cast_channel_proto', 'common/api/api.gyp:extensions_api', 'extensions_browser', 'extensions_common', @@ -1153,6 +1156,8 @@ ], 'sources': [ # Note: sources list duplicated in GN build. + 'browser/api/cast_channel/test_util.cc', + 'browser/api/cast_channel/test_util.h', 'browser/api/dns/mock_host_resolver_creator.cc', 'browser/api/dns/mock_host_resolver_creator.h', 'browser/api/storage/settings_test_util.cc',
diff --git a/extensions/extensions_tests.gyp b/extensions/extensions_tests.gyp index 9652719..a66e54c 100644 --- a/extensions/extensions_tests.gyp +++ b/extensions/extensions_tests.gyp
@@ -27,7 +27,9 @@ '../third_party/mojo/mojo_edk.gyp:mojo_js_lib', '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', + '../third_party/mojo/mojo_public.gyp:mojo_application_bindings', 'common/api/api.gyp:cast_channel_proto', + 'extensions.gyp:extensions_browser', 'extensions.gyp:extensions_common', 'extensions.gyp:extensions_renderer', 'extensions.gyp:extensions_shell_and_test_pak', @@ -174,6 +176,7 @@ '<(DEPTH)/content/content.gyp:content_app_both', '<(DEPTH)/content/content_shell_and_tests.gyp:content_browser_test_support', '<(DEPTH)/content/content_shell_and_tests.gyp:test_support_content', + '<(DEPTH)/device/bluetooth/bluetooth.gyp:device_bluetooth_mocks', '<(DEPTH)/testing/gmock.gyp:gmock', '<(DEPTH)/testing/gtest.gyp:gtest', ], @@ -182,6 +185,7 @@ ], 'sources': [ 'browser/api/audio/audio_apitest.cc', + 'browser/api/bluetooth_socket/bluetooth_socket_apitest.cc', 'browser/api/dns/dns_apitest.cc', 'browser/api/hid/hid_apitest.cc', 'browser/api/printer_provider/printer_provider_apitest.cc',
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index 63a388e..0d5eee4bb 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn
@@ -145,6 +145,8 @@ "set_icon_natives.h", "static_v8_external_one_byte_string_resource.cc", "static_v8_external_one_byte_string_resource.h", + "tab_finder.cc", + "tab_finder.h", "test_features_native_handler.cc", "test_features_native_handler.h", "user_gestures_native_handler.cc",
diff --git a/extensions/renderer/api/serial/data_receiver_unittest.cc b/extensions/renderer/api/serial/data_receiver_unittest.cc index f699d02..1be15969 100644 --- a/extensions/renderer/api/serial/data_receiver_unittest.cc +++ b/extensions/renderer/api/serial/data_receiver_unittest.cc
@@ -7,10 +7,56 @@ #include "device/serial/data_source_sender.h" #include "device/serial/data_stream.mojom.h" #include "extensions/renderer/api_test_base.h" +#include "gin/dictionary.h" +#include "gin/wrappable.h" #include "grit/extensions_renderer_resources.h" namespace extensions { +class DataReceiverFactory : public gin::Wrappable<DataReceiverFactory> { + public: + using Callback = base::Callback<void( + mojo::InterfaceRequest<device::serial::DataSource>, + mojo::InterfacePtr<device::serial::DataSourceClient>)>; + static gin::Handle<DataReceiverFactory> Create(v8::Isolate* isolate, + const Callback& callback) { + return gin::CreateHandle(isolate, + new DataReceiverFactory(callback, isolate)); + } + + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override { + return Wrappable<DataReceiverFactory>::GetObjectTemplateBuilder(isolate) + .SetMethod("create", &DataReceiverFactory::CreateReceiver); + } + + gin::Dictionary CreateReceiver() { + mojo::InterfacePtr<device::serial::DataSource> sink; + mojo::InterfacePtr<device::serial::DataSourceClient> client; + mojo::InterfaceRequest<device::serial::DataSourceClient> client_request = + mojo::GetProxy(&client); + callback_.Run(mojo::GetProxy(&sink), client.Pass()); + + gin::Dictionary result = gin::Dictionary::CreateEmpty(isolate_); + result.Set("source", sink.PassMessagePipe().release()); + result.Set("client", client_request.PassMessagePipe().release()); + return result; + } + + static gin::WrapperInfo kWrapperInfo; + + private: + DataReceiverFactory(const Callback& callback, v8::Isolate* isolate) + : callback_(callback), isolate_(isolate) {} + + base::Callback<void(mojo::InterfaceRequest<device::serial::DataSource>, + mojo::InterfacePtr<device::serial::DataSourceClient>)> + callback_; + v8::Isolate* isolate_; +}; + +gin::WrapperInfo DataReceiverFactory::kWrapperInfo = {gin::kEmbedderNativeGin}; + // Runs tests defined in extensions/test/data/data_receiver_unittest.js class DataReceiverTest : public ApiTestBase { public: @@ -18,8 +64,13 @@ void SetUp() override { ApiTestBase::SetUp(); - service_provider()->AddService(base::Bind( - &DataReceiverTest::CreateDataSource, base::Unretained(this))); + gin::ModuleRegistry::From(env()->context()->v8_context()) + ->AddBuiltinModule(env()->isolate(), + "device/serial/data_receiver_test_factory", + DataReceiverFactory::Create( + env()->isolate(), + base::Bind(&DataReceiverTest::CreateDataSource, + base::Unretained(this))).ToV8()); } void TearDown() override { @@ -35,12 +86,12 @@ private: void CreateDataSource( - mojo::InterfaceRequest<device::serial::DataSource> request) { - sender_ = mojo::WeakBindToRequest( - new device::DataSourceSender( - base::Bind(&DataReceiverTest::ReadyToSend, base::Unretained(this)), - base::Bind(base::DoNothing)), - &request); + mojo::InterfaceRequest<device::serial::DataSource> request, + mojo::InterfacePtr<device::serial::DataSourceClient> client) { + sender_ = new device::DataSourceSender( + request.Pass(), client.Pass(), + base::Bind(&DataReceiverTest::ReadyToSend, base::Unretained(this)), + base::Bind(base::DoNothing)); } void ReadyToSend(scoped_ptr<device::WritableBuffer> buffer) {
diff --git a/extensions/renderer/api/serial/data_sender_unittest.cc b/extensions/renderer/api/serial/data_sender_unittest.cc index e6a13af..461f012 100644 --- a/extensions/renderer/api/serial/data_sender_unittest.cc +++ b/extensions/renderer/api/serial/data_sender_unittest.cc
@@ -38,12 +38,11 @@ private: void CreateDataSink( mojo::InterfaceRequest<device::serial::DataSink> request) { - receiver_ = mojo::WeakBindToRequest( - new device::DataSinkReceiver( - base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)), - base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)), - base::Bind(base::DoNothing)), - &request); + receiver_ = new device::DataSinkReceiver( + request.Pass(), + base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)), + base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)), + base::Bind(base::DoNothing)); } void ReadyToReceive(scoped_ptr<device::ReadOnlyBuffer> buffer) {
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index fde6bcd..fe8073a 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -79,6 +79,7 @@ #include "extensions/renderer/script_injection_manager.h" #include "extensions/renderer/send_request_natives.h" #include "extensions/renderer/set_icon_natives.h" +#include "extensions/renderer/tab_finder.h" #include "extensions/renderer/test_features_native_handler.h" #include "extensions/renderer/user_gestures_native_handler.h" #include "extensions/renderer/utils_native_handler.h" @@ -804,6 +805,10 @@ IPC_MESSAGE_HANDLER(ExtensionMsg_TransferBlobs, OnTransferBlobs) IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions) + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions, + OnUpdateTabSpecificPermissions) + IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions, + OnClearTabSpecificPermissions) IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, content_watcher_.get(), @@ -1065,7 +1070,7 @@ if (is_webkit_initialized_) { UpdateOriginPermissions( - extension, + extension->url(), extension->permissions_data()->GetEffectiveHostPermissions(), active->effective_hosts()); } @@ -1074,6 +1079,62 @@ UpdateBindings(extension->id()); } +void Dispatcher::OnUpdateTabSpecificPermissions(const GURL& visible_url, + const std::string& extension_id, + const URLPatternSet& new_hosts, + bool update_origin_whitelist, + int tab_id) { + // Check against the URL to avoid races. If we can't find the tab, it's + // because this is an extension's background page (run in a different + // process) - in this case, we can't perform the security check. However, + // since activeTab is only granted via user action, this isn't a huge concern. + content::RenderView* render_view = TabFinder::Find(tab_id); + if (render_view && + render_view->GetWebView()->mainFrame()->document().url() != visible_url) { + return; + } + + const Extension* extension = extensions_.GetByID(extension_id); + if (!extension) + return; + + URLPatternSet old_effective = + extension->permissions_data()->GetEffectiveHostPermissions(); + extension->permissions_data()->UpdateTabSpecificPermissions( + tab_id, + new extensions::PermissionSet(extensions::APIPermissionSet(), + extensions::ManifestPermissionSet(), + new_hosts, + extensions::URLPatternSet())); + + if (is_webkit_initialized_ && update_origin_whitelist) { + UpdateOriginPermissions( + extension->url(), + old_effective, + extension->permissions_data()->GetEffectiveHostPermissions()); + } +} + +void Dispatcher::OnClearTabSpecificPermissions( + const std::vector<std::string>& extension_ids, + bool update_origin_whitelist, + int tab_id) { + for (const std::string& id : extension_ids) { + const Extension* extension = extensions_.GetByID(id); + if (extension) { + URLPatternSet old_effective = + extension->permissions_data()->GetEffectiveHostPermissions(); + extension->permissions_data()->ClearTabSpecificPermissions(tab_id); + if (is_webkit_initialized_ && update_origin_whitelist) { + UpdateOriginPermissions( + extension->url(), + old_effective, + extension->permissions_data()->GetEffectiveHostPermissions()); + } + } + } +} + void Dispatcher::OnUsingWebRequestAPI(bool webrequest_used) { webrequest_used_ = webrequest_used; } @@ -1094,15 +1155,14 @@ delegate_->InitOriginPermissions(extension, IsExtensionActive(extension->id())); UpdateOriginPermissions( - extension, + extension->url(), URLPatternSet(), // No old permissions. extension->permissions_data()->GetEffectiveHostPermissions()); } -void Dispatcher::UpdateOriginPermissions( - const Extension* extension, - const URLPatternSet& old_patterns, - const URLPatternSet& new_patterns) { +void Dispatcher::UpdateOriginPermissions(const GURL& extension_url, + const URLPatternSet& old_patterns, + const URLPatternSet& new_patterns) { static const char* kSchemes[] = { url::kHttpScheme, url::kHttpsScheme, @@ -1117,7 +1177,7 @@ pattern != old_patterns.end(); ++pattern) { if (pattern->MatchesScheme(scheme)) { WebSecurityPolicy::removeOriginAccessWhitelistEntry( - extension->url(), + extension_url, WebString::fromUTF8(scheme), WebString::fromUTF8(pattern->host()), pattern->match_subdomains()); @@ -1128,7 +1188,7 @@ pattern != new_patterns.end(); ++pattern) { if (pattern->MatchesScheme(scheme)) { WebSecurityPolicy::addOriginAccessWhitelistEntry( - extension->url(), + extension_url, WebString::fromUTF8(scheme), WebString::fromUTF8(pattern->host()), pattern->match_subdomains());
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index 021fc943..44cb751 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -189,6 +189,15 @@ void OnTransferBlobs(const std::vector<std::string>& blob_uuids); void OnUnloaded(const std::string& id); void OnUpdatePermissions(const ExtensionMsg_UpdatePermissions_Params& params); + void OnUpdateTabSpecificPermissions(const GURL& visible_url, + const std::string& extension_id, + const URLPatternSet& new_hosts, + bool update_origin_whitelist, + int tab_id); + void OnClearTabSpecificPermissions( + const std::vector<std::string>& extension_ids, + bool update_origin_whitelist, + int tab_id); void OnUsingWebRequestAPI(bool webrequest_used); // UserScriptSetManager::Observer implementation. @@ -200,9 +209,9 @@ // Sets up the host permissions for |extension|. void InitOriginPermissions(const Extension* extension); - // Updates the host permissions for extension to include only those in + // Updates the host permissions for the extension url to include only those in // |new_patterns|, and remove from |old_patterns| that are no longer allowed. - void UpdateOriginPermissions(const Extension* extension, + void UpdateOriginPermissions(const GURL& extension_url, const URLPatternSet& old_patterns, const URLPatternSet& new_patterns);
diff --git a/extensions/renderer/extension_helper.cc b/extensions/renderer/extension_helper.cc index 100d342..f664ae9 100644 --- a/extensions/renderer/extension_helper.cc +++ b/extensions/renderer/extension_helper.cc
@@ -145,10 +145,6 @@ OnAddMessageToConsole) IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed, OnAppWindowClosed) - IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions, - OnUpdateTabSpecificPermissions) - IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions, - OnClearTabSpecificPermissions) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -236,35 +232,4 @@ "onAppWindowClosed"); } -void ExtensionHelper::OnUpdateTabSpecificPermissions( - const GURL& url, - const std::string& extension_id, - const extensions::URLPatternSet& origin_set) { - // Check against the URL to avoid races. - GURL active_url(render_view()->GetWebView()->mainFrame()->document().url()); - if (active_url != url) - return; - - const Extension* extension = dispatcher_->extensions()->GetByID(extension_id); - if (!extension) - return; - - extension->permissions_data()->UpdateTabSpecificPermissions( - tab_id_, - new extensions::PermissionSet(extensions::APIPermissionSet(), - extensions::ManifestPermissionSet(), - origin_set, - extensions::URLPatternSet())); -} - -void ExtensionHelper::OnClearTabSpecificPermissions( - const std::vector<std::string>& extension_ids) { - for (const auto& id : extension_ids) { - const extensions::Extension* extension = - dispatcher_->extensions()->GetByID(id); - if (extension) - extension->permissions_data()->ClearTabSpecificPermissions(tab_id_); - } -} - } // namespace extensions
diff --git a/extensions/renderer/extension_helper.h b/extensions/renderer/extension_helper.h index 3dba0777d..5acc30e 100644 --- a/extensions/renderer/extension_helper.h +++ b/extensions/renderer/extension_helper.h
@@ -76,12 +76,6 @@ const std::string& message); void OnAppWindowClosed(); void OnSetFrameName(const std::string& name); - void OnUpdateTabSpecificPermissions( - const GURL& url, - const std::string& extension_id, - const URLPatternSet& origin_set); - void OnClearTabSpecificPermissions( - const std::vector<std::string>& extension_ids); Dispatcher* dispatcher_;
diff --git a/extensions/renderer/resources/data_receiver.js b/extensions/renderer/resources/data_receiver.js index 0f286be..8df9d25 100644 --- a/extensions/renderer/resources/data_receiver.js +++ b/extensions/renderer/resources/data_receiver.js
@@ -86,15 +86,16 @@ /** * A DataReceiver that receives data from a DataSource. - * @param {!MojoHandle} handle The handle to the DataSource. + * @param {!MojoHandle} source The handle to the DataSource. + * @param {!MojoHandle} client The handle to the DataSourceClient. * @param {number} bufferSize How large a buffer to use. * @param {number} fatalErrorValue The receive error value to report in the * event of a fatal error. * @constructor * @alias module:data_receiver.DataReceiver */ - function DataReceiver(handle, bufferSize, fatalErrorValue) { - this.init_(handle, fatalErrorValue, 0, null, [], false); + function DataReceiver(source, client, bufferSize, fatalErrorValue) { + this.init_(source, client, fatalErrorValue, 0, null, [], false); this.source_.init(bufferSize); } @@ -109,6 +110,7 @@ return; this.shutDown_ = true; this.router_.close(); + this.clientRouter_.close(); if (this.receive_) { this.receive_.dispatchFatalError(this.fatalErrorValue_); this.receive_ = null; @@ -117,7 +119,8 @@ /** * Initialize this DataReceiver. - * @param {!MojoHandle} source A handle to the DataSource + * @param {!MojoHandle} source A handle to the DataSource. + * @param {!MojoHandle} client A handle to the DataSourceClient. * @param {number} fatalErrorValue The error to dispatch in the event of a * fatal error. * @param {number} bytesReceived The number of bytes already received. @@ -128,12 +131,9 @@ * @param {boolean} paused Whether the DataSource is paused. * @private */ - DataReceiver.prototype.init_ = function(source, - fatalErrorValue, - bytesReceived, - pendingError, - pendingData, - paused) { + DataReceiver.prototype.init_ = function(source, client, fatalErrorValue, + bytesReceived, pendingError, + pendingData, paused) { /** * The [Router]{@link module:mojo/public/js/router.Router} for the * connection to the DataSource. @@ -141,11 +141,18 @@ */ this.router_ = new router.Router(source); /** + * The [Router]{@link module:mojo/public/js/router.Router} for the + * connection to the DataSource. + * @private + */ + this.clientRouter_ = new router.Router(client); + /** * The connection to the DataSource. * @private */ this.source_ = new dataStream.DataSource.proxyClass(this.router_); - this.router_.setIncomingReceiver(this); + this.client_ = new dataStream.DataSourceClient.stubClass(this); + this.clientRouter_.setIncomingReceiver(this.client_); /** * The current receive operation. * @type {module:data_receiver~PendingReceive} @@ -202,6 +209,7 @@ } var serialized = new serialization.SerializedDataReceiver(); serialized.source = this.router_.connector_.handle_; + serialized.client = this.clientRouter_.connector_.handle_; serialized.fatal_error_value = this.fatalErrorValue_; serialized.paused = this.paused_; serialized.pending_error = this.pendingError_; @@ -211,6 +219,8 @@ }); this.router_.connector_.handle_ = null; this.router_.close(); + this.clientRouter_.connector_.handle_ = null; + this.clientRouter_.close(); this.shutDown_ = true; return Promise.resolve(serialized); }; @@ -242,12 +252,9 @@ buffer.set(data); pendingData.push(buffer.buffer); }); - this.init_(serialized.source, - serialized.fatal_error_value, - serialized.bytes_received, - serialized.pending_error, - pendingData, - serialized.paused); + this.init_(serialized.source, serialized.client, + serialized.fatal_error_value, serialized.bytes_received, + serialized.pending_error, pendingData, serialized.paused); }; /**
diff --git a/extensions/renderer/resources/data_sender.js b/extensions/renderer/resources/data_sender.js index db259ec..0fe084f 100644 --- a/extensions/renderer/resources/data_sender.js +++ b/extensions/renderer/resources/data_sender.js
@@ -21,8 +21,8 @@ */ function PendingSend(data) { /** - * The remaining data to be sent. - * @type {!ArrayBuffer} + * The data to be sent. + * @type {ArrayBuffer} * @private */ this.data_ = data; @@ -33,12 +33,6 @@ */ this.length_ = data.byteLength; /** - * The number of bytes that have been received by the DataSink. - * @type {number} - * @private - */ - this.bytesReceivedBySink_ = 0; - /** * The promise that will be resolved or rejected when this send completes * or fails, respectively. * @type {!Promise.<number>} @@ -70,29 +64,13 @@ }; /** - * @typedef module:data_sender~PendingSend.ReportBytesResult - * @property {number} bytesUnreported The number of bytes reported that were - * not part of the send. - * @property {boolean} done Whether this send has completed. - * @property {?number} bytesToFlush The number of bytes to flush in the event - * of an error. - */ - - /** * Invoked when the DataSink reports that bytes have been sent. Resolves the * promise returned by * [getPromise()]{@link module:data_sender~PendingSend#getPromise} once all * bytes have been reported as sent. - * @param {number} numBytes The number of bytes sent. - * @return {!module:data_sender~PendingSend.ReportBytesResult} */ - PendingSend.prototype.reportBytesSent = function(numBytes) { - var result = this.reportBytesSentInternal_(numBytes); - if (this.bytesReceivedBySink_ == this.length_) { - result.done = true; - this.successCallback_(this.bytesReceivedBySink_); - } - return result; + PendingSend.prototype.reportBytesSent = function() { + this.successCallback_(this.length_); }; /** @@ -102,84 +80,40 @@ * the nubmer of outstanding bytes. * @param {number} numBytes The number of bytes sent. * @param {number} error The error reported by the DataSink. - * @return {!module:data_sender~PendingSend.ReportBytesResult} */ PendingSend.prototype.reportBytesSentAndError = function(numBytes, error) { - var result = this.reportBytesSentInternal_(numBytes); - // If there are remaining bytes to report, the error occurred after this - // PendingSend so we should report success. - if (result.bytesUnreported > 0) { - this.successCallback_(this.bytesReceivedBySink_); - result.bytesToFlush = 0; - return result; - } - var e = new Error(); e.error = error; - e.bytesSent = this.bytesReceivedBySink_; + e.bytesSent = numBytes; this.errorCallback_(e); - this.done = true; - result.bytesToFlush = - this.length_ - this.data_.byteLength - this.bytesReceivedBySink_; - return result; - }; - - /** - * Updates the internal state in response to a report from the DataSink. - * @param {number} numBytes The number of bytes sent. - * @return {!module:data_sender~PendingSend.ReportBytesResult} - * @private - */ - PendingSend.prototype.reportBytesSentInternal_ = function(numBytes) { - this.bytesReceivedBySink_ += numBytes; - var result = {bytesUnreported: 0}; - if (this.bytesReceivedBySink_ > this.length_) { - result.bytesUnreported = this.bytesReceivedBySink_ - this.length_; - this.bytesReceivedBySink_ = this.length_; - } - result.done = false; - return result; }; /** * Writes pending data into the data pipe. * @param {!DataSink} sink The DataSink to receive the data. - * @param {number} availableBufferCapacity The maximum number of bytes to - * send. * @return {!Object} result The send result. * @return {boolean} result.completed Whether all of the pending data was * sent. - * @return {number} result.remainingBufferCapacity The remaining send buffer - * capacity. */ - PendingSend.prototype.sendData = function(sink, availableBufferCapacity) { - var numBytesToSend = - Math.min(availableBufferCapacity, this.data_.byteLength); - sink.onData(new Uint8Array(this.data_, 0, numBytesToSend)); - this.data_ = this.data_.slice(numBytesToSend); - return { - completed: this.data_.byteLength == 0, - remainingBufferCapacity: availableBufferCapacity - numBytesToSend, - }; + PendingSend.prototype.sendData = function(sink) { + var dataSent = sink.onData(new Uint8Array(this.data_)); + this.data_ = null; + return dataSent; }; /** * A DataSender that sends data to a DataSink. - * @param {!MojoHandle} handle The handle to the DataSink. + * @param {!MojoHandle} sink The handle to the DataSink. * @param {number} bufferSize How large a buffer to use for data. * @param {number} fatalErrorValue The send error value to report in the * event of a fatal error. * @constructor * @alias module:data_sender.DataSender */ - function DataSender(handle, bufferSize, fatalErrorValue) { - this.init_(handle, fatalErrorValue, bufferSize); - this.sink_.init(bufferSize); + function DataSender(sink, bufferSize, fatalErrorValue) { + this.init_(sink, fatalErrorValue); } - DataSender.prototype = - $Object.create(dataStreamMojom.DataSinkClient.stubClass.prototype); - /** * Closes this DataSender. */ @@ -188,10 +122,6 @@ return; this.shutDown_ = true; this.router_.close(); - while (this.pendingSends_.length) { - this.pendingSends_.pop().reportBytesSentAndError( - 0, this.fatalErrorValue_); - } while (this.sendsAwaitingAck_.length) { this.sendsAwaitingAck_.pop().reportBytesSentAndError( 0, this.fatalErrorValue_); @@ -201,13 +131,12 @@ /** * Initialize this DataSender. - * @param {!MojoHandle} sink A handle to the DataSink + * @param {!MojoHandle} sink A handle to the DataSink. * @param {number} fatalErrorValue The error to dispatch in the event of a * fatal error. - * @param {number} bufferSize The size of the send buffer. * @private */ - DataSender.prototype.init_ = function(sink, fatalErrorValue, bufferSize) { + DataSender.prototype.init_ = function(sink, fatalErrorValue) { /** * The error to be dispatched in the event of a fatal error. * @const {number} @@ -231,13 +160,6 @@ * @private */ this.sink_ = new dataStreamMojom.DataSink.proxyClass(this.router_); - this.router_.setIncomingReceiver(this); - /** - * A queue of sends that have not fully sent their data to the DataSink. - * @type {!module:data_sender~PendingSend[]} - * @private - */ - this.pendingSends_ = []; /** * A queue of sends that have sent their data to the DataSink, but have not * been received by the DataSink. @@ -260,12 +182,6 @@ * @private */ this.cancelPromise_ = null; - /** - * The available send buffer capacity. - * @type {number} - * @private - */ - this.availableBufferCapacity_ = bufferSize; }; /** @@ -281,7 +197,7 @@ return Promise.resolve(null); var readyToSerialize = Promise.resolve(); - if (this.pendingSends_.length || this.sendsAwaitingAck_.length) { + if (this.sendsAwaitingAck_.length) { if (this.pendingCancel_) readyToSerialize = this.cancelPromise_; else @@ -291,7 +207,6 @@ var serialized = new serialization.SerializedDataSender(); serialized.sink = this.router_.connector_.handle_; serialized.fatal_error_value = this.fatalErrorValue_; - serialized.buffer_size = this.availableBufferCapacity_; this.router_.connector_.handle_ = null; this.router_.close(); this.shutDown_ = true; @@ -320,8 +235,8 @@ this.shutDown_ = true; return; } - this.init_( - serialized.sink, serialized.fatal_error_value, serialized.buffer_size); + this.init_(serialized.sink, serialized.fatal_error_value, + serialized.buffer_size); }; /** @@ -338,22 +253,11 @@ if (this.pendingCancel_) throw new Error('Cancel in progress'); var send = new PendingSend(data); - this.pendingSends_.push(send); - this.sendInternal_(); + this.sendsAwaitingAck_.push(send); + send.sendData(this.sink_).then(this.reportBytesSentAndError.bind(this)); return send.getPromise(); }; - DataSender.prototype.sendInternal_ = function() { - while (this.pendingSends_.length && this.availableBufferCapacity_) { - var result = this.pendingSends_[0].sendData( - this.sink_, this.availableBufferCapacity_); - this.availableBufferCapacity_ = result.remainingBufferCapacity; - if (result.completed) { - this.sendsAwaitingAck_.push(this.pendingSends_.shift()); - } - } - }; - /** * Requests the cancellation of any in-progress sends. Calls to * [send()]{@link module:data_sender.DataSender#send} will fail until the @@ -368,7 +272,7 @@ throw new Error('DataSender has been closed'); if (this.pendingCancel_) throw new Error('Cancel already in progress'); - if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) + if (this.sendsAwaitingAck_.length == 0) return Promise.resolve(); this.sink_.cancel(error); @@ -392,28 +296,17 @@ /** * Invoked by the DataSink to report that data has been successfully sent. - * @param {number} numBytes The number of bytes sent. * @private */ - DataSender.prototype.reportBytesSent = function(numBytes) { - this.availableBufferCapacity_ += numBytes; - while (numBytes > 0 && this.sendsAwaitingAck_.length) { - var result = this.sendsAwaitingAck_[0].reportBytesSent(numBytes); - numBytes = result.bytesUnreported; - if (result.done) - this.sendsAwaitingAck_.shift(); - } - if (numBytes > 0 && this.pendingSends_.length) { - var result = this.pendingSends_[0].reportBytesSent(numBytes); - numBytes = result.bytesUnreported; - } + DataSender.prototype.reportBytesSent = function() { + var result = this.sendsAwaitingAck_[0].reportBytesSent(); + this.sendsAwaitingAck_.shift(); + // A cancel is completed when all of the sends that were in progress have // completed or failed. This is the case where all sends complete // successfully. - if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) + if (this.sendsAwaitingAck_.length == 0) this.callCancelCallback_(); - - this.sendInternal_(); }; /** @@ -422,26 +315,20 @@ * @param {number} error The error reported by the DataSink. * @private */ - DataSender.prototype.reportBytesSentAndError = function(numBytes, error) { - this.availableBufferCapacity_ += numBytes; - while (this.sendsAwaitingAck_.length) { - var result = this.sendsAwaitingAck_[0].reportBytesSentAndError( - numBytes, error); - numBytes = result.bytesUnreported; - this.sendsAwaitingAck_.shift(); - this.availableBufferCapacity_ += result.bytesToFlush; + DataSender.prototype.reportBytesSentAndError = function(result) { + var numBytes = result.bytes_sent; + var error = result.error; + if (!error) { + this.reportBytesSent(); + return; } - while (this.pendingSends_.length) { - var result = this.pendingSends_[0].reportBytesSentAndError( - numBytes, error); - numBytes = result.bytesUnreported; - this.pendingSends_.shift(); - // Note: Only the first PendingSend in |pendingSends_| will have data to - // flush as only the first can have sent data to the DataSink. - this.availableBufferCapacity_ += result.bytesToFlush; - } + var result = + this.sendsAwaitingAck_[0].reportBytesSentAndError(numBytes, error); + this.sendsAwaitingAck_.shift(); + if (this.sendsAwaitingAck_.length) + return; this.callCancelCallback_(); - return Promise.resolve(); + this.sink_.clearError(); }; return {DataSender: DataSender};
diff --git a/extensions/renderer/resources/serial_service.js b/extensions/renderer/resources/serial_service.js index d0f29761..21efb7b 100644 --- a/extensions/renderer/resources/serial_service.js +++ b/extensions/renderer/resources/serial_service.js
@@ -134,14 +134,16 @@ clientOptions.bufferSize = options.bufferSize; }; - function Connection(connection, router, receivePipe, sendPipe, id, options) { + function Connection(connection, router, receivePipe, receiveClientPipe, + sendPipe, id, options) { var state = new serialization.ConnectionState(); state.connectionId = id; updateClientOptions(state, options); var receiver = new dataReceiver.DataReceiver( - receivePipe, state.bufferSize, serialMojom.ReceiveError.DISCONNECTED); - var sender = new dataSender.DataSender( - sendPipe, state.bufferSize, serialMojom.SendError.DISCONNECTED); + receivePipe, receiveClientPipe, state.bufferSize, + serialMojom.ReceiveError.DISCONNECTED); + var sender = new dataSender.DataSender(sendPipe, state.bufferSize, + serialMojom.SendError.DISCONNECTED); this.init_(state, connection, router, @@ -188,11 +190,13 @@ var pipe = core.createMessagePipe(); var sendPipe = core.createMessagePipe(); var receivePipe = core.createMessagePipe(); + var receivePipeClient = core.createMessagePipe(); service.connect(path, serviceOptions, pipe.handle0, sendPipe.handle0, - receivePipe.handle0); + receivePipe.handle0, + receivePipeClient.handle0); var router = new routerModule.Router(pipe.handle1); var connection = new serialMojom.Connection.proxyClass(router); return connection.getInfo().then(convertServiceInfo).then(function(info) { @@ -201,6 +205,7 @@ router.close(); core.close(sendPipe.handle1); core.close(receivePipe.handle1); + core.close(receivePipeClient.handle1); throw e; }).then(function(results) { var info = results[0]; @@ -208,6 +213,7 @@ var serialConnectionClient = new Connection(connection, router, receivePipe.handle1, + receivePipeClient.handle1, sendPipe.handle1, id, options);
diff --git a/chrome/renderer/extensions/tab_finder.cc b/extensions/renderer/tab_finder.cc similarity index 94% rename from chrome/renderer/extensions/tab_finder.cc rename to extensions/renderer/tab_finder.cc index 6884622..ca8b602 100644 --- a/chrome/renderer/extensions/tab_finder.cc +++ b/extensions/renderer/tab_finder.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/tab_finder.h" +#include "extensions/renderer/tab_finder.h" #include "content/public/renderer/render_view.h" #include "extensions/renderer/extension_helper.h"
diff --git a/chrome/renderer/extensions/tab_finder.h b/extensions/renderer/tab_finder.h similarity index 85% rename from chrome/renderer/extensions/tab_finder.h rename to extensions/renderer/tab_finder.h index 28f0b7a..4d326aad 100644 --- a/chrome/renderer/extensions/tab_finder.h +++ b/extensions/renderer/tab_finder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_TAB_FINDER_H_ -#define CHROME_RENDERER_EXTENSIONS_TAB_FINDER_H_ +#ifndef EXTENSIONS_RENDERER_TAB_FINDER_H_ +#define EXTENSIONS_RENDERER_TAB_FINDER_H_ #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -36,4 +36,4 @@ } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_TAB_FINDER_H_ +#endif // EXTENSIONS_RENDERER_TAB_FINDER_H_
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index a1d362a..a251765 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -50,6 +50,8 @@ "//skia", "//third_party/WebKit/public:blink", "//third_party/mojo/src/mojo/edk/system", + "//ui/base", + "//ui/base/ime", "//ui/wm", "//v8", ]
diff --git a/extensions/shell/app_shell.gyp b/extensions/shell/app_shell.gyp index 1666e43..0b7255e 100644 --- a/extensions/shell/app_shell.gyp +++ b/extensions/shell/app_shell.gyp
@@ -44,6 +44,8 @@ '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/third_party/WebKit/public/blink.gyp:blink', '<(DEPTH)/third_party/mojo/mojo_edk.gyp:mojo_system_impl', + '<(DEPTH)/ui/base/ime/ui_base_ime.gyp:ui_base_ime', + '<(DEPTH)/ui/base/ui_base.gyp:ui_base', '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', ], 'export_dependent_settings': [
diff --git a/extensions/shell/browser/media_capture_util.cc b/extensions/shell/browser/media_capture_util.cc index 30e3fb6..d8a11a8 100644 --- a/extensions/shell/browser/media_capture_util.cc +++ b/extensions/shell/browser/media_capture_util.cc
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/logging.h" #include "content/public/browser/media_capture_devices.h" +#include "extensions/common/extension.h" #include "extensions/common/permissions/permissions_data.h" using content::MediaCaptureDevices;
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/connect/manifest.json b/extensions/test/data/api_test/bluetooth_socket/connect/manifest.json similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/connect/manifest.json rename to extensions/test/data/api_test/bluetooth_socket/connect/manifest.json
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/connect/runtest.js b/extensions/test/data/api_test/bluetooth_socket/connect/runtest.js similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/connect/runtest.js rename to extensions/test/data/api_test/bluetooth_socket/connect/runtest.js
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/listen/manifest.json b/extensions/test/data/api_test/bluetooth_socket/listen/manifest.json similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/listen/manifest.json rename to extensions/test/data/api_test/bluetooth_socket/listen/manifest.json
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/listen/runtest.js b/extensions/test/data/api_test/bluetooth_socket/listen/runtest.js similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/listen/runtest.js rename to extensions/test/data/api_test/bluetooth_socket/listen/runtest.js
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/permission_denied/manifest.json b/extensions/test/data/api_test/bluetooth_socket/permission_denied/manifest.json similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/permission_denied/manifest.json rename to extensions/test/data/api_test/bluetooth_socket/permission_denied/manifest.json
diff --git a/chrome/test/data/extensions/api_test/bluetooth_socket/permission_denied/runtest.js b/extensions/test/data/api_test/bluetooth_socket/permission_denied/runtest.js similarity index 100% rename from chrome/test/data/extensions/api_test/bluetooth_socket/permission_denied/runtest.js rename to extensions/test/data/api_test/bluetooth_socket/permission_denied/runtest.js
diff --git a/extensions/test/data/api_test/usb/get_user_selected_devices/background.js b/extensions/test/data/api_test/usb/get_user_selected_devices/background.js new file mode 100644 index 0000000..1b4e54ba --- /dev/null +++ b/extensions/test/data/api_test/usb/get_user_selected_devices/background.js
@@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var device_from_user = undefined; + +chrome.test.runWithUserGesture(function() { + chrome.usb.getDevices({}, function(devices) { + chrome.test.assertEq(0, devices.length); + chrome.usb.getUserSelectedDevices({ multiple: false }, function(devices) { + chrome.test.assertEq(1, devices.length); + device_from_user = devices[0]; + chrome.usb.openDevice(device_from_user, function(connection) { + chrome.usb.closeDevice(connection); + chrome.test.sendMessage("opened_device"); + }); + }); + }); +}); + +chrome.usb.onDeviceRemoved.addListener(function(device) { + if (device.device == device_from_user.device) { + chrome.test.sendMessage("success"); + } else { + chrome.test.sendMessage("failure"); + } +});
diff --git a/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json b/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json new file mode 100644 index 0000000..11e58c938 --- /dev/null +++ b/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json
@@ -0,0 +1,13 @@ +{ + "name": "chrome.usb.getUserSelectedDevices", + "version": "0.1", + "description": "browser test for chrome.usb.getUserSelectedDevices", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "usb" + ] +}
diff --git a/extensions/test/data/data_receiver_unittest.js b/extensions/test/data/data_receiver_unittest.js index 75d3ca76f..b46189a4 100644 --- a/extensions/test/data/data_receiver_unittest.js +++ b/extensions/test/data/data_receiver_unittest.js
@@ -13,17 +13,14 @@ // Returns a promise to a newly created DataReceiver. function createReceiver() { return Promise.all([ - requireAsync('content/public/renderer/service_provider'), requireAsync('data_receiver'), - requireAsync('device/serial/data_stream.mojom'), + requireAsync('device/serial/data_receiver_test_factory'), ]).then(function(modules) { - var serviceProvider = modules[0]; - var dataReceiver = modules[1]; - var dataStream = modules[2]; - return new dataReceiver.DataReceiver( - serviceProvider.connectToService(dataStream.DataSource.name), - BUFFER_SIZE, - FATAL_ERROR); + var dataReceiver = modules[0]; + var factory = modules[1]; + var receiver = factory.create(); + return new dataReceiver.DataReceiver(receiver.source, receiver.client, + BUFFER_SIZE, FATAL_ERROR); }); }
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 21598a8..daa04f1 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc
@@ -254,6 +254,7 @@ #endif isolate_data_.reset(); isolate_->Dispose(); + isolate_ = NULL; } // static
diff --git a/google_apis/gcm/engine/connection_factory_impl.cc b/google_apis/gcm/engine/connection_factory_impl.cc index 218f833..a8ec37fe 100644 --- a/google_apis/gcm/engine/connection_factory_impl.cc +++ b/google_apis/gcm/engine/connection_factory_impl.cc
@@ -7,6 +7,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/metrics/sparse_histogram.h" +#include "base/profiler/scoped_tracker.h" #include "google_apis/gcm/engine/connection_handler_impl.h" #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" #include "google_apis/gcm/protocol/mcs.pb.h" @@ -342,6 +343,10 @@ } void ConnectionFactoryImpl::OnConnectDone(int result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455884 ConnectionFactoryImpl::OnConnectDone")); if (result != net::OK) { // If the connection fails, try another proxy. result = ReconsiderProxyAfterError(result);
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 88bed32..73fb1eb 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -86,6 +86,8 @@ #define glGenTransformFeedbacks GLES2_GET_FUN(GenTransformFeedbacks) #define glGetActiveAttrib GLES2_GET_FUN(GetActiveAttrib) #define glGetActiveUniform GLES2_GET_FUN(GetActiveUniform) +#define glGetActiveUniformBlockiv GLES2_GET_FUN(GetActiveUniformBlockiv) +#define glGetActiveUniformBlockName GLES2_GET_FUN(GetActiveUniformBlockName) #define glGetAttachedShaders GLES2_GET_FUN(GetAttachedShaders) #define glGetAttribLocation GLES2_GET_FUN(GetAttribLocation) #define glGetBooleanv GLES2_GET_FUN(GetBooleanv) @@ -109,6 +111,7 @@ #define glGetString GLES2_GET_FUN(GetString) #define glGetTexParameterfv GLES2_GET_FUN(GetTexParameterfv) #define glGetTexParameteriv GLES2_GET_FUN(GetTexParameteriv) +#define glGetUniformBlockIndex GLES2_GET_FUN(GetUniformBlockIndex) #define glGetUniformfv GLES2_GET_FUN(GetUniformfv) #define glGetUniformiv GLES2_GET_FUN(GetUniformiv) #define glGetUniformLocation GLES2_GET_FUN(GetUniformLocation) @@ -148,6 +151,7 @@ #define glShaderSource GLES2_GET_FUN(ShaderSource) #define glShallowFinishCHROMIUM GLES2_GET_FUN(ShallowFinishCHROMIUM) #define glShallowFlushCHROMIUM GLES2_GET_FUN(ShallowFlushCHROMIUM) +#define glOrderingBarrierCHROMIUM GLES2_GET_FUN(OrderingBarrierCHROMIUM) #define glStencilFunc GLES2_GET_FUN(StencilFunc) #define glStencilFuncSeparate GLES2_GET_FUN(StencilFuncSeparate) #define glStencilMask GLES2_GET_FUN(StencilMask) @@ -188,6 +192,7 @@ #define glUniform4iv GLES2_GET_FUN(Uniform4iv) #define glUniform4ui GLES2_GET_FUN(Uniform4ui) #define glUniform4uiv GLES2_GET_FUN(Uniform4uiv) +#define glUniformBlockBinding GLES2_GET_FUN(UniformBlockBinding) #define glUniformMatrix2fv GLES2_GET_FUN(UniformMatrix2fv) #define glUniformMatrix2x3fv GLES2_GET_FUN(UniformMatrix2x3fv) #define glUniformMatrix2x4fv GLES2_GET_FUN(UniformMatrix2x4fv) @@ -254,6 +259,7 @@ #define glRateLimitOffscreenContextCHROMIUM \ GLES2_GET_FUN(RateLimitOffscreenContextCHROMIUM) #define glGetProgramInfoCHROMIUM GLES2_GET_FUN(GetProgramInfoCHROMIUM) +#define glGetUniformBlocksCHROMIUM GLES2_GET_FUN(GetUniformBlocksCHROMIUM) #define glCreateStreamTextureCHROMIUM GLES2_GET_FUN(CreateStreamTextureCHROMIUM) #define glCreateImageCHROMIUM GLES2_GET_FUN(CreateImageCHROMIUM) #define glDestroyImageCHROMIUM GLES2_GET_FUN(DestroyImageCHROMIUM)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index b0884b6..5c90330 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1313,6 +1313,21 @@ 'GL_MOUSE_POSITION_CHROMIUM', ], }, + 'UniformBlockParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_UNIFORM_BLOCK_BINDING', + 'GL_UNIFORM_BLOCK_DATA_SIZE', + 'GL_UNIFORM_BLOCK_NAME_LENGTH', + 'GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS', + 'GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES', + 'GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER', + 'GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER', + ], + 'invalid': [ + 'GL_NEAREST', + ], + }, 'VertexAttribType': { 'type': 'GLenum', 'valid': [ @@ -1508,6 +1523,10 @@ 'type': 'Bind', 'id_mapping': [ 'Buffer' ], 'gen_func': 'GenBuffersARB', + 'valid_args': { + '3': '4', + '4': '4' + }, 'unsafe': True, }, 'BindFramebuffer': { @@ -2030,6 +2049,21 @@ 'uint32_t type', ], }, + 'GetActiveUniformBlockiv': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'result': ['SizedResult<GLint>'], + 'unsafe': True, + }, + 'GetActiveUniformBlockName': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, GLuint index, uint32_t name_bucket_id, ' + 'void* result', + 'result': ['int32_t'], + 'unsafe': True, + }, 'GetAttachedShaders': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -2200,7 +2234,27 @@ 'get_len_enum': 'GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE', 'unit_test': False, 'extension': True, - }, + }, + 'GetUniformBlockIndex': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, uint32_t name_bucket_id, GLuint* index', + 'result': ['GLuint'], + 'error_return': 'GL_INVALID_INDEX', + 'unsafe': True, + }, + 'GetUniformBlocksCHROMIUM': { + 'type': 'Custom', + 'expectation': False, + 'impl_func': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + 'cmd_args': 'GLidProgram program, uint32_t bucket_id', + 'result': ['uint32_t'], + 'unsafe': True, + }, 'GetUniformfv': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -2702,6 +2756,11 @@ 'count': 12, 'unsafe': True, }, + 'UniformBlockBinding': { + 'type': 'Custom', + 'impl_func': False, + 'unsafe': True, + }, 'UnmapBufferCHROMIUM': { 'gen_cmd': False, 'extension': True, @@ -3021,6 +3080,13 @@ 'chromium': True, 'client_test': False, }, + 'OrderingBarrierCHROMIUM': { + 'impl_func': False, + 'gen_cmd': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + }, 'TraceBeginCHROMIUM': { 'type': 'Custom', 'impl_func': False, @@ -6440,90 +6506,7 @@ }) for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) - size_code_block = """ // Compute the total size. - base::CheckedNumeric<size_t> total_size = count; - total_size += 1; - total_size *= sizeof(GLint); - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); - return; - } - size_t header_size = total_size.ValueOrDefault(0); - std::vector<GLint> header(count + 1); - header[0] = static_cast<GLint>(count); - for (GLsizei ii = 0; ii < count; ++ii) { - GLint len = 0; - if (%(data)s[ii]) {""" - if length_arg == None: - size_code_block += """ - len = static_cast<GLint>(strlen(%(data)s[ii]));""" - else: - size_code_block += """ - len = (%(length)s && %(length)s[ii] >= 0) ? - %(length)s[ii] : base::checked_cast<GLint>(strlen(%(data)s[ii]));""" - size_code_block += """ - } - total_size += len; - total_size += 1; // NULL at the end of each char array. - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); - return; - } - header[ii + 1] = len; -} -""" - file.Write(size_code_block % { - 'data': data_arg.name, - 'length': length_arg.name if not length_arg == None else '', - 'func_name': func.name, - }) - data_code_block = """ // Pack data into a bucket on the service. - helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); - size_t offset = 0; - for (GLsizei ii = 0; ii <= count; ++ii) { - const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : - %(data)s[ii - 1]; - base::CheckedNumeric<size_t> checked_size = (ii == 0) ? header_size : - static_cast<size_t>(header[ii]); - if (ii > 0) { - checked_size += 1; // NULL in the end. - } - if (!checked_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); - return; - } - size_t size = checked_size.ValueOrDefault(0); - while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid() || buffer.size() == 0) { - SetGLError(GL_OUT_OF_MEMORY, "gl%(func_name)s", "too large"); - return; - } - size_t copy_size = buffer.size(); - if (ii > 0 && buffer.size() == size) - --copy_size; - if (copy_size) - memcpy(buffer.address(), src, copy_size); - if (copy_size < buffer.size()) { - // Append NULL in the end. - DCHECK(copy_size + 1 == buffer.size()); - char* str = reinterpret_cast<char*>(buffer.address()); - str[copy_size] = 0; - } - helper_->SetBucketData(kResultBucketId, offset, buffer.size(), - buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - src += buffer.size(); - size -= buffer.size(); - } - } - DCHECK_EQ(total_size.ValueOrDefault(0), offset); -""" - file.Write(data_code_block % { - 'data': data_arg.name, - 'length': length_arg.name if not length_arg == None else '', - 'func_name': func.name, - }) + bucket_args = [] for arg in func.GetOriginalArgs(): if arg.name == 'count' or arg == self.__GetLengthArg(func): @@ -6532,12 +6515,22 @@ bucket_args.append('kResultBucketId') else: bucket_args.append(arg.name) - file.Write(" helper_->%sBucket(%s);\n" % - (func.name, ", ".join(bucket_args))) - file.Write(" helper_->SetBucketSize(kResultBucketId, 0);"); - file.Write(" CheckGLError();\n") - file.Write("}\n") - file.Write("\n") + code_block = """ + if (!PackStringsToBucket(count, %(data)s, %(length)s, "gl%(func_name)s")) { + return; + } + helper_->%(func_name)sBucket(%(bucket_args)s); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + +""" + file.Write(code_block % { + 'data': data_arg.name, + 'length': length_arg.name if not length_arg == None else 'NULL', + 'func_name': func.name, + 'bucket_args': ', '.join(bucket_args), + }) def WriteGLES2ImplementationUnitTest(self, func, file): """Overrriden from TypeHandler.""" @@ -7969,48 +7962,21 @@ def WriteGetCode(self, file): """Overridden from Argument.""" code = """ - const size_t kMinBucketSize = sizeof(GLint); - // Each string has at least |length| in the header and a NUL character. - const size_t kMinStringSize = sizeof(GLint) + 1; Bucket* bucket = GetBucket(c.%(name)s); if (!bucket) { return error::kInvalidArguments; } - const size_t bucket_size = bucket->size(); - if (bucket_size < kMinBucketSize) { + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { return error::kInvalidArguments; } - const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size); - const GLint* header = reinterpret_cast<const GLint*>(bucket_data); - GLsizei count = static_cast<GLsizei>(header[0]); - if (count < 0) { - return error::kInvalidArguments; - } - const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; - if (max_count < static_cast<size_t>(count)) { - return error::kInvalidArguments; - } - const GLint* length = header + 1; - scoped_ptr<const char*[]> strs; - if (count > 0) - strs.reset(new const char*[count]); - const char** %(original_name)s = strs.get(); - base::CheckedNumeric<size_t> total_size = sizeof(GLint); - total_size *= count + 1; // Header size. - if (!total_size.IsValid()) - return error::kInvalidArguments; - for (GLsizei ii = 0; ii < count; ++ii) { - %(original_name)s[ii] = bucket_data + total_size.ValueOrDefault(0); - total_size += length[ii]; - total_size += 1; // NUL char at the end of each char array. - if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || - %(original_name)s[ii][length[ii]] != 0) { - return error::kInvalidArguments; - } - } - if (total_size.ValueOrDefault(0) != bucket_size) { - return error::kInvalidArguments; - } + const char** %(original_name)s = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; """ file.Write(code % { 'name': self.name,
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc index 3c50f6b2..258e821 100644 --- a/gpu/command_buffer/client/client_test_helper.cc +++ b/gpu/command_buffer/client/client_test_helper.cc
@@ -130,6 +130,10 @@ FlushHelper(put_offset); } +void MockClientCommandBuffer::OrderingBarrier(int32 put_offset) { + FlushHelper(put_offset); +} + void MockClientCommandBuffer::DelegateToFake() { ON_CALL(*this, DestroyTransferBuffer(_)) .WillByDefault(Invoke(
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h index 6778a831..111c4f4 100644 --- a/gpu/command_buffer/client/client_test_helper.h +++ b/gpu/command_buffer/client/client_test_helper.h
@@ -70,6 +70,7 @@ MOCK_METHOD1(DestroyTransferBuffer, void(int32 id)); virtual void Flush(int32 put_offset) override; + virtual void OrderingBarrier(int32 put_offset) override; void DelegateToFake(); }; @@ -80,6 +81,7 @@ virtual ~MockClientCommandBufferMockFlush(); MOCK_METHOD1(Flush, void(int32 put_offset)); + MOCK_METHOD1(OrderingBarrier, void(int32 put_offset)); void DelegateToFake(); };
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index a99201e..038ba41f 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -150,7 +150,7 @@ if (put_ == total_entry_count_) put_ = 0; - if (usable() && last_put_sent_ != put_) { + if (usable()) { last_flush_time_ = base::TimeTicks::Now(); last_put_sent_ = put_; command_buffer_->Flush(put_); @@ -159,6 +159,18 @@ } } +void CommandBufferHelper::OrderingBarrier() { + // Wrap put_ before setting the barrier. + if (put_ == total_entry_count_) + put_ = 0; + + if (usable()) { + command_buffer_->OrderingBarrier(put_); + ++flush_generation_; + CalcImmediateEntries(0); + } +} + #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) void CommandBufferHelper::PeriodicFlushCheck() { base::TimeTicks current_time = base::TimeTicks::Now();
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h index 053c1c9..3f7fba7 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -66,6 +66,11 @@ // returns, the command buffer service is aware of all pending commands. void Flush(); + // Ensures that commands up to the put pointer will be processed in the + // command buffer service before any future commands on other command buffers + // sharing a channel. + void OrderingBarrier(); + // Waits until all the commands have been executed. Returns whether it // was successful. The function will fail if the command buffer service has // disconnected. @@ -322,6 +327,7 @@ int32 token_; int32 put_; int32 last_put_sent_; + int32 last_barrier_put_sent_; #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) int commands_issued_;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc index 2e807e22a..ac83da5 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -709,4 +709,64 @@ EXPECT_EQ(error::kNoError, GetError()); } +TEST_F(CommandBufferHelperTest, TestOrderingBarrierFlushGeneration) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + // Generation should change after OrderingBarrier() but not before. + uint32 gen1, gen2, gen3; + + gen1 = GetHelperFlushGeneration(); + AddUniqueCommandWithExpect(error::kNoError, 2); + gen2 = GetHelperFlushGeneration(); + helper_->OrderingBarrier(); + gen3 = GetHelperFlushGeneration(); + EXPECT_EQ(gen2, gen1); + EXPECT_NE(gen3, gen2); + + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_EQ(error::kNoError, GetError()); +} + +// Expect Flush() to always call CommandBuffer::Flush(). +TEST_F(CommandBufferHelperTest, TestFlushToCommandBuffer) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + int flush_count1, flush_count2, flush_count3; + + flush_count1 = command_buffer_->FlushCount(); + AddUniqueCommandWithExpect(error::kNoError, 2); + helper_->Flush(); + flush_count2 = command_buffer_->FlushCount(); + helper_->Flush(); + flush_count3 = command_buffer_->FlushCount(); + + EXPECT_EQ(flush_count2, flush_count1 + 1); + EXPECT_EQ(flush_count3, flush_count2 + 1); +} + +// Expect OrderingBarrier() to always call CommandBuffer::OrderingBarrier(). +TEST_F(CommandBufferHelperTest, TestOrderingBarrierToCommandBuffer) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + int flush_count1, flush_count2, flush_count3; + + flush_count1 = command_buffer_->FlushCount(); + AddUniqueCommandWithExpect(error::kNoError, 2); + helper_->OrderingBarrier(); + flush_count2 = command_buffer_->FlushCount(); + helper_->OrderingBarrier(); + flush_count3 = command_buffer_->FlushCount(); + + EXPECT_EQ(flush_count2, flush_count1 + 1); + EXPECT_EQ(flush_count3, flush_count2 + 1); +} + } // namespace gpu
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc index 0f15f1d5e..f10695ed 100644 --- a/gpu/command_buffer/client/gl_in_process_context.cc +++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -68,7 +68,7 @@ size_t GetMappedMemoryLimit() override; #if defined(OS_ANDROID) - virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( + scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( uint32 stream_id) override; #endif
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 503fff0..bd0f0dd1 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -338,6 +338,20 @@ gles2::GetGLContext()->GetActiveUniform(program, index, bufsize, length, size, type, name); } +void GLES2GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) { + gles2::GetGLContext()->GetActiveUniformBlockiv(program, index, pname, params); +} +void GLES2GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) { + gles2::GetGLContext()->GetActiveUniformBlockName(program, index, bufsize, + length, name); +} void GLES2GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -431,6 +445,9 @@ void GLES2GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { gles2::GetGLContext()->GetTexParameteriv(target, pname, params); } +GLuint GLES2GetUniformBlockIndex(GLuint program, const char* name) { + return gles2::GetGLContext()->GetUniformBlockIndex(program, name); +} void GLES2GetUniformfv(GLuint program, GLint location, GLfloat* params) { gles2::GetGLContext()->GetUniformfv(program, location, params); } @@ -578,6 +595,9 @@ void GLES2ShallowFlushCHROMIUM() { gles2::GetGLContext()->ShallowFlushCHROMIUM(); } +void GLES2OrderingBarrierCHROMIUM() { + gles2::GetGLContext()->OrderingBarrierCHROMIUM(); +} void GLES2StencilFunc(GLenum func, GLint ref, GLuint mask) { gles2::GetGLContext()->StencilFunc(func, ref, mask); } @@ -759,6 +779,9 @@ void GLES2Uniform4uiv(GLint location, GLsizei count, const GLuint* v) { gles2::GetGLContext()->Uniform4uiv(location, count, v); } +void GLES2UniformBlockBinding(GLuint program, GLuint index, GLuint binding) { + gles2::GetGLContext()->UniformBlockBinding(program, index, binding); +} void GLES2UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -1038,6 +1061,12 @@ void* info) { gles2::GetGLContext()->GetProgramInfoCHROMIUM(program, bufsize, size, info); } +void GLES2GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + gles2::GetGLContext()->GetUniformBlocksCHROMIUM(program, bufsize, size, info); +} GLuint GLES2CreateStreamTextureCHROMIUM(GLuint texture) { return gles2::GetGLContext()->CreateStreamTextureCHROMIUM(texture); } @@ -1539,6 +1568,14 @@ reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniform), }, { + "glGetActiveUniformBlockiv", + reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniformBlockiv), + }, + { + "glGetActiveUniformBlockName", + reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniformBlockName), + }, + { "glGetAttachedShaders", reinterpret_cast<GLES2FunctionPointer>(glGetAttachedShaders), }, @@ -1628,6 +1665,10 @@ reinterpret_cast<GLES2FunctionPointer>(glGetTexParameteriv), }, { + "glGetUniformBlockIndex", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformBlockIndex), + }, + { "glGetUniformfv", reinterpret_cast<GLES2FunctionPointer>(glGetUniformfv), }, @@ -1784,6 +1825,10 @@ reinterpret_cast<GLES2FunctionPointer>(glShallowFlushCHROMIUM), }, { + "glOrderingBarrierCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glOrderingBarrierCHROMIUM), + }, + { "glStencilFunc", reinterpret_cast<GLES2FunctionPointer>(glStencilFunc), }, @@ -1944,6 +1989,10 @@ reinterpret_cast<GLES2FunctionPointer>(glUniform4uiv), }, { + "glUniformBlockBinding", + reinterpret_cast<GLES2FunctionPointer>(glUniformBlockBinding), + }, + { "glUniformMatrix2fv", reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix2fv), }, @@ -2192,6 +2241,10 @@ reinterpret_cast<GLES2FunctionPointer>(glGetProgramInfoCHROMIUM), }, { + "glGetUniformBlocksCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformBlocksCHROMIUM), + }, + { "glCreateStreamTextureCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glCreateStreamTextureCHROMIUM), },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 2ac4d69..074502c 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -702,6 +702,30 @@ } } +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetActiveUniformBlockiv* c = + GetCmdSpace<gles2::cmds::GetActiveUniformBlockiv>(); + if (c) { + c->Init(program, index, pname, params_shm_id, params_shm_offset); + } +} + +void GetActiveUniformBlockName(GLuint program, + GLuint index, + uint32_t name_bucket_id, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::GetActiveUniformBlockName* c = + GetCmdSpace<gles2::cmds::GetActiveUniformBlockName>(); + if (c) { + c->Init(program, index, name_bucket_id, result_shm_id, result_shm_offset); + } +} + void GetAttachedShaders(GLuint program, uint32_t result_shm_id, uint32_t result_shm_offset, @@ -921,6 +945,17 @@ } } +void GetUniformBlockIndex(GLuint program, + uint32_t name_bucket_id, + uint32_t index_shm_id, + uint32_t index_shm_offset) { + gles2::cmds::GetUniformBlockIndex* c = + GetCmdSpace<gles2::cmds::GetUniformBlockIndex>(); + if (c) { + c->Init(program, name_bucket_id, index_shm_id, index_shm_offset); + } +} + void GetUniformfv(GLuint program, GLint location, uint32_t params_shm_id, @@ -1637,6 +1672,14 @@ } } +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) { + gles2::cmds::UniformBlockBinding* c = + GetCmdSpace<gles2::cmds::UniformBlockBinding>(); + if (c) { + c->Init(program, index, binding); + } +} + void UniformMatrix2fvImmediate(GLint location, GLsizei count, const GLfloat* value) { @@ -2145,6 +2188,14 @@ } } +void GetUniformBlocksCHROMIUM(GLuint program, uint32_t bucket_id) { + gles2::cmds::GetUniformBlocksCHROMIUM* c = + GetCmdSpace<gles2::cmds::GetUniformBlocksCHROMIUM>(); + if (c) { + c->Init(program, bucket_id); + } +} + void GetTranslatedShaderSourceANGLE(GLuint shader, uint32_t bucket_id) { gles2::cmds::GetTranslatedShaderSourceANGLE* c = GetCmdSpace<gles2::cmds::GetTranslatedShaderSourceANGLE>();
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 7ef5444..86b50720 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -702,6 +702,15 @@ return true; } return false; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + *params = capabilities_.max_uniform_buffer_bindings; + return true; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + *params = capabilities_.max_transform_feedback_separate_attribs; + return true; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + *params = capabilities_.uniform_buffer_offset_alignment; + return true; default: return false; } @@ -834,6 +843,13 @@ // TODO(piman): Add the FreeEverything() logic here. } +void GLES2Implementation::OrderingBarrierCHROMIUM() { + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOrderingBarrierCHROMIUM"); + // Flush command buffer at the GPU channel level. May be implemented as + // Flush(). + helper_->CommandBufferHelper::OrderingBarrier(); +} + void GLES2Implementation::Finish() { GPU_CLIENT_SINGLE_THREAD_CHECK(); FinishHelper(); @@ -1091,6 +1107,35 @@ return loc; } +GLuint GLES2Implementation::GetUniformBlockIndexHelper( + GLuint program, const char* name) { + typedef cmds::GetUniformBlockIndex::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_INVALID_INDEX; + } + *result = GL_INVALID_INDEX; + SetBucketAsCString(kResultBucketId, name); + helper_->GetUniformBlockIndex( + program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + helper_->SetBucketSize(kResultBucketId, 0); + return *result; +} + +GLuint GLES2Implementation::GetUniformBlockIndex( + GLuint program, const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformBlockIndex(" + << program << ", " << name << ")"); + TRACE_EVENT0("gpu", "GLES2::GetUniformBlockIndex"); + GLuint index = share_group_->program_info_manager()->GetUniformBlockIndex( + this, program, name); + GPU_CLIENT_LOG("returned " << index); + CheckGLError(); + return index; +} + void GLES2Implementation::LinkProgram(GLuint program) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLinkProgram(" << program << ")"); @@ -2272,6 +2317,115 @@ CheckGLError(); } +bool GLES2Implementation::GetActiveUniformBlockNameHelper( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name) { + DCHECK_LE(0, bufsize); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + typedef cmds::GetActiveUniformBlockName::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + // Set as failed so if the command fails we'll recover. + *result = 0; + helper_->GetActiveUniformBlockName(program, index, kResultBucketId, + GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (*result) { + if (bufsize == 0) { + if (length) { + *length = 0; + } + } else if (length || name) { + std::vector<int8> str; + GetBucketContents(kResultBucketId, &str); + DCHECK(str.size() > 0); + GLsizei max_size = + std::min(bufsize, static_cast<GLsizei>(str.size())) - 1; + if (length) { + *length = max_size; + } + if (name) { + memcpy(name, &str[0], max_size); + name[max_size] = '\0'; + } + } + } + return *result != 0; +} + +void GLES2Implementation::GetActiveUniformBlockName( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockName(" + << program << ", " << index << ", " << bufsize << ", " + << static_cast<const void*>(length) << ", " + << static_cast<const void*>(name) << ")"); + if (bufsize < 0) { + SetGLError(GL_INVALID_VALUE, "glGetActiveUniformBlockName", "bufsize < 0"); + return; + } + TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockName"); + bool success = + share_group_->program_info_manager()->GetActiveUniformBlockName( + this, program, index, bufsize, length, name); + if (success) { + if (name) { + GPU_CLIENT_LOG(" name: " << name); + } + } + CheckGLError(); +} + +bool GLES2Implementation::GetActiveUniformBlockivHelper( + GLuint program, GLuint index, GLenum pname, GLint* params) { + typedef cmds::GetActiveUniformBlockiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + result->SetNumResults(0); + helper_->GetActiveUniformBlockiv( + program, index, pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (result->GetNumResults() > 0) { + if (params) { + result->CopyResult(params); + } + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + return true; + } + return false; +} + +void GLES2Implementation::GetActiveUniformBlockiv( + GLuint program, GLuint index, GLenum pname, GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockiv(" + << program << ", " << index << ", " + << GLES2Util::GetStringProgramParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockiv"); + bool success = + share_group_->program_info_manager()->GetActiveUniformBlockiv( + this, program, index, pname, params); + if (success) { + if (params) { + // TODO(zmo): For GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, there will + // be more than one value returned in params. + GPU_CLIENT_LOG(" params: " << params[0]); + } + } + CheckGLError(); +} + void GLES2Implementation::GetAttachedShaders( GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -2638,6 +2792,10 @@ // the old model but possibly not true in the new model if another context has // deleted the resource. +// NOTE #2: There is a bug in some BindXXXHelpers, that IDs might be marked as +// used even when Bind has failed. However, the bug is minor compared to the +// overhead & duplicated checking in client side. + void GLES2Implementation::BindBufferHelper( GLenum target, GLuint buffer_id) { // TODO(gman): See note #1 above. @@ -2662,8 +2820,7 @@ changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. + // TODO(gman): See note #2 above. if (changed) { GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( this, target, buffer_id, &GLES2Implementation::BindBufferStub); @@ -2679,8 +2836,7 @@ void GLES2Implementation::BindBufferBaseHelper( GLenum target, GLuint index, GLuint buffer_id) { // TODO(zmo): See note #1 above. - // TODO(zmo): There's a bug here. If the target or index is invalid the ID - // will not be used even though it's marked it as used here. + // TODO(zmo): See note #2 above. GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( this, target, index, buffer_id, &GLES2Implementation::BindBufferBaseStub); } @@ -2696,8 +2852,7 @@ GLenum target, GLuint index, GLuint buffer_id, GLintptr offset, GLsizeiptr size) { // TODO(zmo): See note #1 above. - // TODO(zmo): There's a bug here. If an arguments is invalid the ID will not - // be used even though it's marked it as used here. + // TODO(zmo): See note #2 above. GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( this, target, index, buffer_id, offset, size, &GLES2Implementation::BindBufferRangeStub); @@ -2777,8 +2932,7 @@ changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. + // TODO(zmo): See note #2 above. if (changed) { GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind( this, target, renderbuffer, @@ -2827,8 +2981,7 @@ changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used. even though it's marked it as used here. + // TODO(gman): See note #2 above. if (changed) { GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind( this, target, texture, &GLES2Implementation::BindTextureStub); @@ -2847,7 +3000,6 @@ } void GLES2Implementation::BindVertexArrayOESHelper(GLuint array) { - // TODO(gman): See note #1 above. bool changed = false; if (vertex_array_object_manager_->BindVertexArray(array, &changed)) { if (changed) { @@ -2878,8 +3030,7 @@ changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. + // TODO(gman): See note #2 above. if (changed) { GetIdHandler(id_namespaces::kValuebuffers)->MarkAsUsedForBind( this, target, valuebuffer, @@ -3509,6 +3660,47 @@ memcpy(info, &result[0], result.size()); } +void GLES2Implementation::GetUniformBlocksCHROMIUMHelper( + GLuint program, std::vector<int8>* result) { + DCHECK(result); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + helper_->GetUniformBlocksCHROMIUM(program, kResultBucketId); + GetBucketContents(kResultBucketId, result); +} + +void GLES2Implementation::GetUniformBlocksCHROMIUM( + GLuint program, GLsizei bufsize, GLsizei* size, void* info) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + if (bufsize < 0) { + SetGLError( + GL_INVALID_VALUE, "glUniformBlocksCHROMIUM", "bufsize less than 0."); + return; + } + if (size == NULL) { + SetGLError(GL_INVALID_VALUE, "glUniformBlocksCHROMIUM", "size is null."); + return; + } + // Make sure they've set size to 0 else the value will be undefined on + // lost context. + DCHECK_EQ(0, *size); + std::vector<int8> result; + GetUniformBlocksCHROMIUMHelper(program, &result); + if (result.empty()) { + return; + } + *size = result.size(); + if (!info) { + return; + } + if (static_cast<size_t>(bufsize) < result.size()) { + SetGLError(GL_INVALID_OPERATION, + "glUniformBlocksCHROMIUM", "bufsize is too small for result."); + return; + } + memcpy(info, &result[0], result.size()); +} + GLuint GLES2Implementation::CreateStreamTextureCHROMIUM(GLuint texture) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] CreateStreamTextureCHROMIUM(" @@ -4382,6 +4574,94 @@ return false; } +bool GLES2Implementation::PackStringsToBucket(GLsizei count, + const char* const* str, + const GLint* length, + const char* func_name) { + DCHECK_LE(0, count); + // Compute the total size. + base::CheckedNumeric<size_t> total_size = count; + total_size += 1; + total_size *= sizeof(GLint); + if (!total_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + size_t header_size = total_size.ValueOrDefault(0); + std::vector<GLint> header(count + 1); + header[0] = static_cast<GLint>(count); + for (GLsizei ii = 0; ii < count; ++ii) { + GLint len = 0; + if (str[ii]) { + len = (length && length[ii] >= 0) + ? length[ii] + : base::checked_cast<GLint>(strlen(str[ii])); + } + total_size += len; + total_size += 1; // NULL at the end of each char array. + if (!total_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + header[ii + 1] = len; + } + // Pack data into a bucket on the service. + helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); + size_t offset = 0; + for (GLsizei ii = 0; ii <= count; ++ii) { + const char* src = + (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : str[ii - 1]; + base::CheckedNumeric<size_t> checked_size = + (ii == 0) ? header_size : static_cast<size_t>(header[ii]); + if (ii > 0) { + checked_size += 1; // NULL in the end. + } + if (!checked_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + size_t size = checked_size.ValueOrDefault(0); + while (size) { + ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); + if (!buffer.valid() || buffer.size() == 0) { + SetGLError(GL_OUT_OF_MEMORY, func_name, "too large"); + return false; + } + size_t copy_size = buffer.size(); + if (ii > 0 && buffer.size() == size) + --copy_size; + if (copy_size) + memcpy(buffer.address(), src, copy_size); + if (copy_size < buffer.size()) { + // Append NULL in the end. + DCHECK(copy_size + 1 == buffer.size()); + char* str = reinterpret_cast<char*>(buffer.address()); + str[copy_size] = 0; + } + helper_->SetBucketData(kResultBucketId, offset, buffer.size(), + buffer.shm_id(), buffer.offset()); + offset += buffer.size(); + src += buffer.size(); + size -= buffer.size(); + } + } + DCHECK_EQ(total_size.ValueOrDefault(0), offset); + return true; +} + +void GLES2Implementation::UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformBlockBinding(" << program + << ", " << index << ", " << binding << ")"); + share_group_->program_info_manager()->UniformBlockBinding( + this, program, index, binding); + helper_->UniformBlockBinding(program, index, binding); + CheckGLError(); +} + + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator.
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 470200e8..dbc0671a 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -220,6 +220,14 @@ bool GetActiveUniformHelper( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); + void GetUniformBlocksCHROMIUMHelper( + GLuint program, std::vector<int8>* result); + GLuint GetUniformBlockIndexHelper(GLuint program, const char* name); + bool GetActiveUniformBlockNameHelper( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name); + bool GetActiveUniformBlockivHelper( + GLuint program, GLuint index, GLenum pname, GLint* params); void FreeUnusedSharedMemory(); void FreeEverything(); @@ -619,6 +627,13 @@ GLuint buffer_id, const char* function_name, GLuint offset, GLsizei size); + // Pack 2D arrays of char into a bucket. + // Helper function for ShaderSource(), TransformFeedbackVaryings(), etc. + bool PackStringsToBucket(GLsizei count, + const char* const* str, + const GLint* length, + const char* func_name); + const std::string& GetLogPrefix() const; #if defined(GL_CLIENT_FAIL_GL_ERRORS)
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 3a6e5f36..44f763e 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -255,6 +255,17 @@ GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; + +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; + void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -327,6 +338,8 @@ void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; + void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; @@ -431,6 +444,8 @@ void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; + void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, @@ -570,6 +585,8 @@ void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; + void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -779,6 +796,11 @@ GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; + GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index d84c1233..625c747 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -1747,73 +1747,10 @@ SetGLError(GL_INVALID_VALUE, "glShaderSource", "count < 0"); return; } - // Compute the total size. - base::CheckedNumeric<size_t> total_size = count; - total_size += 1; - total_size *= sizeof(GLint); - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow"); + + if (!PackStringsToBucket(count, str, length, "glShaderSource")) { return; } - size_t header_size = total_size.ValueOrDefault(0); - std::vector<GLint> header(count + 1); - header[0] = static_cast<GLint>(count); - for (GLsizei ii = 0; ii < count; ++ii) { - GLint len = 0; - if (str[ii]) { - len = (length && length[ii] >= 0) - ? length[ii] - : base::checked_cast<GLint>(strlen(str[ii])); - } - total_size += len; - total_size += 1; // NULL at the end of each char array. - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow"); - return; - } - header[ii + 1] = len; - } - // Pack data into a bucket on the service. - helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); - size_t offset = 0; - for (GLsizei ii = 0; ii <= count; ++ii) { - const char* src = - (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : str[ii - 1]; - base::CheckedNumeric<size_t> checked_size = - (ii == 0) ? header_size : static_cast<size_t>(header[ii]); - if (ii > 0) { - checked_size += 1; // NULL in the end. - } - if (!checked_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow"); - return; - } - size_t size = checked_size.ValueOrDefault(0); - while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid() || buffer.size() == 0) { - SetGLError(GL_OUT_OF_MEMORY, "glShaderSource", "too large"); - return; - } - size_t copy_size = buffer.size(); - if (ii > 0 && buffer.size() == size) - --copy_size; - if (copy_size) - memcpy(buffer.address(), src, copy_size); - if (copy_size < buffer.size()) { - // Append NULL in the end. - DCHECK(copy_size + 1 == buffer.size()); - char* str = reinterpret_cast<char*>(buffer.address()); - str[copy_size] = 0; - } - helper_->SetBucketData(kResultBucketId, offset, buffer.size(), - buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - src += buffer.size(); - size -= buffer.size(); - } - } - DCHECK_EQ(total_size.ValueOrDefault(0), offset); helper_->ShaderSourceBucket(shader, kResultBucketId); helper_->SetBucketSize(kResultBucketId, 0); CheckGLError(); @@ -1990,72 +1927,11 @@ SetGLError(GL_INVALID_VALUE, "glTransformFeedbackVaryings", "count < 0"); return; } - // Compute the total size. - base::CheckedNumeric<size_t> total_size = count; - total_size += 1; - total_size *= sizeof(GLint); - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glTransformFeedbackVaryings", "overflow"); + + if (!PackStringsToBucket(count, varyings, NULL, + "glTransformFeedbackVaryings")) { return; } - size_t header_size = total_size.ValueOrDefault(0); - std::vector<GLint> header(count + 1); - header[0] = static_cast<GLint>(count); - for (GLsizei ii = 0; ii < count; ++ii) { - GLint len = 0; - if (varyings[ii]) { - len = static_cast<GLint>(strlen(varyings[ii])); - } - total_size += len; - total_size += 1; // NULL at the end of each char array. - if (!total_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glTransformFeedbackVaryings", "overflow"); - return; - } - header[ii + 1] = len; - } - // Pack data into a bucket on the service. - helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); - size_t offset = 0; - for (GLsizei ii = 0; ii <= count; ++ii) { - const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0]) - : varyings[ii - 1]; - base::CheckedNumeric<size_t> checked_size = - (ii == 0) ? header_size : static_cast<size_t>(header[ii]); - if (ii > 0) { - checked_size += 1; // NULL in the end. - } - if (!checked_size.IsValid()) { - SetGLError(GL_INVALID_VALUE, "glTransformFeedbackVaryings", "overflow"); - return; - } - size_t size = checked_size.ValueOrDefault(0); - while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid() || buffer.size() == 0) { - SetGLError(GL_OUT_OF_MEMORY, "glTransformFeedbackVaryings", - "too large"); - return; - } - size_t copy_size = buffer.size(); - if (ii > 0 && buffer.size() == size) - --copy_size; - if (copy_size) - memcpy(buffer.address(), src, copy_size); - if (copy_size < buffer.size()) { - // Append NULL in the end. - DCHECK(copy_size + 1 == buffer.size()); - char* str = reinterpret_cast<char*>(buffer.address()); - str[copy_size] = 0; - } - helper_->SetBucketData(kResultBucketId, offset, buffer.size(), - buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - src += buffer.size(); - size -= buffer.size(); - } - } - DCHECK_EQ(total_size.ValueOrDefault(0), offset); helper_->TransformFeedbackVaryingsBucket(program, kResultBucketId, buffermode); helper_->SetBucketSize(kResultBucketId, 0);
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index c88ba642..52a2cef 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -378,6 +378,8 @@ static const GLint kMaxVertexUniformVectors = 128; static const GLint kNumCompressedTextureFormats = 0; static const GLint kNumShaderBinaryFormats = 0; + static const GLuint kMaxTransformFeedbackSeparateAttribs = 4; + static const GLuint kMaxUniformBufferBindings = 36; static const GLuint kStartId = 1024; static const GLuint kBuffersStartId = GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts; @@ -439,6 +441,9 @@ capabilities.num_compressed_texture_formats = kNumCompressedTextureFormats; capabilities.num_shader_binary_formats = kNumShaderBinaryFormats; + capabilities.max_transform_feedback_separate_attribs = + kMaxTransformFeedbackSeparateAttribs; + capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings; capabilities.bind_generates_resource_chromium = bind_generates_resource_service ? 1 : 0; EXPECT_CALL(*gpu_control_, GetCapabilities()) @@ -2019,6 +2024,108 @@ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); } +TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const GLuint kProgramId = 123; + const char kBad = 0x12; + GLsizei size = 0; + const Str7 kString = {"foobar"}; + char buf[20]; + + ExpectedMemoryInfo mem1 = + GetExpectedMemory(MaxTransferBufferSize()); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); + ExpectedMemoryInfo result2 = + GetExpectedResultMemory(sizeof(cmds::GetError::Result)); + + memset(buf, kBad, sizeof(buf)); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), + SetMemory(mem1.ptr, kString))) + .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) + .RetiresOnSaturation(); + + struct Cmds { + cmd::SetBucketSize set_bucket_size1; + cmds::GetUniformBlocksCHROMIUM get_uniform_blocks; + cmd::GetBucketStart get_bucket_start; + cmd::SetToken set_token1; + cmd::SetBucketSize set_bucket_size2; + }; + Cmds expected; + expected.set_bucket_size1.Init(kBucketId, 0); + expected.get_uniform_blocks.Init(kProgramId, kBucketId); + expected.get_bucket_start.Init( + kBucketId, result1.id, result1.offset, + MaxTransferBufferSize(), mem1.id, mem1.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_size2.Init(kBucketId, 0); + gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); + EXPECT_EQ(sizeof(kString), static_cast<size_t>(size)); + EXPECT_STREQ(kString.str, buf); + EXPECT_EQ(buf[sizeof(kString)], kBad); +} + +TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const GLuint kProgramId = 123; + GLsizei size = 0; + const Str7 kString = {"foobar"}; + char buf[20]; + + ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); + ExpectedMemoryInfo result2 = + GetExpectedResultMemory(sizeof(cmds::GetError::Result)); + ExpectedMemoryInfo result3 = + GetExpectedResultMemory(sizeof(cmds::GetError::Result)); + ExpectedMemoryInfo result4 = + GetExpectedResultMemory(sizeof(cmds::GetError::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), + SetMemory(mem1.ptr, kString))) + .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) + .RetiresOnSaturation(); + + // try bufsize not big enough. + struct Cmds { + cmd::SetBucketSize set_bucket_size1; + cmds::GetUniformBlocksCHROMIUM get_uniform_blocks; + cmd::GetBucketStart get_bucket_start; + cmd::SetToken set_token1; + cmd::SetBucketSize set_bucket_size2; + }; + Cmds expected; + expected.set_bucket_size1.Init(kBucketId, 0); + expected.get_uniform_blocks.Init(kProgramId, kBucketId); + expected.get_bucket_start.Init( + kBucketId, result1.id, result1.offset, + MaxTransferBufferSize(), mem1.id, mem1.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_size2.Init(kBucketId, 0); + gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError()); + ClearCommands(); + + // try bad bufsize + gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); + ClearCommands(); + // try no size ptr. + gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); +} + // Test that things are cached TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) { struct PNameValue {
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 743458b..f4e5658d 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -55,9 +55,9 @@ cmds::BindBufferRange cmd; }; Cmds expected; - expected.cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 5); + expected.cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 4); - gl_->BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 5); + gl_->BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 4); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -751,6 +751,8 @@ } // TODO(zmo): Implement unit test for GetActiveAttrib // TODO(zmo): Implement unit test for GetActiveUniform +// TODO(zmo): Implement unit test for GetActiveUniformBlockiv +// TODO(zmo): Implement unit test for GetActiveUniformBlockName // TODO(zmo): Implement unit test for GetAttachedShaders // TODO(zmo): Implement unit test for GetAttribLocation @@ -983,6 +985,7 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_EQ(static_cast<Result::Type>(1), result); } +// TODO(zmo): Implement unit test for GetUniformBlockIndex // TODO(zmo): Implement unit test for GetUniformfv // TODO(zmo): Implement unit test for GetUniformiv // TODO(zmo): Implement unit test for GetUniformLocation @@ -2030,6 +2033,17 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, UniformBlockBinding) { + struct Cmds { + cmds::UniformBlockBinding cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3); + + gl_->UniformBlockBinding(1, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, UniformMatrix2fv) { GLfloat data[2][4] = {{0}}; struct Cmds {
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index c3a2c3e..1a03ada 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -186,6 +186,15 @@ GLint* size, GLenum* type, char* name) = 0; +virtual void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) = 0; +virtual void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) = 0; virtual void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -240,6 +249,7 @@ GLenum pname, GLfloat* params) = 0; virtual void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) = 0; +virtual GLuint GetUniformBlockIndex(GLuint program, const char* name) = 0; virtual void GetUniformfv(GLuint program, GLint location, GLfloat* params) = 0; virtual void GetUniformiv(GLuint program, GLint location, GLint* params) = 0; virtual GLint GetUniformLocation(GLuint program, const char* name) = 0; @@ -309,6 +319,7 @@ const GLint* length) = 0; virtual void ShallowFinishCHROMIUM() = 0; virtual void ShallowFlushCHROMIUM() = 0; +virtual void OrderingBarrierCHROMIUM() = 0; virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) = 0; virtual void StencilFuncSeparate(GLenum face, GLenum func, @@ -410,6 +421,9 @@ GLuint z, GLuint w) = 0; virtual void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) = 0; +virtual void UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) = 0; virtual void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -564,6 +578,10 @@ GLsizei bufsize, GLsizei* size, void* info) = 0; +virtual void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) = 0; virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) = 0; virtual GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 34a0c426..96bda87 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -185,6 +185,15 @@ GLint* size, GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -235,6 +244,7 @@ const GLubyte* GetString(GLenum name) override; void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override; void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; GLint GetUniformLocation(GLuint program, const char* name) override; @@ -304,6 +314,7 @@ const GLint* length) override; void ShallowFinishCHROMIUM() override; void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, GLenum func, @@ -403,6 +414,7 @@ GLuint z, GLuint w) override; void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -551,6 +563,10 @@ GLsizei bufsize, GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index cf121fc..859bd86 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -286,6 +286,17 @@ GLenum* /* type */, char* /* name */) { } +void GLES2InterfaceStub::GetActiveUniformBlockiv(GLuint /* program */, + GLuint /* index */, + GLenum /* pname */, + GLint* /* params */) { +} +void GLES2InterfaceStub::GetActiveUniformBlockName(GLuint /* program */, + GLuint /* index */, + GLsizei /* bufsize */, + GLsizei* /* length */, + char* /* name */) { +} void GLES2InterfaceStub::GetAttachedShaders(GLuint /* program */, GLsizei /* maxcount */, GLsizei* /* count */, @@ -376,6 +387,10 @@ GLenum /* pname */, GLint* /* params */) { } +GLuint GLES2InterfaceStub::GetUniformBlockIndex(GLuint /* program */, + const char* /* name */) { + return 0; +} void GLES2InterfaceStub::GetUniformfv(GLuint /* program */, GLint /* location */, GLfloat* /* params */) { @@ -516,6 +531,8 @@ } void GLES2InterfaceStub::ShallowFlushCHROMIUM() { } +void GLES2InterfaceStub::OrderingBarrierCHROMIUM() { +} void GLES2InterfaceStub::StencilFunc(GLenum /* func */, GLint /* ref */, GLuint /* mask */) { @@ -710,6 +727,10 @@ GLsizei /* count */, const GLuint* /* v */) { } +void GLES2InterfaceStub::UniformBlockBinding(GLuint /* program */, + GLuint /* index */, + GLuint /* binding */) { +} void GLES2InterfaceStub::UniformMatrix2fv(GLint /* location */, GLsizei /* count */, GLboolean /* transpose */, @@ -961,6 +982,11 @@ GLsizei* /* size */, void* /* info */) { } +void GLES2InterfaceStub::GetUniformBlocksCHROMIUM(GLuint /* program */, + GLsizei /* bufsize */, + GLsizei* /* size */, + void* /* info */) { +} GLuint GLES2InterfaceStub::CreateStreamTextureCHROMIUM(GLuint /* texture */) { return 0; }
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index db9b375..61ec8a3 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -185,6 +185,15 @@ GLint* size, GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -235,6 +244,7 @@ const GLubyte* GetString(GLenum name) override; void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override; void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; GLint GetUniformLocation(GLuint program, const char* name) override; @@ -304,6 +314,7 @@ const GLint* length) override; void ShallowFinishCHROMIUM() override; void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, GLenum func, @@ -403,6 +414,7 @@ GLuint z, GLuint w) override; void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -551,6 +563,10 @@ GLsizei bufsize, GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 33bc3ae..7190d502 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -500,6 +500,23 @@ gl_->GetActiveUniform(program, index, bufsize, length, size, type, name); } +void GLES2TraceImplementation::GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetActiveUniformBlockiv"); + gl_->GetActiveUniformBlockiv(program, index, pname, params); +} + +void GLES2TraceImplementation::GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetActiveUniformBlockName"); + gl_->GetActiveUniformBlockName(program, index, bufsize, length, name); +} + void GLES2TraceImplementation::GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -653,6 +670,12 @@ gl_->GetTexParameteriv(target, pname, params); } +GLuint GLES2TraceImplementation::GetUniformBlockIndex(GLuint program, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformBlockIndex"); + return gl_->GetUniformBlockIndex(program, name); +} + void GLES2TraceImplementation::GetUniformfv(GLuint program, GLint location, GLfloat* params) { @@ -899,6 +922,11 @@ gl_->ShallowFlushCHROMIUM(); } +void GLES2TraceImplementation::OrderingBarrierCHROMIUM() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::OrderingBarrierCHROMIUM"); + gl_->OrderingBarrierCHROMIUM(); +} + void GLES2TraceImplementation::StencilFunc(GLenum func, GLint ref, GLuint mask) { @@ -1210,6 +1238,13 @@ gl_->Uniform4uiv(location, count, v); } +void GLES2TraceImplementation::UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformBlockBinding"); + gl_->UniformBlockBinding(program, index, binding); +} + void GLES2TraceImplementation::UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -1647,6 +1682,14 @@ gl_->GetProgramInfoCHROMIUM(program, bufsize, size, info); } +void GLES2TraceImplementation::GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformBlocksCHROMIUM"); + gl_->GetUniformBlocksCHROMIUM(program, bufsize, size, info); +} + GLuint GLES2TraceImplementation::CreateStreamTextureCHROMIUM(GLuint texture) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateStreamTextureCHROMIUM");
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc index 205d1b9..d1c6f9e 100644 --- a/gpu/command_buffer/client/program_info_manager.cc +++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -4,8 +4,6 @@ #include "gpu/command_buffer/client/program_info_manager.h" -#include "base/numerics/safe_math.h" - namespace { template<typename T> static T LocalGetAs( @@ -181,6 +179,13 @@ return GL_INVALID_INDEX; } +void ProgramInfoManager::Program::UniformBlockBinding( + GLuint index , GLuint binding) { + if (index < uniform_blocks_.size()) { + uniform_blocks_[index].binding = binding; + } +} + void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { if (cached_es2_) { return; @@ -249,6 +254,8 @@ uniform_blocks_.clear(); active_uniform_block_max_name_length_ = 0; + // |result| comes from GPU process. We consider it trusted data. Therefore, + // no need to check for overflows as the GPU side did the checks already. uint32_t header_size = sizeof(UniformBlocksHeader); DCHECK_GE(result.size(), header_size); const UniformBlocksHeader* header = LocalGetAs<const UniformBlocksHeader*>( @@ -536,32 +543,43 @@ return info->GetUniformBlockIndex(name); } } - return false; - // TODO(zmo): return gl->GetUniformBlockIndexHelper(program, name); + return gl->GetUniformBlockIndexHelper(program, name); } bool ProgramInfoManager::GetActiveUniformBlockName( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei buf_size, GLsizei* length, char* name) { + DCHECK_LE(0, buf_size); + if (!name) { + buf_size = 0; + } { base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); if (info) { const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); - if (uniform_block && buf_size >= 1) { - GLsizei written_size = std::min( - buf_size, static_cast<GLsizei>(uniform_block->name.size()) + 1); - if (length) { - *length = written_size - 1; + if (uniform_block) { + if (buf_size == 0) { + if (length) { + *length = 0; + } + } else if (length || name) { + GLsizei max_size = std::min( + buf_size - 1, static_cast<GLsizei>(uniform_block->name.size())); + if (length) { + *length = max_size; + } + if (name) { + memcpy(name, uniform_block->name.data(), max_size); + name[max_size] = '\0'; + } } - memcpy(name, uniform_block->name.c_str(), written_size); return true; } } } - return false; - // TODO(zmo): return gl->GetActiveUniformBlockNameHelper( - // program, index, buf_size, length, name); + return gl->GetActiveUniformBlockNameHelper( + program, index, buf_size, length, name); } bool ProgramInfoManager::GetActiveUniformBlockiv( @@ -624,9 +642,21 @@ } } } - return false; - // TODO(zmo): return gl->GetActiveUniformBlockivHelper( - // program, index, pname, params); + return gl->GetActiveUniformBlockivHelper(program, index, pname, params); +} + +void ProgramInfoManager::UniformBlockBinding( + GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding) { + GLuint max_bindings = + static_cast<GLuint>(gl->capabilities().max_uniform_buffer_bindings); + if (binding < max_bindings) { + base::AutoLock auto_lock(lock_); + // If UniformBlock info haven't been cached yet, skip updating the binding. + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + info->UniformBlockBinding(index, binding); + } + } } } // namespace gles2
diff --git a/gpu/command_buffer/client/program_info_manager.h b/gpu/command_buffer/client/program_info_manager.h index efbff73f..342e9ea 100644 --- a/gpu/command_buffer/client/program_info_manager.h +++ b/gpu/command_buffer/client/program_info_manager.h
@@ -60,6 +60,12 @@ GLES2Implementation* gl, GLuint program, GLuint index, GLenum pname, GLint* params); + // Attempt to update the |index| uniform block binding. + // It's no op if the program does not exist, or the |index| uniform block + // is not in the cache, or binding >= GL_MAX_UNIFORM_BUFFER_BINDINGS. + void UniformBlockBinding( + GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding); + private: friend class ProgramInfoManagerTest; @@ -126,6 +132,8 @@ // Gets the index of a uniform block by name. GLuint GetUniformBlockIndex(const std::string& name) const; const UniformBlock* GetUniformBlock(GLuint index) const; + // Update the binding if the |index| uniform block is in the cache. + void UniformBlockBinding(GLuint index, GLuint binding); // Updates the ES2 only program info after a successful link. void UpdateES2(const std::vector<int8>& result);
diff --git a/gpu/command_buffer/client/program_info_manager_unittest.cc b/gpu/command_buffer/client/program_info_manager_unittest.cc index a2fc722..ce0802d 100644 --- a/gpu/command_buffer/client/program_info_manager_unittest.cc +++ b/gpu/command_buffer/client/program_info_manager_unittest.cc
@@ -12,6 +12,8 @@ static_cast<const uint8*>(start); } +const GLuint kClientProgramId = 321; + } // namespace anonymous namespace gpu { @@ -23,13 +25,9 @@ ~ProgramInfoManagerTest() override {} protected: - void SetUp() override {} + typedef ProgramInfoManager::Program Program; - void TearDown() override {} -}; - -TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { - struct Data { + struct UniformBlocksData { UniformBlocksHeader header; UniformBlockInfo entry[2]; char name0[4]; @@ -37,55 +35,77 @@ char name1[8]; uint32_t indices1[1]; }; - Data data; - // The names needs to be of size 4*k-1 to avoid padding in the struct Data. - // This is a testing only problem. - const char* kName[] = { "cow", "chicken" }; - const uint32_t kIndices0[] = { 1, 2 }; - const uint32_t kIndices1[] = { 3 }; - const uint32_t* kIndices[] = { kIndices0, kIndices1 }; - data.header.num_uniform_blocks = 2; - data.entry[0].binding = 0; - data.entry[0].data_size = 8; - data.entry[0].name_offset = ComputeOffset(&data, data.name0); - data.entry[0].name_length = arraysize(data.name0); - data.entry[0].active_uniforms = arraysize(data.indices0); - data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0); - data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); - data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); - data.entry[1].binding = 1; - data.entry[1].data_size = 4; - data.entry[1].name_offset = ComputeOffset(&data, data.name1); - data.entry[1].name_length = arraysize(data.name1); - data.entry[1].active_uniforms = arraysize(data.indices1); - data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1); - data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); - data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); - memcpy(data.name0, kName[0], arraysize(data.name0)); - data.indices0[0] = kIndices[0][0]; - data.indices0[1] = kIndices[0][1]; - memcpy(data.name1, kName[1], arraysize(data.name1)); - data.indices1[0] = kIndices[1][0]; + void SetUp() override { + program_info_manager_.reset(new ProgramInfoManager); + program_info_manager_->CreateInfo(kClientProgramId); + { + base::AutoLock auto_lock(program_info_manager_->lock_); + program_ = program_info_manager_->GetProgramInfo( + NULL, kClientProgramId, ProgramInfoManager::kNone); + ASSERT_TRUE(program_ != NULL); + } + } + + void TearDown() override {} + + void SetupUniformBlocksData(UniformBlocksData* data) { + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + const uint32_t kIndices0[] = { 1, 2 }; + const uint32_t kIndices1[] = { 3 }; + const uint32_t* kIndices[] = { kIndices0, kIndices1 }; + data->header.num_uniform_blocks = 2; + data->entry[0].binding = 0; + data->entry[0].data_size = 8; + data->entry[0].name_offset = ComputeOffset(data, data->name0); + data->entry[0].name_length = arraysize(data->name0); + data->entry[0].active_uniforms = arraysize(data->indices0); + data->entry[0].active_uniform_offset = ComputeOffset(data, data->indices0); + data->entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); + data->entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); + data->entry[1].binding = 1; + data->entry[1].data_size = 4; + data->entry[1].name_offset = ComputeOffset(data, data->name1); + data->entry[1].name_length = arraysize(data->name1); + data->entry[1].active_uniforms = arraysize(data->indices1); + data->entry[1].active_uniform_offset = ComputeOffset(data, data->indices1); + data->entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); + data->entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); + memcpy(data->name0, kName[0], arraysize(data->name0)); + data->indices0[0] = kIndices[0][0]; + data->indices0[1] = kIndices[0][1]; + memcpy(data->name1, kName[1], arraysize(data->name1)); + data->indices1[0] = kIndices[1][0]; + } + + scoped_ptr<ProgramInfoManager> program_info_manager_; + Program* program_; +}; + +TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + const std::string kName[] = { data.name0, data.name1 }; + const uint32_t* kIndices[] = { data.indices0, data.indices1 }; std::vector<int8> result(sizeof(data)); memcpy(&result[0], &data, sizeof(data)); + EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); + program_->UpdateES3UniformBlocks(result); + EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); - ProgramInfoManager::Program program; - EXPECT_FALSE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); - program.UpdateES3UniformBlocks(result); - EXPECT_TRUE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); GLint uniform_block_count = 0; - EXPECT_TRUE(program.GetProgramiv( + EXPECT_TRUE(program_->GetProgramiv( GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); EXPECT_EQ(data.header.num_uniform_blocks, static_cast<uint32_t>(uniform_block_count)); GLint max_name_length = 0; - EXPECT_TRUE(program.GetProgramiv( + EXPECT_TRUE(program_->GetProgramiv( GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { - EXPECT_EQ(ii, program.GetUniformBlockIndex(kName[ii])); - const ProgramInfoManager::Program::UniformBlock* info = - program.GetUniformBlock(ii); + EXPECT_EQ(ii, program_->GetUniformBlockIndex(kName[ii])); + const Program::UniformBlock* info = program_->GetUniformBlock(ii); EXPECT_TRUE(info != NULL); EXPECT_EQ(data.entry[ii].binding, info->binding); EXPECT_EQ(data.entry[ii].data_size, info->data_size); @@ -102,8 +122,110 @@ EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); } - EXPECT_EQ(GL_INVALID_INDEX, program.GetUniformBlockIndex("BadName")); - EXPECT_EQ(NULL, program.GetUniformBlock(data.header.num_uniform_blocks)); + EXPECT_EQ(GL_INVALID_INDEX, program_->GetUniformBlockIndex("BadName")); + EXPECT_EQ(NULL, program_->GetUniformBlock(data.header.num_uniform_blocks)); +} + +TEST_F(ProgramInfoManagerTest, GetUniformBlockIndexCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + + EXPECT_EQ(0u, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, data.name0)); + EXPECT_EQ(1u, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, data.name1)); + EXPECT_EQ(GL_INVALID_INDEX, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, "BadName")); +} + +TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockNameCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + + GLsizei buf_size = std::max(strlen(data.name0), strlen(data.name1)) + 1; + std::vector<char> buffer(buf_size); + GLsizei length = 0; + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); + EXPECT_EQ(static_cast<GLsizei>(strlen(data.name0)), length); + EXPECT_STREQ(data.name0, &buffer[0]); + + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 1, buf_size, &length, &buffer[0])); + EXPECT_EQ(static_cast<GLsizei>(strlen(data.name1)), length); + EXPECT_STREQ(data.name1, &buffer[0]); + + // Test length == NULL. + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, NULL, &buffer[0])); + EXPECT_STREQ(data.name0, &buffer[0]); + + // Test buffer == NULL. + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, NULL)); + EXPECT_EQ(0, length); + + // Test buf_size smaller than string size. + buf_size = strlen(data.name0); + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); + EXPECT_EQ(buf_size, length + 1); + EXPECT_STREQ(std::string(data.name0).substr(0, length).c_str(), &buffer[0]); +} + +TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockivCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + const char* kName[] = { data.name0, data.name1 }; + const uint32_t* kIndices[] = { data.indices0, data.indices1 }; + + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + ASSERT_GE(2u, data.entry[ii].active_uniforms); + GLint params[2]; + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_BINDING, params)); + EXPECT_EQ(data.entry[ii].binding, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_DATA_SIZE, params)); + EXPECT_EQ(data.entry[ii].data_size, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, params)); + EXPECT_EQ(strlen(kName[ii]) + 1, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, params)); + EXPECT_EQ(data.entry[ii].active_uniforms, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, params)); + for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { + EXPECT_EQ(kIndices[ii][uu], static_cast<uint32_t>(params[uu])); + } + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, params)); + EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, + static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, params)); + EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, + static_cast<uint32_t>(params[0])); + } } } // namespace gles2
diff --git a/gpu/command_buffer/client/query_tracker_unittest.cc b/gpu/command_buffer/client/query_tracker_unittest.cc index 53f5195..f6f48ec 100644 --- a/gpu/command_buffer/client/query_tracker_unittest.cc +++ b/gpu/command_buffer/client/query_tracker_unittest.cc
@@ -161,24 +161,23 @@ EXPECT_EQ(kToken, query->token()); EXPECT_EQ(1, query->submit_count()); - // Check CheckResultsAvailable. - EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); - EXPECT_FALSE(query->NeverUsed()); - EXPECT_TRUE(query->Pending()); - // Flush only once if no more flushes happened between a call to // EndQuery command and CheckResultsAvailable // Advance put_ so flush calls in CheckResultsAvailable go through // and updates flush_generation count helper_->Noop(1); - // Set Query in pending state_ to simulate EndQuery command is called - query->MarkAsPending(kToken); - EXPECT_TRUE(query->Pending()); + // Store FlushGeneration count after EndQuery is called uint32 gen1 = GetFlushGeneration(); + + // Check CheckResultsAvailable. EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); + EXPECT_FALSE(query->NeverUsed()); + EXPECT_TRUE(query->Pending()); + uint32 gen2 = GetFlushGeneration(); EXPECT_NE(gen1, gen2); + // Repeated calls to CheckResultsAvailable should not flush unnecessarily EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); gen1 = GetFlushGeneration();
diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc index 7dac4f5..1a2a4b07 100644 --- a/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc
@@ -82,6 +82,7 @@ .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*command_buffer(), OnFlush()).Times(AtMost(1)); + EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1)); transfer_buffer_.reset(); }
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index dc4ce3a0..2f45372 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -77,6 +77,8 @@ GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizeiNotNegative n, GLuint* ids); GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name); GL_APICALL void GL_APIENTRY glGetActiveUniform (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLidProgram program, GLuint index, GLenumUniformBlockParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* name); GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLidProgram program, GLsizeiNotNegative maxcount, GLsizeiOptional* count, GLuint* shaders); GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetBooleanv (GLenumGLState pname, GLboolean* params); @@ -99,6 +101,7 @@ GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenumStringType name); GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenumGetTexParamTarget target, GLenumTextureParameter pname, GLfloat* params); GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenumGetTexParamTarget target, GLenumTextureParameter pname, GLint* params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetUniformfv (GLidProgram program, GLintUniformLocation location, GLfloat* params); GL_APICALL void GL_APIENTRY glGetUniformiv (GLidProgram program, GLintUniformLocation location, GLint* params); GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLidProgram program, const char* name); @@ -138,6 +141,7 @@ GL_APICALL void GL_APIENTRY glShaderSource (GLidShader shader, GLsizeiNotNegative count, const GLchar* const* str, const GLint* length); GL_APICALL void GL_APIENTRY glShallowFinishCHROMIUM (void); GL_APICALL void GL_APIENTRY glShallowFlushCHROMIUM (void); +GL_APICALL void GL_APIENTRY glOrderingBarrierCHROMIUM (void); GL_APICALL void GL_APIENTRY glStencilFunc (GLenumCmpFunction func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenumFaceType face, GLenumCmpFunction func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); @@ -178,6 +182,7 @@ GL_APICALL void GL_APIENTRY glUniform4iv (GLintUniformLocation location, GLsizeiNotNegative count, const GLint* v); GL_APICALL void GL_APIENTRY glUniform4ui (GLintUniformLocation location, GLuint x, GLuint y, GLuint z, GLuint w); GL_APICALL void GL_APIENTRY glUniform4uiv (GLintUniformLocation location, GLsizeiNotNegative count, const GLuint* v); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLidProgram program, GLuint index, GLuint binding); GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); @@ -242,6 +247,7 @@ GL_APICALL void GL_APIENTRY glRequestExtensionCHROMIUM (const char* extension); GL_APICALL void GL_APIENTRY glRateLimitOffscreenContextCHROMIUM (void); GL_APICALL void GL_APIENTRY glGetProgramInfoCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); +GL_APICALL void GL_APIENTRY glGetUniformBlocksCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); GL_APICALL GLuint GL_APIENTRY glCreateStreamTextureCHROMIUM (GLuint texture); GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM (ClientBuffer buffer, GLsizei width, GLsizei height, GLenum internalformat); GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM (GLuint image_id);
diff --git a/gpu/command_buffer/common/capabilities.cc b/gpu/command_buffer/common/capabilities.cc index ab33aeb7..97c26d8f 100644 --- a/gpu/command_buffer/common/capabilities.cc +++ b/gpu/command_buffer/common/capabilities.cc
@@ -23,6 +23,9 @@ num_compressed_texture_formats(0), num_shader_binary_formats(0), bind_generates_resource_chromium(0), + max_transform_feedback_separate_attribs(0), + max_uniform_buffer_bindings(0), + uniform_buffer_offset_alignment(1), post_sub_buffer(false), egl_image_external(false), texture_format_bgra8888(false),
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h index a465ca23..92c3c19 100644 --- a/gpu/command_buffer/common/capabilities.h +++ b/gpu/command_buffer/common/capabilities.h
@@ -75,6 +75,9 @@ int num_compressed_texture_formats; int num_shader_binary_formats; int bind_generates_resource_chromium; + int max_transform_feedback_separate_attribs; + int max_uniform_buffer_bindings; + int uniform_buffer_offset_alignment; bool post_sub_buffer; bool egl_image_external;
diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h index d846ec11..b69936320 100644 --- a/gpu/command_buffer/common/command_buffer.h +++ b/gpu/command_buffer/common/command_buffer.h
@@ -90,6 +90,11 @@ // subsequent Flushes on the same GpuChannel. virtual void Flush(int32 put_offset) = 0; + // As Flush, ensures that on the service side, commands up to put_offset + // are processed but before subsequent commands on the same GpuChannel but + // flushing to the service may be deferred. + virtual void OrderingBarrier(int32 put_offset) = 0; + // The writer calls this to wait until the current token is within a // specific range, inclusive. Can return early if an error is generated. virtual void WaitForTokenInRange(int32 start, int32 end) = 0;
diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h index b7366f8..9e1f7131 100644 --- a/gpu/command_buffer/common/command_buffer_mock.h +++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -25,6 +25,7 @@ MOCK_METHOD0(GetLastState, State()); MOCK_METHOD0(GetLastToken, int32()); MOCK_METHOD1(Flush, void(int32 put_offset)); + MOCK_METHOD1(OrderingBarrier, void(int32 put_offset)); MOCK_METHOD2(WaitForTokenInRange, void(int32 start, int32 end)); MOCK_METHOD2(WaitForGetOffsetInRange, void(int32 start, int32 end)); MOCK_METHOD1(SetGetBuffer, void(int32 transfer_buffer_id));
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 47c2b683..09f780d6 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -3374,6 +3374,131 @@ "offset of GetActiveUniform Result type should be " "8"); +struct GetActiveUniformBlockiv { + typedef GetActiveUniformBlockiv ValueType; + static const CommandId kCmdId = kGetActiveUniformBlockiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + program = _program; + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetActiveUniformBlockiv) == 24, + "size of GetActiveUniformBlockiv should be 24"); +static_assert(offsetof(GetActiveUniformBlockiv, header) == 0, + "offset of GetActiveUniformBlockiv header should be 0"); +static_assert(offsetof(GetActiveUniformBlockiv, program) == 4, + "offset of GetActiveUniformBlockiv program should be 4"); +static_assert(offsetof(GetActiveUniformBlockiv, index) == 8, + "offset of GetActiveUniformBlockiv index should be 8"); +static_assert(offsetof(GetActiveUniformBlockiv, pname) == 12, + "offset of GetActiveUniformBlockiv pname should be 12"); +static_assert(offsetof(GetActiveUniformBlockiv, params_shm_id) == 16, + "offset of GetActiveUniformBlockiv params_shm_id should be 16"); +static_assert( + offsetof(GetActiveUniformBlockiv, params_shm_offset) == 20, + "offset of GetActiveUniformBlockiv params_shm_offset should be 20"); + +struct GetActiveUniformBlockName { + typedef GetActiveUniformBlockName ValueType; + static const CommandId kCmdId = kGetActiveUniformBlockName; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef int32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + program = _program; + index = _index; + name_bucket_id = _name_bucket_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _name_bucket_id, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t name_bucket_id; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(GetActiveUniformBlockName) == 24, + "size of GetActiveUniformBlockName should be 24"); +static_assert(offsetof(GetActiveUniformBlockName, header) == 0, + "offset of GetActiveUniformBlockName header should be 0"); +static_assert(offsetof(GetActiveUniformBlockName, program) == 4, + "offset of GetActiveUniformBlockName program should be 4"); +static_assert(offsetof(GetActiveUniformBlockName, index) == 8, + "offset of GetActiveUniformBlockName index should be 8"); +static_assert( + offsetof(GetActiveUniformBlockName, name_bucket_id) == 12, + "offset of GetActiveUniformBlockName name_bucket_id should be 12"); +static_assert(offsetof(GetActiveUniformBlockName, result_shm_id) == 16, + "offset of GetActiveUniformBlockName result_shm_id should be 16"); +static_assert( + offsetof(GetActiveUniformBlockName, result_shm_offset) == 20, + "offset of GetActiveUniformBlockName result_shm_offset should be 20"); + struct GetAttachedShaders { typedef GetAttachedShaders ValueType; static const CommandId kCmdId = kGetAttachedShaders; @@ -4516,6 +4641,61 @@ static_assert(offsetof(GetTexParameteriv, params_shm_offset) == 16, "offset of GetTexParameteriv params_shm_offset should be 16"); +struct GetUniformBlockIndex { + typedef GetUniformBlockIndex ValueType; + static const CommandId kCmdId = kGetUniformBlockIndex; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef GLuint Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + SetHeader(); + program = _program; + name_bucket_id = _name_bucket_id; + index_shm_id = _index_shm_id; + index_shm_offset = _index_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _name_bucket_id, _index_shm_id, _index_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t name_bucket_id; + uint32_t index_shm_id; + uint32_t index_shm_offset; +}; + +static_assert(sizeof(GetUniformBlockIndex) == 20, + "size of GetUniformBlockIndex should be 20"); +static_assert(offsetof(GetUniformBlockIndex, header) == 0, + "offset of GetUniformBlockIndex header should be 0"); +static_assert(offsetof(GetUniformBlockIndex, program) == 4, + "offset of GetUniformBlockIndex program should be 4"); +static_assert(offsetof(GetUniformBlockIndex, name_bucket_id) == 8, + "offset of GetUniformBlockIndex name_bucket_id should be 8"); +static_assert(offsetof(GetUniformBlockIndex, index_shm_id) == 12, + "offset of GetUniformBlockIndex index_shm_id should be 12"); +static_assert(offsetof(GetUniformBlockIndex, index_shm_offset) == 16, + "offset of GetUniformBlockIndex index_shm_offset should be 16"); + struct GetUniformfv { typedef GetUniformfv ValueType; static const CommandId kCmdId = kGetUniformfv; @@ -8205,6 +8385,47 @@ static_assert(offsetof(Uniform4uivImmediate, count) == 8, "offset of Uniform4uivImmediate count should be 8"); +struct UniformBlockBinding { + typedef UniformBlockBinding ValueType; + static const CommandId kCmdId = kUniformBlockBinding; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, GLuint _index, GLuint _binding) { + SetHeader(); + program = _program; + index = _index; + binding = _binding; + } + + void* Set(void* cmd, GLuint _program, GLuint _index, GLuint _binding) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _binding); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t binding; +}; + +static_assert(sizeof(UniformBlockBinding) == 16, + "size of UniformBlockBinding should be 16"); +static_assert(offsetof(UniformBlockBinding, header) == 0, + "offset of UniformBlockBinding header should be 0"); +static_assert(offsetof(UniformBlockBinding, program) == 4, + "offset of UniformBlockBinding program should be 4"); +static_assert(offsetof(UniformBlockBinding, index) == 8, + "offset of UniformBlockBinding index should be 8"); +static_assert(offsetof(UniformBlockBinding, binding) == 12, + "offset of UniformBlockBinding binding should be 12"); + struct UniformMatrix2fvImmediate { typedef UniformMatrix2fvImmediate ValueType; static const CommandId kCmdId = kUniformMatrix2fvImmediate; @@ -10512,6 +10733,45 @@ "offset of GetProgramInfoCHROMIUM Result num_uniforms should be " "8"); +struct GetUniformBlocksCHROMIUM { + typedef GetUniformBlocksCHROMIUM ValueType; + static const CommandId kCmdId = kGetUniformBlocksCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, uint32_t _bucket_id) { + SetHeader(); + program = _program; + bucket_id = _bucket_id; + } + + void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_program, _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t bucket_id; +}; + +static_assert(sizeof(GetUniformBlocksCHROMIUM) == 12, + "size of GetUniformBlocksCHROMIUM should be 12"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, header) == 0, + "offset of GetUniformBlocksCHROMIUM header should be 0"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, program) == 4, + "offset of GetUniformBlocksCHROMIUM program should be 4"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, bucket_id) == 8, + "offset of GetUniformBlocksCHROMIUM bucket_id should be 8"); + struct GetTranslatedShaderSourceANGLE { typedef GetTranslatedShaderSourceANGLE ValueType; static const CommandId kCmdId = kGetTranslatedShaderSourceANGLE;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 804bebc..19163a5 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -1095,6 +1095,42 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetActiveUniformBlockiv) { + cmds::GetActiveUniformBlockiv& cmd = + *GetBufferAs<cmds::GetActiveUniformBlockiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<GLenum>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniformBlockiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLenum>(13), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetActiveUniformBlockName) { + cmds::GetActiveUniformBlockName& cmd = + *GetBufferAs<cmds::GetActiveUniformBlockName>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniformBlockName::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetAttachedShaders) { cmds::GetAttachedShaders& cmd = *GetBufferAs<cmds::GetAttachedShaders>(); void* next_cmd = @@ -1415,6 +1451,21 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetUniformBlockIndex) { + cmds::GetUniformBlockIndex& cmd = *GetBufferAs<cmds::GetUniformBlockIndex>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformBlockIndex::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.index_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.index_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetUniformfv) { cmds::GetUniformfv& cmd = *GetBufferAs<cmds::GetUniformfv>(); void* next_cmd = @@ -2683,6 +2734,19 @@ // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, UniformBlockBinding) { + cmds::UniformBlockBinding& cmd = *GetBufferAs<cmds::UniformBlockBinding>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformBlockBinding::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLuint>(13), cmd.binding); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, UniformMatrix2fvImmediate) { const int kSomeBaseValueToTestWith = 51; static GLfloat data[] = { @@ -3667,6 +3731,19 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetUniformBlocksCHROMIUM) { + cmds::GetUniformBlocksCHROMIUM& cmd = + *GetBufferAs<cmds::GetUniformBlocksCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformBlocksCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetTranslatedShaderSourceANGLE) { cmds::GetTranslatedShaderSourceANGLE& cmd = *GetBufferAs<cmds::GetTranslatedShaderSourceANGLE>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index df996d8..27cd88b5 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -87,195 +87,200 @@ OP(GenTransformFeedbacksImmediate) /* 328 */ \ OP(GetActiveAttrib) /* 329 */ \ OP(GetActiveUniform) /* 330 */ \ - OP(GetAttachedShaders) /* 331 */ \ - OP(GetAttribLocation) /* 332 */ \ - OP(GetBooleanv) /* 333 */ \ - OP(GetBufferParameteriv) /* 334 */ \ - OP(GetError) /* 335 */ \ - OP(GetFloatv) /* 336 */ \ - OP(GetFragDataLocation) /* 337 */ \ - OP(GetFramebufferAttachmentParameteriv) /* 338 */ \ - OP(GetIntegerv) /* 339 */ \ - OP(GetInternalformativ) /* 340 */ \ - OP(GetProgramiv) /* 341 */ \ - OP(GetProgramInfoLog) /* 342 */ \ - OP(GetRenderbufferParameteriv) /* 343 */ \ - OP(GetSamplerParameterfv) /* 344 */ \ - OP(GetSamplerParameteriv) /* 345 */ \ - OP(GetShaderiv) /* 346 */ \ - OP(GetShaderInfoLog) /* 347 */ \ - OP(GetShaderPrecisionFormat) /* 348 */ \ - OP(GetShaderSource) /* 349 */ \ - OP(GetString) /* 350 */ \ - OP(GetTexParameterfv) /* 351 */ \ - OP(GetTexParameteriv) /* 352 */ \ - OP(GetUniformfv) /* 353 */ \ - OP(GetUniformiv) /* 354 */ \ - OP(GetUniformLocation) /* 355 */ \ - OP(GetVertexAttribfv) /* 356 */ \ - OP(GetVertexAttribiv) /* 357 */ \ - OP(GetVertexAttribPointerv) /* 358 */ \ - OP(Hint) /* 359 */ \ - OP(InvalidateFramebufferImmediate) /* 360 */ \ - OP(InvalidateSubFramebufferImmediate) /* 361 */ \ - OP(IsBuffer) /* 362 */ \ - OP(IsEnabled) /* 363 */ \ - OP(IsFramebuffer) /* 364 */ \ - OP(IsProgram) /* 365 */ \ - OP(IsRenderbuffer) /* 366 */ \ - OP(IsSampler) /* 367 */ \ - OP(IsShader) /* 368 */ \ - OP(IsSync) /* 369 */ \ - OP(IsTexture) /* 370 */ \ - OP(IsTransformFeedback) /* 371 */ \ - OP(LineWidth) /* 372 */ \ - OP(LinkProgram) /* 373 */ \ - OP(PauseTransformFeedback) /* 374 */ \ - OP(PixelStorei) /* 375 */ \ - OP(PolygonOffset) /* 376 */ \ - OP(ReadBuffer) /* 377 */ \ - OP(ReadPixels) /* 378 */ \ - OP(ReleaseShaderCompiler) /* 379 */ \ - OP(RenderbufferStorage) /* 380 */ \ - OP(ResumeTransformFeedback) /* 381 */ \ - OP(SampleCoverage) /* 382 */ \ - OP(SamplerParameterf) /* 383 */ \ - OP(SamplerParameterfvImmediate) /* 384 */ \ - OP(SamplerParameteri) /* 385 */ \ - OP(SamplerParameterivImmediate) /* 386 */ \ - OP(Scissor) /* 387 */ \ - OP(ShaderBinary) /* 388 */ \ - OP(ShaderSourceBucket) /* 389 */ \ - OP(StencilFunc) /* 390 */ \ - OP(StencilFuncSeparate) /* 391 */ \ - OP(StencilMask) /* 392 */ \ - OP(StencilMaskSeparate) /* 393 */ \ - OP(StencilOp) /* 394 */ \ - OP(StencilOpSeparate) /* 395 */ \ - OP(TexImage2D) /* 396 */ \ - OP(TexImage3D) /* 397 */ \ - OP(TexParameterf) /* 398 */ \ - OP(TexParameterfvImmediate) /* 399 */ \ - OP(TexParameteri) /* 400 */ \ - OP(TexParameterivImmediate) /* 401 */ \ - OP(TexStorage3D) /* 402 */ \ - OP(TexSubImage2D) /* 403 */ \ - OP(TexSubImage3D) /* 404 */ \ - OP(TransformFeedbackVaryingsBucket) /* 405 */ \ - OP(Uniform1f) /* 406 */ \ - OP(Uniform1fvImmediate) /* 407 */ \ - OP(Uniform1i) /* 408 */ \ - OP(Uniform1ivImmediate) /* 409 */ \ - OP(Uniform1ui) /* 410 */ \ - OP(Uniform1uivImmediate) /* 411 */ \ - OP(Uniform2f) /* 412 */ \ - OP(Uniform2fvImmediate) /* 413 */ \ - OP(Uniform2i) /* 414 */ \ - OP(Uniform2ivImmediate) /* 415 */ \ - OP(Uniform2ui) /* 416 */ \ - OP(Uniform2uivImmediate) /* 417 */ \ - OP(Uniform3f) /* 418 */ \ - OP(Uniform3fvImmediate) /* 419 */ \ - OP(Uniform3i) /* 420 */ \ - OP(Uniform3ivImmediate) /* 421 */ \ - OP(Uniform3ui) /* 422 */ \ - OP(Uniform3uivImmediate) /* 423 */ \ - OP(Uniform4f) /* 424 */ \ - OP(Uniform4fvImmediate) /* 425 */ \ - OP(Uniform4i) /* 426 */ \ - OP(Uniform4ivImmediate) /* 427 */ \ - OP(Uniform4ui) /* 428 */ \ - OP(Uniform4uivImmediate) /* 429 */ \ - OP(UniformMatrix2fvImmediate) /* 430 */ \ - OP(UniformMatrix2x3fvImmediate) /* 431 */ \ - OP(UniformMatrix2x4fvImmediate) /* 432 */ \ - OP(UniformMatrix3fvImmediate) /* 433 */ \ - OP(UniformMatrix3x2fvImmediate) /* 434 */ \ - OP(UniformMatrix3x4fvImmediate) /* 435 */ \ - OP(UniformMatrix4fvImmediate) /* 436 */ \ - OP(UniformMatrix4x2fvImmediate) /* 437 */ \ - OP(UniformMatrix4x3fvImmediate) /* 438 */ \ - OP(UseProgram) /* 439 */ \ - OP(ValidateProgram) /* 440 */ \ - OP(VertexAttrib1f) /* 441 */ \ - OP(VertexAttrib1fvImmediate) /* 442 */ \ - OP(VertexAttrib2f) /* 443 */ \ - OP(VertexAttrib2fvImmediate) /* 444 */ \ - OP(VertexAttrib3f) /* 445 */ \ - OP(VertexAttrib3fvImmediate) /* 446 */ \ - OP(VertexAttrib4f) /* 447 */ \ - OP(VertexAttrib4fvImmediate) /* 448 */ \ - OP(VertexAttribI4i) /* 449 */ \ - OP(VertexAttribI4ivImmediate) /* 450 */ \ - OP(VertexAttribI4ui) /* 451 */ \ - OP(VertexAttribI4uivImmediate) /* 452 */ \ - OP(VertexAttribIPointer) /* 453 */ \ - OP(VertexAttribPointer) /* 454 */ \ - OP(Viewport) /* 455 */ \ - OP(BlitFramebufferCHROMIUM) /* 456 */ \ - OP(RenderbufferStorageMultisampleCHROMIUM) /* 457 */ \ - OP(RenderbufferStorageMultisampleEXT) /* 458 */ \ - OP(FramebufferTexture2DMultisampleEXT) /* 459 */ \ - OP(TexStorage2DEXT) /* 460 */ \ - OP(GenQueriesEXTImmediate) /* 461 */ \ - OP(DeleteQueriesEXTImmediate) /* 462 */ \ - OP(BeginQueryEXT) /* 463 */ \ - OP(BeginTransformFeedback) /* 464 */ \ - OP(EndQueryEXT) /* 465 */ \ - OP(EndTransformFeedback) /* 466 */ \ - OP(InsertEventMarkerEXT) /* 467 */ \ - OP(PushGroupMarkerEXT) /* 468 */ \ - OP(PopGroupMarkerEXT) /* 469 */ \ - OP(GenVertexArraysOESImmediate) /* 470 */ \ - OP(DeleteVertexArraysOESImmediate) /* 471 */ \ - OP(IsVertexArrayOES) /* 472 */ \ - OP(BindVertexArrayOES) /* 473 */ \ - OP(SwapBuffers) /* 474 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 475 */ \ - OP(EnableFeatureCHROMIUM) /* 476 */ \ - OP(ResizeCHROMIUM) /* 477 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 478 */ \ - OP(RequestExtensionCHROMIUM) /* 479 */ \ - OP(GetProgramInfoCHROMIUM) /* 480 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 481 */ \ - OP(PostSubBufferCHROMIUM) /* 482 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 483 */ \ - OP(CopyTextureCHROMIUM) /* 484 */ \ - OP(DrawArraysInstancedANGLE) /* 485 */ \ - OP(DrawElementsInstancedANGLE) /* 486 */ \ - OP(VertexAttribDivisorANGLE) /* 487 */ \ - OP(GenMailboxCHROMIUM) /* 488 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 489 */ \ - OP(ProduceTextureDirectCHROMIUMImmediate) /* 490 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 491 */ \ - OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 492 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 493 */ \ - OP(GenValuebuffersCHROMIUMImmediate) /* 494 */ \ - OP(DeleteValuebuffersCHROMIUMImmediate) /* 495 */ \ - OP(IsValuebufferCHROMIUM) /* 496 */ \ - OP(BindValuebufferCHROMIUM) /* 497 */ \ - OP(SubscribeValueCHROMIUM) /* 498 */ \ - OP(PopulateSubscribedValuesCHROMIUM) /* 499 */ \ - OP(UniformValuebufferCHROMIUM) /* 500 */ \ - OP(BindTexImage2DCHROMIUM) /* 501 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 502 */ \ - OP(TraceBeginCHROMIUM) /* 503 */ \ - OP(TraceEndCHROMIUM) /* 504 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 505 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 506 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 507 */ \ - OP(WaitAllAsyncTexImage2DCHROMIUM) /* 508 */ \ - OP(DiscardFramebufferEXTImmediate) /* 509 */ \ - OP(LoseContextCHROMIUM) /* 510 */ \ - OP(InsertSyncPointCHROMIUM) /* 511 */ \ - OP(WaitSyncPointCHROMIUM) /* 512 */ \ - OP(DrawBuffersEXTImmediate) /* 513 */ \ - OP(DiscardBackbufferCHROMIUM) /* 514 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 515 */ \ - OP(SwapInterval) /* 516 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 517 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 518 */ \ - OP(BlendBarrierKHR) /* 519 */ + OP(GetActiveUniformBlockiv) /* 331 */ \ + OP(GetActiveUniformBlockName) /* 332 */ \ + OP(GetAttachedShaders) /* 333 */ \ + OP(GetAttribLocation) /* 334 */ \ + OP(GetBooleanv) /* 335 */ \ + OP(GetBufferParameteriv) /* 336 */ \ + OP(GetError) /* 337 */ \ + OP(GetFloatv) /* 338 */ \ + OP(GetFragDataLocation) /* 339 */ \ + OP(GetFramebufferAttachmentParameteriv) /* 340 */ \ + OP(GetIntegerv) /* 341 */ \ + OP(GetInternalformativ) /* 342 */ \ + OP(GetProgramiv) /* 343 */ \ + OP(GetProgramInfoLog) /* 344 */ \ + OP(GetRenderbufferParameteriv) /* 345 */ \ + OP(GetSamplerParameterfv) /* 346 */ \ + OP(GetSamplerParameteriv) /* 347 */ \ + OP(GetShaderiv) /* 348 */ \ + OP(GetShaderInfoLog) /* 349 */ \ + OP(GetShaderPrecisionFormat) /* 350 */ \ + OP(GetShaderSource) /* 351 */ \ + OP(GetString) /* 352 */ \ + OP(GetTexParameterfv) /* 353 */ \ + OP(GetTexParameteriv) /* 354 */ \ + OP(GetUniformBlockIndex) /* 355 */ \ + OP(GetUniformfv) /* 356 */ \ + OP(GetUniformiv) /* 357 */ \ + OP(GetUniformLocation) /* 358 */ \ + OP(GetVertexAttribfv) /* 359 */ \ + OP(GetVertexAttribiv) /* 360 */ \ + OP(GetVertexAttribPointerv) /* 361 */ \ + OP(Hint) /* 362 */ \ + OP(InvalidateFramebufferImmediate) /* 363 */ \ + OP(InvalidateSubFramebufferImmediate) /* 364 */ \ + OP(IsBuffer) /* 365 */ \ + OP(IsEnabled) /* 366 */ \ + OP(IsFramebuffer) /* 367 */ \ + OP(IsProgram) /* 368 */ \ + OP(IsRenderbuffer) /* 369 */ \ + OP(IsSampler) /* 370 */ \ + OP(IsShader) /* 371 */ \ + OP(IsSync) /* 372 */ \ + OP(IsTexture) /* 373 */ \ + OP(IsTransformFeedback) /* 374 */ \ + OP(LineWidth) /* 375 */ \ + OP(LinkProgram) /* 376 */ \ + OP(PauseTransformFeedback) /* 377 */ \ + OP(PixelStorei) /* 378 */ \ + OP(PolygonOffset) /* 379 */ \ + OP(ReadBuffer) /* 380 */ \ + OP(ReadPixels) /* 381 */ \ + OP(ReleaseShaderCompiler) /* 382 */ \ + OP(RenderbufferStorage) /* 383 */ \ + OP(ResumeTransformFeedback) /* 384 */ \ + OP(SampleCoverage) /* 385 */ \ + OP(SamplerParameterf) /* 386 */ \ + OP(SamplerParameterfvImmediate) /* 387 */ \ + OP(SamplerParameteri) /* 388 */ \ + OP(SamplerParameterivImmediate) /* 389 */ \ + OP(Scissor) /* 390 */ \ + OP(ShaderBinary) /* 391 */ \ + OP(ShaderSourceBucket) /* 392 */ \ + OP(StencilFunc) /* 393 */ \ + OP(StencilFuncSeparate) /* 394 */ \ + OP(StencilMask) /* 395 */ \ + OP(StencilMaskSeparate) /* 396 */ \ + OP(StencilOp) /* 397 */ \ + OP(StencilOpSeparate) /* 398 */ \ + OP(TexImage2D) /* 399 */ \ + OP(TexImage3D) /* 400 */ \ + OP(TexParameterf) /* 401 */ \ + OP(TexParameterfvImmediate) /* 402 */ \ + OP(TexParameteri) /* 403 */ \ + OP(TexParameterivImmediate) /* 404 */ \ + OP(TexStorage3D) /* 405 */ \ + OP(TexSubImage2D) /* 406 */ \ + OP(TexSubImage3D) /* 407 */ \ + OP(TransformFeedbackVaryingsBucket) /* 408 */ \ + OP(Uniform1f) /* 409 */ \ + OP(Uniform1fvImmediate) /* 410 */ \ + OP(Uniform1i) /* 411 */ \ + OP(Uniform1ivImmediate) /* 412 */ \ + OP(Uniform1ui) /* 413 */ \ + OP(Uniform1uivImmediate) /* 414 */ \ + OP(Uniform2f) /* 415 */ \ + OP(Uniform2fvImmediate) /* 416 */ \ + OP(Uniform2i) /* 417 */ \ + OP(Uniform2ivImmediate) /* 418 */ \ + OP(Uniform2ui) /* 419 */ \ + OP(Uniform2uivImmediate) /* 420 */ \ + OP(Uniform3f) /* 421 */ \ + OP(Uniform3fvImmediate) /* 422 */ \ + OP(Uniform3i) /* 423 */ \ + OP(Uniform3ivImmediate) /* 424 */ \ + OP(Uniform3ui) /* 425 */ \ + OP(Uniform3uivImmediate) /* 426 */ \ + OP(Uniform4f) /* 427 */ \ + OP(Uniform4fvImmediate) /* 428 */ \ + OP(Uniform4i) /* 429 */ \ + OP(Uniform4ivImmediate) /* 430 */ \ + OP(Uniform4ui) /* 431 */ \ + OP(Uniform4uivImmediate) /* 432 */ \ + OP(UniformBlockBinding) /* 433 */ \ + OP(UniformMatrix2fvImmediate) /* 434 */ \ + OP(UniformMatrix2x3fvImmediate) /* 435 */ \ + OP(UniformMatrix2x4fvImmediate) /* 436 */ \ + OP(UniformMatrix3fvImmediate) /* 437 */ \ + OP(UniformMatrix3x2fvImmediate) /* 438 */ \ + OP(UniformMatrix3x4fvImmediate) /* 439 */ \ + OP(UniformMatrix4fvImmediate) /* 440 */ \ + OP(UniformMatrix4x2fvImmediate) /* 441 */ \ + OP(UniformMatrix4x3fvImmediate) /* 442 */ \ + OP(UseProgram) /* 443 */ \ + OP(ValidateProgram) /* 444 */ \ + OP(VertexAttrib1f) /* 445 */ \ + OP(VertexAttrib1fvImmediate) /* 446 */ \ + OP(VertexAttrib2f) /* 447 */ \ + OP(VertexAttrib2fvImmediate) /* 448 */ \ + OP(VertexAttrib3f) /* 449 */ \ + OP(VertexAttrib3fvImmediate) /* 450 */ \ + OP(VertexAttrib4f) /* 451 */ \ + OP(VertexAttrib4fvImmediate) /* 452 */ \ + OP(VertexAttribI4i) /* 453 */ \ + OP(VertexAttribI4ivImmediate) /* 454 */ \ + OP(VertexAttribI4ui) /* 455 */ \ + OP(VertexAttribI4uivImmediate) /* 456 */ \ + OP(VertexAttribIPointer) /* 457 */ \ + OP(VertexAttribPointer) /* 458 */ \ + OP(Viewport) /* 459 */ \ + OP(BlitFramebufferCHROMIUM) /* 460 */ \ + OP(RenderbufferStorageMultisampleCHROMIUM) /* 461 */ \ + OP(RenderbufferStorageMultisampleEXT) /* 462 */ \ + OP(FramebufferTexture2DMultisampleEXT) /* 463 */ \ + OP(TexStorage2DEXT) /* 464 */ \ + OP(GenQueriesEXTImmediate) /* 465 */ \ + OP(DeleteQueriesEXTImmediate) /* 466 */ \ + OP(BeginQueryEXT) /* 467 */ \ + OP(BeginTransformFeedback) /* 468 */ \ + OP(EndQueryEXT) /* 469 */ \ + OP(EndTransformFeedback) /* 470 */ \ + OP(InsertEventMarkerEXT) /* 471 */ \ + OP(PushGroupMarkerEXT) /* 472 */ \ + OP(PopGroupMarkerEXT) /* 473 */ \ + OP(GenVertexArraysOESImmediate) /* 474 */ \ + OP(DeleteVertexArraysOESImmediate) /* 475 */ \ + OP(IsVertexArrayOES) /* 476 */ \ + OP(BindVertexArrayOES) /* 477 */ \ + OP(SwapBuffers) /* 478 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 479 */ \ + OP(EnableFeatureCHROMIUM) /* 480 */ \ + OP(ResizeCHROMIUM) /* 481 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 482 */ \ + OP(RequestExtensionCHROMIUM) /* 483 */ \ + OP(GetProgramInfoCHROMIUM) /* 484 */ \ + OP(GetUniformBlocksCHROMIUM) /* 485 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 486 */ \ + OP(PostSubBufferCHROMIUM) /* 487 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 488 */ \ + OP(CopyTextureCHROMIUM) /* 489 */ \ + OP(DrawArraysInstancedANGLE) /* 490 */ \ + OP(DrawElementsInstancedANGLE) /* 491 */ \ + OP(VertexAttribDivisorANGLE) /* 492 */ \ + OP(GenMailboxCHROMIUM) /* 493 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 494 */ \ + OP(ProduceTextureDirectCHROMIUMImmediate) /* 495 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 496 */ \ + OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 497 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 498 */ \ + OP(GenValuebuffersCHROMIUMImmediate) /* 499 */ \ + OP(DeleteValuebuffersCHROMIUMImmediate) /* 500 */ \ + OP(IsValuebufferCHROMIUM) /* 501 */ \ + OP(BindValuebufferCHROMIUM) /* 502 */ \ + OP(SubscribeValueCHROMIUM) /* 503 */ \ + OP(PopulateSubscribedValuesCHROMIUM) /* 504 */ \ + OP(UniformValuebufferCHROMIUM) /* 505 */ \ + OP(BindTexImage2DCHROMIUM) /* 506 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 507 */ \ + OP(TraceBeginCHROMIUM) /* 508 */ \ + OP(TraceEndCHROMIUM) /* 509 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 510 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 511 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 512 */ \ + OP(WaitAllAsyncTexImage2DCHROMIUM) /* 513 */ \ + OP(DiscardFramebufferEXTImmediate) /* 514 */ \ + OP(LoseContextCHROMIUM) /* 515 */ \ + OP(InsertSyncPointCHROMIUM) /* 516 */ \ + OP(WaitSyncPointCHROMIUM) /* 517 */ \ + OP(DrawBuffersEXTImmediate) /* 518 */ \ + OP(DiscardBackbufferCHROMIUM) /* 519 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 520 */ \ + OP(SwapInterval) /* 521 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 522 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 523 */ \ + OP(BlendBarrierKHR) /* 524 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index a2f4ca7..282c6b3 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -78,6 +78,7 @@ static std::string GetStringTextureWrapMode(uint32_t value); static std::string GetStringTransformFeedbackBindTarget(uint32_t value); static std::string GetStringTransformFeedbackPrimitiveMode(uint32_t value); +static std::string GetStringUniformBlockParameter(uint32_t value); static std::string GetStringValueBufferTarget(uint32_t value); static std::string GetStringVertexAttribType(uint32_t value); static std::string GetStringVertexAttribute(uint32_t value);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index db3a6c48..559991a 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -5260,6 +5260,23 @@ arraysize(string_table), value); } +std::string GLES2Util::GetStringUniformBlockParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_UNIFORM_BLOCK_BINDING, "GL_UNIFORM_BLOCK_BINDING"}, + {GL_UNIFORM_BLOCK_DATA_SIZE, "GL_UNIFORM_BLOCK_DATA_SIZE"}, + {GL_UNIFORM_BLOCK_NAME_LENGTH, "GL_UNIFORM_BLOCK_NAME_LENGTH"}, + {GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS"}, + {GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES"}, + {GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER"}, + {GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, + "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringValueBufferTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM,
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc index 2389dc1..9b6b7e21 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
@@ -77,13 +77,16 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( gfx::GLContext* context) { DCHECK(context->IsCurrent(NULL)); + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + // Threaded mailbox uses EGLImage which conflicts with EGL uploader. // The spec only allows one EGL image per sibling group, but currently the // image handle cannot be shared between the threaded mailbox code and // AsyncPixelTransferManagerEGL. bool uses_threaded_mailboxes = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableThreadedTextureMailboxes); + cl->HasSwitch(switches::kEnableThreadedTextureMailboxes); + // TexImage2D orphans the EGLImage used for threaded mailbox sharing. + bool use_teximage2d_over_texsubimage2d = !uses_threaded_mailboxes; switch (gfx::GetGLImplementation()) { case gfx::kGLImplementationEGLGLES2: DCHECK(context); @@ -93,15 +96,16 @@ context->HasExtension("EGL_KHR_image_base") && context->HasExtension("EGL_KHR_gl_texture_2D_image") && context->HasExtension("GL_OES_EGL_image") && - !uses_threaded_mailboxes && - AllowTransferThreadForGpu()) { + !uses_threaded_mailboxes && AllowTransferThreadForGpu()) { TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateWithThread"); return new AsyncPixelTransferManagerEGL; } - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle( + use_teximage2d_over_texsubimage2d); case gfx::kGLImplementationOSMesaGL: { TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateIdle"); - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle( + use_teximage2d_over_texsubimage2d); } case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub;
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc index 2ed4f7d9..b44b477404 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
@@ -183,9 +183,8 @@ base::TimeTicks begin_time(base::TimeTicks::Now()); gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_); - // If it's a full texture update, use glTexImage2D as it's faster. - // TODO(epenner): Make this configurable (http://crbug.com/259924) - if (tex_params.xoffset == 0 && + if (shared_state_->use_teximage2d_over_texsubimage2d && + tex_params.xoffset == 0 && tex_params.yoffset == 0 && tex_params.target == define_params_.target && tex_params.level == define_params_.level && @@ -234,8 +233,11 @@ AsyncPixelTransferManagerIdle::Task::~Task() {} -AsyncPixelTransferManagerIdle::SharedState::SharedState() - : texture_upload_count(0) {} +AsyncPixelTransferManagerIdle::SharedState::SharedState( + bool use_teximage2d_over_texsubimage2d) + : use_teximage2d_over_texsubimage2d(use_teximage2d_over_texsubimage2d), + texture_upload_count(0) { +} AsyncPixelTransferManagerIdle::SharedState::~SharedState() {} @@ -250,8 +252,9 @@ } } -AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle() - : shared_state_() { +AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle( + bool use_teximage2d_over_texsubimage2d) + : shared_state_(use_teximage2d_over_texsubimage2d) { } AsyncPixelTransferManagerIdle::~AsyncPixelTransferManagerIdle() {}
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h index 8aba7ff..41a77b3 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h
@@ -13,7 +13,8 @@ class AsyncPixelTransferManagerIdle : public AsyncPixelTransferManager { public: - AsyncPixelTransferManagerIdle(); + explicit AsyncPixelTransferManagerIdle( + bool use_teximage2d_over_texsubimage2d); ~AsyncPixelTransferManagerIdle() override; // AsyncPixelTransferManager implementation: @@ -43,10 +44,11 @@ // State shared between Managers and Delegates. struct SharedState { - SharedState(); + explicit SharedState(bool use_teximage2d_over_texsubimage2d); ~SharedState(); void ProcessNotificationTasks(); + const bool use_teximage2d_over_texsubimage2d; int texture_upload_count; base::TimeDelta total_texture_upload_time; std::list<Task> tasks;
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc index e756a463..b0cc463 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc
@@ -28,7 +28,7 @@ case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: case gfx::kGLImplementationEGLGLES2: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default:
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc index 6f7c5d1..dcc7e18 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc
@@ -18,7 +18,7 @@ case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: case gfx::kGLImplementationAppleGL: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default:
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc index 3bf32c0f..dc106e8 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc
@@ -18,7 +18,7 @@ case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: case gfx::kGLImplementationEGLGLES2: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default:
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc index 21e2ae49..f2444b31 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -79,6 +79,10 @@ put_offset_change_callback_.Run(); } +void CommandBufferService::OrderingBarrier(int32 put_offset) { + Flush(put_offset); +} + void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) { DCHECK_EQ(-1, ring_buffer_id_); DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty.
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index 69b9ad76..28a5f6f 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -52,6 +52,7 @@ State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 transfer_buffer_id) override;
diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc index f40c721..99fdb76 100644 --- a/gpu/command_buffer/service/common_decoder.cc +++ b/gpu/command_buffer/service/common_decoder.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/common_decoder.h" + +#include "base/numerics/safe_math.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" namespace gpu { @@ -69,6 +71,53 @@ return true; } +bool CommonDecoder::Bucket::GetAsStrings( + GLsizei* _count, std::vector<char*>* _string, std::vector<GLint>* _length) { + const size_t kMinBucketSize = sizeof(GLint); + // Each string has at least |length| in the header and a NUL character. + const size_t kMinStringSize = sizeof(GLint) + 1; + const size_t bucket_size = this->size(); + if (bucket_size < kMinBucketSize) { + return false; + } + char* bucket_data = this->GetDataAs<char*>(0, bucket_size); + GLint* header = reinterpret_cast<GLint*>(bucket_data); + GLsizei count = static_cast<GLsizei>(header[0]); + if (count < 0) { + return false; + } + const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; + if (max_count < static_cast<size_t>(count)) { + return false; + } + GLint* length = header + 1; + std::vector<char*> strs(count); + base::CheckedNumeric<size_t> total_size = sizeof(GLint); + total_size *= count + 1; // Header size. + if (!total_size.IsValid()) + return false; + for (GLsizei ii = 0; ii < count; ++ii) { + strs[ii] = bucket_data + total_size.ValueOrDefault(0); + total_size += length[ii]; + total_size += 1; // NUL char at the end of each char array. + if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || + strs[ii][length[ii]] != 0) { + return false; + } + } + if (total_size.ValueOrDefault(0) != bucket_size) { + return false; + } + DCHECK(_count && _string && _length); + *_count = count; + *_string = strs; + _length->resize(count); + for (GLsizei ii = 0; ii < count; ++ii) { + (*_length)[ii] = length[ii]; + } + return true; +} + CommonDecoder::CommonDecoder() : engine_(NULL) {} CommonDecoder::~CommonDecoder() {}
diff --git a/gpu/command_buffer/service/common_decoder.h b/gpu/command_buffer/service/common_decoder.h index fc9ecf2..53de875 100644 --- a/gpu/command_buffer/service/common_decoder.h +++ b/gpu/command_buffer/service/common_decoder.h
@@ -14,6 +14,10 @@ #include "gpu/command_buffer/service/cmd_parser.h" #include "gpu/gpu_export.h" +// Forwardly declare a few GL types to avoid including GL header files. +typedef int GLsizei; +typedef int GLint; + namespace gpu { class CommandBufferEngine; @@ -82,6 +86,13 @@ // is no string. bool GetAsString(std::string* str); + // Gets the bucket data as strings. + // On success, the number of strings are in |_count|, the string data are + // in |_string|, and string sizes are in |_length|.. + bool GetAsStrings(GLsizei* _count, + std::vector<char*>* _string, + std::vector<GLint>* _length); + private: bool OffsetSizeValid(size_t offset, size_t size) const { size_t temp = offset + size;
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 5706086..803b121 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -17,6 +17,10 @@ #include "ui/gl/gl_fence.h" #include "ui/gl/gl_implementation.h" +#if !defined(OS_MACOSX) +#include "ui/gl/gl_fence_egl.h" +#endif + namespace gpu { namespace gles2 { @@ -1020,6 +1024,12 @@ texture_format_validators_[GL_RG_EXT].AddValue(GL_HALF_FLOAT_OES); } } + +#if !defined(OS_MACOSX) + if (workarounds_.ignore_egl_sync_failures) { + gfx::GLFenceEGL::SetIgnoreFailures(); + } +#endif } void FeatureInfo::AddExtensionString(const char* s) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index f37c61a4..706b0a7 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1163,16 +1163,16 @@ GLuint client_id, GLint location, const char* name); error::Error GetAttribLocationHelper( - GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, - const std::string& name_str); + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); error::Error GetUniformLocationHelper( - GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, - const std::string& name_str); + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); error::Error GetFragDataLocationHelper( - GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, - const std::string& name_str); + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); // Wrapper for glShaderSource. void DoShaderSource( @@ -2842,6 +2842,14 @@ DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats); DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &caps.bind_generates_resource_chromium); + if (unsafe_es3_apis_enabled()) { + DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + &caps.max_transform_feedback_separate_attribs); + DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, + &caps.max_uniform_buffer_bindings); + DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, + &caps.uniform_buffer_offset_alignment); + } caps.egl_image_external = feature_info_->feature_flags().oes_egl_image_external; @@ -7051,14 +7059,17 @@ GLuint client_id, GLsizei count, const char** data, const GLint* length) { std::string str; for (GLsizei ii = 0; ii < count; ++ii) { - str.append(data[ii]); + if (length && length[ii] > 0) + str.append(data[ii], length[ii]); + else + str.append(data[ii]); } Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource"); if (!shader) { return; } // Note: We don't actually call glShaderSource here. We wait until - // the call to glCompileShader. + // we actually compile the shader. shader->set_source(str); } @@ -7086,6 +7097,10 @@ vertex_translator_.get() : fragment_translator_.get(); } + shader->RequestCompile(); + + // TODO(dyen): Currently we compile immediately when glCompileShader is + // requested. Eventually this should be deffered to the linker stage. shader->DoCompile( translator, feature_info_->feature_flags().angle_translated_shader_source ? @@ -8186,6 +8201,39 @@ c.program, c.location_shm_id, c.location_shm_offset, name_str); } +error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformBlockIndex& c = + *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + GLuint* index = GetSharedMemoryAs<GLuint*>( + c.index_shm_id, c.index_shm_offset, sizeof(GLuint)); + if (!index) { + return error::kOutOfBounds; + } + // Require the client to init this in case the context is lost and we are no + // longer executing commands. + if (*index != GL_INVALID_INDEX) { + return error::kGenericError; + } + Program* program = GetProgramInfoNotShader( + c.program, "glGetUniformBlockIndex"); + if (!program) { + return error::kNoError; + } + *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str()); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, const void* cmd_data) { const gles2::cmds::GetString& c = @@ -9682,6 +9730,116 @@ return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetActiveUniformBlockiv& c = + *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data); + GLuint program_id = c.program; + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + Program* program = GetProgramInfoNotShader( + program_id, "glGetActiveUniformBlockiv"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetActiveActiveUniformBlockiv", "program not linked"); + return error::kNoError; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv"); + GLsizei num_values = 1; + if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) { + GLint num = 0; + glGetActiveUniformBlockiv( + service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + // Assume this will the same error if calling with pname. + LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", ""); + return error::kNoError; + } + num_values = static_cast<GLsizei>(num); + } + typedef cmds::GetActiveUniformBlockiv::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + glGetActiveUniformBlockiv(service_id, index, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetActiveUniformBlockName& c = + *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data); + GLuint program_id = c.program; + GLuint index = c.index; + uint32 name_bucket_id = c.name_bucket_id; + typedef cmds::GetActiveUniformBlockName::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (*result != 0) { + return error::kInvalidArguments; + } + Program* program = GetProgramInfoNotShader( + program_id, "glGetActiveUniformBlockName"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetActiveActiveUniformBlockName", "program not linked"); + return error::kNoError; + } + GLint max_length = 0; + glGetProgramiv( + service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length); + // Increase one so &buffer[0] is always valid. + GLsizei buf_size = static_cast<GLsizei>(max_length) + 1; + std::vector<char> buffer(buf_size); + GLsizei length = 0; + glGetActiveUniformBlockName( + service_id, index, buf_size, &length, &buffer[0]); + if (length == 0) { + *result = 0; + return error::kNoError; + } + *result = 1; + Bucket* bucket = CreateBucket(name_bucket_id); + DCHECK_GT(buf_size, length); + DCHECK_EQ(0, buffer[length]); + bucket->SetFromString(&buffer[0]); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size, const void* cmd_data) { const gles2::cmds::GetActiveAttrib& c = @@ -10016,6 +10174,25 @@ return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformBlocksCHROMIUM& c = + *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data); + GLuint program_id = static_cast<GLuint>(c.program); + uint32 bucket_id = c.bucket_id; + Bucket* bucket = CreateBucket(bucket_id); + bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail. + Program* program = NULL; + program = GetProgram(program_id); + if (!program || !program->IsValid()) { + return error::kNoError; + } + program->GetUniformBlocks(bucket); + return error::kNoError; +} + error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { switch (reset_status_) { case GL_NO_ERROR: @@ -11652,6 +11829,25 @@ return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniformBlockBinding( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformBlockBinding& c = + *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data); + GLuint client_id = c.program; + GLuint index = static_cast<GLuint>(c.index); + GLuint binding = static_cast<GLuint>(c.binding); + Program* program = GetProgramInfoNotShader( + client_id, "glUniformBlockBinding"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + glUniformBlockBinding(service_id, index, binding); + return error::kNoError; +} + void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( TextureRef* texture_ref) { Texture* texture = texture_ref->texture();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 720d54e3..49fa872 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2432,48 +2432,21 @@ (void)c; GLuint shader = static_cast<GLuint>(c.shader); - const size_t kMinBucketSize = sizeof(GLint); - // Each string has at least |length| in the header and a NUL character. - const size_t kMinStringSize = sizeof(GLint) + 1; Bucket* bucket = GetBucket(c.str_bucket_id); if (!bucket) { return error::kInvalidArguments; } - const size_t bucket_size = bucket->size(); - if (bucket_size < kMinBucketSize) { + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { return error::kInvalidArguments; } - const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size); - const GLint* header = reinterpret_cast<const GLint*>(bucket_data); - GLsizei count = static_cast<GLsizei>(header[0]); - if (count < 0) { - return error::kInvalidArguments; - } - const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; - if (max_count < static_cast<size_t>(count)) { - return error::kInvalidArguments; - } - const GLint* length = header + 1; - scoped_ptr<const char* []> strs; - if (count > 0) - strs.reset(new const char* [count]); - const char** str = strs.get(); - base::CheckedNumeric<size_t> total_size = sizeof(GLint); - total_size *= count + 1; // Header size. - if (!total_size.IsValid()) - return error::kInvalidArguments; - for (GLsizei ii = 0; ii < count; ++ii) { - str[ii] = bucket_data + total_size.ValueOrDefault(0); - total_size += length[ii]; - total_size += 1; // NUL char at the end of each char array. - if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || - str[ii][length[ii]] != 0) { - return error::kInvalidArguments; - } - } - if (total_size.ValueOrDefault(0) != bucket_size) { - return error::kInvalidArguments; - } + const char** str = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; DoShaderSource(shader, count, str, length); return error::kNoError; } @@ -2817,48 +2790,21 @@ (void)c; GLuint program = static_cast<GLuint>(c.program); - const size_t kMinBucketSize = sizeof(GLint); - // Each string has at least |length| in the header and a NUL character. - const size_t kMinStringSize = sizeof(GLint) + 1; Bucket* bucket = GetBucket(c.varyings_bucket_id); if (!bucket) { return error::kInvalidArguments; } - const size_t bucket_size = bucket->size(); - if (bucket_size < kMinBucketSize) { + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { return error::kInvalidArguments; } - const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size); - const GLint* header = reinterpret_cast<const GLint*>(bucket_data); - GLsizei count = static_cast<GLsizei>(header[0]); - if (count < 0) { - return error::kInvalidArguments; - } - const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; - if (max_count < static_cast<size_t>(count)) { - return error::kInvalidArguments; - } - const GLint* length = header + 1; - scoped_ptr<const char* []> strs; - if (count > 0) - strs.reset(new const char* [count]); - const char** varyings = strs.get(); - base::CheckedNumeric<size_t> total_size = sizeof(GLint); - total_size *= count + 1; // Header size. - if (!total_size.IsValid()) - return error::kInvalidArguments; - for (GLsizei ii = 0; ii < count; ++ii) { - varyings[ii] = bucket_data + total_size.ValueOrDefault(0); - total_size += length[ii]; - total_size += 1; // NUL char at the end of each char array. - if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || - varyings[ii][length[ii]] != 0) { - return error::kInvalidArguments; - } - } - if (total_size.ValueOrDefault(0) != bucket_size) { - return error::kInvalidArguments; - } + const char** varyings = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; GLenum buffermode = static_cast<GLenum>(c.buffermode); DoTransformFeedbackVaryings(program, count, varyings, buffermode); return error::kNoError;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 2b6a38f..3508768 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -85,10 +85,10 @@ TEST_P(GLES2DecoderTest1, BindBufferRangeValidArgs) { EXPECT_CALL(*gl_, BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, - kServiceBufferId, 4, 5)); + kServiceBufferId, 4, 4)); SpecializedSetup<cmds::BindBufferRange, 0>(true); cmds::BindBufferRange cmd; - cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_, 4, 5); + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_, 4, 4); decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -98,12 +98,12 @@ TEST_P(GLES2DecoderTest1, BindBufferRangeValidArgsNewId) { EXPECT_CALL(*gl_, BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, - kNewServiceId, 4, 5)); + kNewServiceId, 4, 4)); EXPECT_CALL(*gl_, GenBuffersARB(1, _)) .WillOnce(SetArgumentPointee<1>(kNewServiceId)); SpecializedSetup<cmds::BindBufferRange, 0>(true); cmds::BindBufferRange cmd; - cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId, 4, 5); + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId, 4, 4); decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -1208,6 +1208,10 @@ // TODO(gman): GetActiveUniform +// TODO(gman): GetActiveUniformBlockiv + +// TODO(gman): GetActiveUniformBlockName + // TODO(gman): GetAttachedShaders // TODO(gman): GetAttribLocation @@ -1879,80 +1883,4 @@ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); EXPECT_EQ(0u, result->size); } - -TEST_P(GLES2DecoderTest1, GetTexParameterivValidArgs) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - SpecializedSetup<cmds::GetTexParameteriv, 0>(true); - typedef cmds::GetTexParameteriv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, GetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - result->GetData())); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ( - decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs1_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} -// TODO(gman): GetUniformfv - #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index 2947723a..5a3f3b4a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -12,6 +12,83 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ +TEST_P(GLES2DecoderTest2, GetTexParameterivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetTexParameteriv, 0>(true); + typedef cmds::GetTexParameteriv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + result->GetData())); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs0_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs1_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} +// TODO(gman): GetUniformBlockIndex + +// TODO(gman): GetUniformfv + // TODO(gman): GetUniformiv // TODO(gman): GetUniformLocation @@ -1213,6 +1290,7 @@ decoder_->set_unsafe_es3_apis_enabled(false); EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); } +// TODO(gman): UniformBlockBinding TEST_P(GLES2DecoderTest2, UniformMatrix2fvImmediateValidArgs) { cmds::UniformMatrix2fvImmediate& cmd = @@ -1471,59 +1549,4 @@ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } - -TEST_P(GLES2DecoderTest2, VertexAttrib4fvImmediateValidArgs) { - cmds::VertexAttrib4fvImmediate& cmd = - *GetImmediateAs<cmds::VertexAttrib4fvImmediate>(); - SpecializedSetup<cmds::VertexAttrib4fvImmediate, 0>(true); - GLfloat temp[4] = { - 0, - }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttrib4fv(1, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttribI4iValidArgs) { - EXPECT_CALL(*gl_, VertexAttribI4i(1, 2, 3, 4, 5)); - SpecializedSetup<cmds::VertexAttribI4i, 0>(true); - cmds::VertexAttribI4i cmd; - cmd.Init(1, 2, 3, 4, 5); - decoder_->set_unsafe_es3_apis_enabled(true); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - decoder_->set_unsafe_es3_apis_enabled(false); - EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest2, VertexAttribI4ivImmediateValidArgs) { - cmds::VertexAttribI4ivImmediate& cmd = - *GetImmediateAs<cmds::VertexAttribI4ivImmediate>(); - SpecializedSetup<cmds::VertexAttribI4ivImmediate, 0>(true); - GLint temp[4] = { - 0, - }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttribI4iv(1, reinterpret_cast<GLint*>( - ImmediateDataAddress(&cmd)))); - decoder_->set_unsafe_es3_apis_enabled(true); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - decoder_->set_unsafe_es3_apis_enabled(false); - EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); -} - -TEST_P(GLES2DecoderTest2, VertexAttribI4uiValidArgs) { - EXPECT_CALL(*gl_, VertexAttribI4ui(1, 2, 3, 4, 5)); - SpecializedSetup<cmds::VertexAttribI4ui, 0>(true); - cmds::VertexAttribI4ui cmd; - cmd.Init(1, 2, 3, 4, 5); - decoder_->set_unsafe_es3_apis_enabled(true); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - decoder_->set_unsafe_es3_apis_enabled(false); - EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); -} #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 2eb4e58..7e6c5d10 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -12,6 +12,61 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ +TEST_P(GLES2DecoderTest3, VertexAttrib4fvImmediateValidArgs) { + cmds::VertexAttrib4fvImmediate& cmd = + *GetImmediateAs<cmds::VertexAttrib4fvImmediate>(); + SpecializedSetup<cmds::VertexAttrib4fvImmediate, 0>(true); + GLfloat temp[4] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttrib4fv(1, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4iValidArgs) { + EXPECT_CALL(*gl_, VertexAttribI4i(1, 2, 3, 4, 5)); + SpecializedSetup<cmds::VertexAttribI4i, 0>(true); + cmds::VertexAttribI4i cmd; + cmd.Init(1, 2, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4ivImmediateValidArgs) { + cmds::VertexAttribI4ivImmediate& cmd = + *GetImmediateAs<cmds::VertexAttribI4ivImmediate>(); + SpecializedSetup<cmds::VertexAttribI4ivImmediate, 0>(true); + GLint temp[4] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttribI4iv(1, reinterpret_cast<GLint*>( + ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4uiValidArgs) { + EXPECT_CALL(*gl_, VertexAttribI4ui(1, 2, 3, 4, 5)); + SpecializedSetup<cmds::VertexAttribI4ui, 0>(true); + cmds::VertexAttribI4ui cmd; + cmd.Init(1, 2, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest3, VertexAttribI4uivImmediateValidArgs) { cmds::VertexAttribI4uivImmediate& cmd = *GetImmediateAs<cmds::VertexAttribI4uivImmediate>(); @@ -113,6 +168,8 @@ // TODO(gman): GetProgramInfoCHROMIUM +// TODO(gman): GetUniformBlocksCHROMIUM + // TODO(gman): GetTranslatedShaderSourceANGLE // TODO(gman): PostSubBufferCHROMIUM // TODO(gman): TexImageIOSurface2DCHROMIUM
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc index 5eda0a9..f5ef1d2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
@@ -81,6 +81,47 @@ EXPECT_EQ(0u, info->num_uniforms); } +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlocksCHROMIUMValidArgs) { + const uint32 kBucketId = 123; + GetUniformBlocksCHROMIUM cmd; + cmd.Init(client_program_id_, kBucketId); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket->size()); + UniformBlocksHeader* header = + bucket->GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlocksCHROMIUMInvalidArgs) { + const uint32 kBucketId = 123; + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_TRUE(bucket == NULL); + GetUniformBlocksCHROMIUM cmd; + cmd.Init(kInvalidClientId, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket->size()); + UniformBlocksHeader* header = + bucket->GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + ASSERT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); +} + TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); @@ -530,6 +571,285 @@ EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameSucceeds) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + const char kName[] = "HolyCow"; + const GLsizei kMaxLength = strlen(kName) + 1; + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, _)) + .WillOnce(SetArgPointee<2>(kMaxLength)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockName(kServiceProgramId, 0, _, _, _)) + .WillOnce(DoAll(SetArgPointee<3>(strlen(kName)), + SetArrayArgument<4>(kName, kName + strlen(kName) + 1))) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, *result); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(0, + memcmp(bucket->GetData(0, bucket->size()), kName, bucket->size())); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameUnlinkedProgram) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, *result); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockNameResultNotInitFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 1; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameBadProgramFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(kInvalidClientId, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockNameBadSharedMemoryFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(client_program_id_, + 0, + kBucketId, + kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivSucceeds) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + GLenum kPname[] { + GL_UNIFORM_BLOCK_BINDING, + GL_UNIFORM_BLOCK_DATA_SIZE, + GL_UNIFORM_BLOCK_NAME_LENGTH, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, + }; + for (size_t ii = 0; ii < arraysize(kPname); ++ii) { + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + kPname[ii], + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + if (kPname[ii] == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv(kServiceProgramId, 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<3>(1)) + .RetiresOnSaturation(); + } + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv( + kServiceProgramId, 0, kPname[ii], _)) + .WillOnce(SetArgPointee<3>(1976)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(1976, result->GetData()[0]); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + } +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivSucceedsZeroUniforms) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv( + kServiceProgramId, 0, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<3>(0)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv(kServiceProgramId, 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, _)) + .Times(1) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivUnlinkedProgram) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivResultNotInitFails) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(1); // Should be initialized to 0. + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivBadProgramFails) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(kInvalidClientId, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivBadSharedMemoryFails) { + GetActiveUniformBlockiv cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) { const GLuint kAttribIndex = 1; const uint32 kBucketId = 123; @@ -927,6 +1247,58 @@ EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlockIndex) { + const uint32 kBucketId = 123; + const GLuint kIndex = 10; + const char* kName = "color"; + typedef GetUniformBlockIndex::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + SetBucketAsCString(kBucketId, kName); + *result = GL_INVALID_INDEX; + GetUniformBlockIndex cmd; + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformBlockIndex(kServiceProgramId, StrEq(kName))) + .WillOnce(Return(kIndex)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kIndex, *result); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlockIndexInvalidArgs) { + const uint32 kBucketId = 123; + typedef GetUniformBlockIndex::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = GL_INVALID_INDEX; + GetUniformBlockIndex cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + // Check no bucket + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_INDEX, *result); + // Check bad program id. + const char* kName = "color"; + SetBucketAsCString(kBucketId, kName); + cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + *result = GL_INVALID_INDEX; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_INDEX, *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Check bad memory + cmd.Init(client_program_id_, + kBucketId, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, GetUniformLocation) { const uint32 kBucketId = 123; const char* kNonExistentName = "foobar"; @@ -975,6 +1347,18 @@ EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, UniformBlockBindingValidArgs) { + EXPECT_CALL(*gl_, UniformBlockBinding(kServiceProgramId, 2, 3)); + SpecializedSetup<cmds::UniformBlockBinding, 0>(true); + cmds::UniformBlockBinding cmd; + cmd.Init(client_program_id_, 2, 3); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUMBucket) { const uint32 kBucketId = 123; const GLint kLocation = 2;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index 6c9d377..c173a020 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -78,6 +78,7 @@ ValueValidator<GLenum> texture_wrap_mode; ValueValidator<GLenum> transform_feedback_bind_target; ValueValidator<GLenum> transform_feedback_primitive_mode; +ValueValidator<GLenum> uniform_block_parameter; ValueValidator<GLenum> value_buffer_target; ValueValidator<GLint> vertex_attrib_size; ValueValidator<GLenum> vertex_attrib_type;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 1f1211b..9727f76 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -552,6 +552,16 @@ GL_TRIANGLES, }; +static const GLenum valid_uniform_block_parameter_table[] = { + GL_UNIFORM_BLOCK_BINDING, + GL_UNIFORM_BLOCK_DATA_SIZE, + GL_UNIFORM_BLOCK_NAME_LENGTH, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, +}; + static const GLenum valid_value_buffer_target_table[] = { GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, }; @@ -698,6 +708,8 @@ transform_feedback_primitive_mode( valid_transform_feedback_primitive_mode_table, arraysize(valid_transform_feedback_primitive_mode_table)), + uniform_block_parameter(valid_uniform_block_parameter_table, + arraysize(valid_uniform_block_parameter_table)), value_buffer_target(valid_value_buffer_target_table, arraysize(valid_value_buffer_target_table)), vertex_attrib_size(valid_vertex_attrib_size_table,
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index 7a6556b..5db80b0 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -631,6 +631,10 @@ QueueTask(task); } +void InProcessCommandBuffer::OrderingBarrier(int32 put_offset) { + Flush(put_offset); +} + void InProcessCommandBuffer::WaitForTokenInRange(int32 start, int32 end) { CheckSequencedThread(); while (!InRange(start, end, GetLastToken()) &&
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index ab68f152..3be36023 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -92,6 +92,7 @@ State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 shm_id) override;
diff --git a/gpu/command_buffer/service/mailbox_manager_sync.cc b/gpu/command_buffer/service/mailbox_manager_sync.cc index b12e9b4..4f24bd7 100644 --- a/gpu/command_buffer/service/mailbox_manager_sync.cc +++ b/gpu/command_buffer/service/mailbox_manager_sync.cc
@@ -59,7 +59,7 @@ sync_points.pop(); } // Need to use EGL fences since we are likely not in a single share group. - linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL(true))); + linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL)); if (fence.get()) { std::pair<SyncPointToFenceMap::iterator, bool> result = sync_point_to_fence.insert(std::make_pair(sync_point, fence));
diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc index 4bf16e3..1e8e11b8 100644 --- a/gpu/command_buffer/service/memory_program_cache.cc +++ b/gpu/command_buffer/service/memory_program_cache.cc
@@ -180,12 +180,12 @@ const ShaderCacheCallback& shader_callback) { char a_sha[kHashLength]; char b_sha[kHashLength]; - DCHECK(shader_a && !shader_a->signature_source().empty() && - shader_b && !shader_b->signature_source().empty()); + DCHECK(shader_a && !shader_a->last_compiled_source().empty() && + shader_b && !shader_b->last_compiled_source().empty()); ComputeShaderHash( - shader_a->signature_source(), translator_a, a_sha); + shader_a->last_compiled_source(), translator_a, a_sha); ComputeShaderHash( - shader_b->signature_source(), translator_b, b_sha); + shader_b->last_compiled_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -256,12 +256,12 @@ char a_sha[kHashLength]; char b_sha[kHashLength]; - DCHECK(shader_a && !shader_a->signature_source().empty() && - shader_b && !shader_b->signature_source().empty()); + DCHECK(shader_a && !shader_a->last_compiled_source().empty() && + shader_b && !shader_b->last_compiled_source().empty()); ComputeShaderHash( - shader_a->signature_source(), translator_a, a_sha); + shader_a->last_compiled_source(), translator_a, a_sha); ComputeShaderHash( - shader_b->signature_source(), translator_b, b_sha); + shader_b->last_compiled_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha,
diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc index 7c39028..8f8c430 100644 --- a/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -196,9 +196,9 @@ base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); @@ -221,9 +221,9 @@ base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); @@ -232,9 +232,9 @@ cache_->LoadProgram(shader_cache_shader()); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); } @@ -396,7 +396,7 @@ base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); - const std::string vertex_orig_source = vertex_shader_->signature_source(); + const std::string vertex_orig_source = vertex_shader_->last_compiled_source(); vertex_shader_->set_source("different!"); TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( @@ -488,7 +488,7 @@ const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1; // save old source and modify for new program - const std::string& old_source = fragment_shader_->signature_source(); + const std::string& old_source = fragment_shader_->last_compiled_source(); fragment_shader_->set_source("al sdfkjdk"); TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true); @@ -512,15 +512,15 @@ base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( old_source, NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); } @@ -543,9 +543,9 @@ base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL)); } @@ -567,9 +567,9 @@ base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), + vertex_shader_->last_compiled_source(), NULL, - fragment_shader_->signature_source(), + fragment_shader_->last_compiled_source(), NULL, NULL));
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index d866504..1f6b2d49 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc
@@ -562,12 +562,12 @@ bool link = true; ProgramCache* cache = manager_->program_cache_; if (cache) { - DCHECK(!attached_shaders_[0]->signature_source().empty() && - !attached_shaders_[1]->signature_source().empty()); + DCHECK(!attached_shaders_[0]->last_compiled_source().empty() && + !attached_shaders_[1]->last_compiled_source().empty()); ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( - attached_shaders_[0]->signature_source(), + attached_shaders_[0]->last_compiled_source(), vertex_translator, - attached_shaders_[1]->signature_source(), + attached_shaders_[1]->last_compiled_source(), fragment_translator, &bind_attrib_location_map_);
diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc index 2707b90..90b1576 100644 --- a/gpu/command_buffer/service/shader_manager.cc +++ b/gpu/command_buffer/service/shader_manager.cc
@@ -26,6 +26,7 @@ Shader::Shader(GLuint service_id, GLenum shader_type) : use_count_(0), + shader_state_(kShaderStateWaiting), service_id_(service_id), shader_type_(shader_type), valid_(false) { @@ -34,13 +35,28 @@ Shader::~Shader() { } +void Shader::RequestCompile() { + shader_state_ = kShaderStateCompileRequested; + last_compiled_source_ = source_; +} + void Shader::DoCompile(ShaderTranslatorInterface* translator, TranslatedShaderSourceType type) { + // We require that RequestCompile() must be called before DoCompile(), + // so we can return early if the shader state is not what we expect. + if (shader_state_ != kShaderStateCompileRequested) { + return; + } + + // Signify the shader has been compiled, whether or not it is valid + // is dependent on the |valid_| member variable. + shader_state_ = kShaderStateCompiled; + // Translate GL ES 2.0 shader to Desktop GL shader and pass that to // glShaderSource and then glCompileShader. - const char* source_for_driver = source_.c_str(); + const char* source_for_driver = last_compiled_source_.c_str(); if (translator) { - valid_ = translator->Translate(source_, + valid_ = translator->Translate(last_compiled_source_, &log_info_, &translated_source_, &attrib_map_, @@ -50,7 +66,6 @@ if (!valid_) { return; } - signature_source_ = source_; source_for_driver = translated_source_.c_str(); } @@ -61,13 +76,14 @@ glGetShaderiv(service_id_, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &max_len); - scoped_ptr<char[]> buffer(new char[max_len]); + translated_source_.resize(max_len); GLint len = 0; glGetTranslatedShaderSourceANGLE( - service_id_, max_len, &len, buffer.get()); + service_id_, translated_source_.size(), + &len, &translated_source_.at(0)); DCHECK(max_len == 0 || len < max_len); - DCHECK(len == 0 || buffer[len] == '\0'); - translated_source_ = std::string(buffer.get(), len); + DCHECK(len == 0 || translated_source_[len] == '\0'); + translated_source_.resize(len); } GLint status = GL_FALSE; @@ -78,17 +94,17 @@ // All translated shaders must compile. GLint max_len = 0; glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); - scoped_ptr<char[]> buffer(new char[max_len]); + log_info_.resize(max_len); GLint len = 0; - glGetShaderInfoLog(service_id_, max_len, &len, buffer.get()); + glGetShaderInfoLog(service_id_, log_info_.size(), &len, &log_info_.at(0)); DCHECK(max_len == 0 || len < max_len); - DCHECK(len == 0 || buffer[len] == '\0'); + DCHECK(len == 0 || log_info_[len] == '\0'); valid_ = false; - log_info_ = std::string(buffer.get(), len); + log_info_.resize(len); LOG_IF(ERROR, translator) << "Shader translator allowed/produced an invalid shader " << "unless the driver is buggy:" - << "\n--original-shader--\n" << source_ + << "\n--original-shader--\n" << last_compiled_source_ << "\n--translated-shader--\n" << source_for_driver << "\n--info-log--\n" << log_info_; }
diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h index c726767..11f567d4 100644 --- a/gpu/command_buffer/service/shader_manager.h +++ b/gpu/command_buffer/service/shader_manager.h
@@ -29,9 +29,21 @@ kGL, // GL or GLES }; + enum ShaderState { + kShaderStateWaiting, + kShaderStateCompileRequested, + kShaderStateCompiled, // Signifies compile happened, not valid compile. + }; + + void RequestCompile(); + void DoCompile(ShaderTranslatorInterface* translator, TranslatedShaderSourceType type); + ShaderState shader_state() const { + return shader_state_; + } + GLuint service_id() const { return service_id_; } @@ -52,8 +64,8 @@ return translated_source_; } - const std::string& signature_source() const { - return signature_source_; + const std::string& last_compiled_source() const { + return last_compiled_source_; } const sh::Attribute* GetAttribInfo(const std::string& name) const; @@ -73,7 +85,7 @@ } bool valid() const { - return valid_; + return shader_state_ == kShaderStateCompiled && valid_; } bool IsDeleted() const { @@ -131,8 +143,12 @@ int use_count_; + // The current state of the shader. + ShaderState shader_state_; + // The shader this Shader is tracking. GLuint service_id_; + // Type of shader - GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. GLenum shader_type_; @@ -143,7 +159,7 @@ std::string source_; // The source the last compile used. - std::string signature_source_; + std::string last_compiled_source_; // The translated shader source. std::string translated_source_;
diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc index 4218d50..f5f6206 100644 --- a/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/gpu/command_buffer/service/shader_manager_unittest.cc
@@ -127,16 +127,30 @@ EXPECT_FALSE(shader1->InUse()); EXPECT_TRUE(shader1->source().empty()); EXPECT_TRUE(shader1->log_info().empty()); - EXPECT_TRUE(shader1->signature_source().empty()); + EXPECT_TRUE(shader1->last_compiled_source().empty()); EXPECT_TRUE(shader1->translated_source().empty()); EXPECT_EQ(0u, shader1->attrib_map().size()); EXPECT_EQ(0u, shader1->uniform_map().size()); EXPECT_EQ(0u, shader1->varying_map().size()); + EXPECT_EQ(Shader::kShaderStateWaiting, shader1->shader_state()); // Check we can set its source. shader1->set_source(kClient1Source); EXPECT_STREQ(kClient1Source, shader1->source().c_str()); - EXPECT_TRUE(shader1->signature_source().empty()); + EXPECT_TRUE(shader1->last_compiled_source().empty()); + + // Check that DoCompile() will not work if RequestCompile() was not called. + MockShaderTranslator translator; + shader1->DoCompile(&translator, Shader::kANGLE); + EXPECT_EQ(Shader::kShaderStateWaiting, shader1->shader_state()); + EXPECT_FALSE(shader1->valid()); + + // Check RequestCompile() will update the state and last compiled source, but + // still keep the actual compile state invalid. + shader1->RequestCompile(); + EXPECT_EQ(Shader::kShaderStateCompileRequested, shader1->shader_state()); + EXPECT_STREQ(kClient1Source, shader1->last_compiled_source().c_str()); + EXPECT_FALSE(shader1->valid()); // Check DoCompile() will set compilation states, log, translated source, // shader variables, and name mapping. @@ -168,7 +182,7 @@ EXPECT_TRUE(shader1->valid()); // When compilation succeeds, no log is recorded. EXPECT_STREQ("", shader1->log_info().c_str()); - EXPECT_STREQ(kClient1Source, shader1->signature_source().c_str()); + EXPECT_STREQ(kClient1Source, shader1->last_compiled_source().c_str()); EXPECT_STREQ(kTranslatedSource.c_str(), shader1->translated_source().c_str()); // Check varying infos got copied.
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc index 878490c3..98d738d7 100644 --- a/gpu/command_buffer/service/shader_translator.cc +++ b/gpu/command_buffer/service/shader_translator.cc
@@ -123,7 +123,6 @@ compiler_ = ShConstructCompiler( shader_type, shader_spec, shader_output, resources); } - compiler_options_ = *resources; implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES); driver_bug_workarounds_ = driver_bug_workarounds; return compiler_ != NULL;
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h index 6075896..ef25ebb 100644 --- a/gpu/command_buffer/service/shader_translator.h +++ b/gpu/command_buffer/service/shader_translator.h
@@ -110,7 +110,6 @@ int GetCompileOptions() const; ShHandle compiler_; - ShBuiltInResources compiler_options_; bool implementation_is_glsl_es_; ShCompileOptions driver_bug_workarounds_; ObserverList<DestructionObserver> destruction_observers_;
diff --git a/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc index 621e6a1..174edaa 100644 --- a/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc +++ b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
@@ -23,23 +23,23 @@ const base::Closure& release_callback); // implement gfx::GLImage - virtual void Destroy(bool have_context) override; - virtual gfx::Size GetSize() override; - virtual bool BindTexImage(unsigned target) override; - virtual void ReleaseTexImage(unsigned target) override; - virtual bool CopyTexImage(unsigned target) override; - virtual void WillUseTexImage() override; - virtual void DidUseTexImage() override {} - virtual void WillModifyTexImage() override {} - virtual void DidModifyTexImage() override {} - virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int z_order, - gfx::OverlayTransform transform, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect) override; + void Destroy(bool have_context) override; + gfx::Size GetSize() override; + bool BindTexImage(unsigned target) override; + void ReleaseTexImage(unsigned target) override; + bool CopyTexImage(unsigned target) override; + void WillUseTexImage() override; + void DidUseTexImage() override {} + void WillModifyTexImage() override {} + void DidModifyTexImage() override {} + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override; private: - virtual ~GLImageImpl(); + ~GLImageImpl() override; scoped_refptr<gfx::SurfaceTexture> surface_texture_; base::Closure release_callback_;
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index 550e0cd..6cd0acf6 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc
@@ -790,6 +790,7 @@ .WillOnce(SetArgumentPointee<2>(GL_TRUE)) .RetiresOnSaturation(); } + shader->RequestCompile(); shader->DoCompile(&translator, Shader::kGL); }
diff --git a/gpu/command_buffer/tests/gl_program_unittest.cc b/gpu/command_buffer/tests/gl_program_unittest.cc index aec95b2..186b28b 100644 --- a/gpu/command_buffer/tests/gl_program_unittest.cc +++ b/gpu/command_buffer/tests/gl_program_unittest.cc
@@ -121,6 +121,35 @@ GLTestHelper::CheckGLError("no errors", __LINE__); } +TEST_F(GLProgramTest, ShaderLengthSpecified) { + const std::string valid_shader_str = SHADER( + attribute vec4 a_position; + void main() + { + gl_Position = a_position; + } + ); + + const std::string invalid_shader = valid_shader_str + "invalid suffix"; + + // Compiling invalid program should fail. + const char* invalid_shader_strings[] = { invalid_shader.c_str() }; + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, invalid_shader_strings, NULL); + glCompileShader(vs); + + GLint compile_state = 0; + glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state); + EXPECT_EQ(GL_FALSE, compile_state); + + // Compiling program cutting off invalid parts should succeed. + const GLint lengths[] = { valid_shader_str.length() }; + glShaderSource(vs, 1, invalid_shader_strings, lengths); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state); + EXPECT_EQ(GL_TRUE, compile_state); +} + TEST_F(GLProgramTest, UniformsInCurrentProgram) { static const char* v_shader_str = SHADER( attribute vec4 a_position;
diff --git a/gpu/command_buffer/tests/gl_unittests_android.cc b/gpu/command_buffer/tests/gl_unittests_android.cc index d3517a6..9bdd503 100644 --- a/gpu/command_buffer/tests/gl_unittests_android.cc +++ b/gpu/command_buffer/tests/gl_unittests_android.cc
@@ -22,13 +22,9 @@ class GLSurfaceTextureTest : public testing::Test { protected: - virtual void SetUp() override { - gl_.Initialize(GLManager::Options()); - } + void SetUp() override { gl_.Initialize(GLManager::Options()); } - virtual void TearDown() override { - gl_.Destroy(); - } + void TearDown() override { gl_.Destroy(); } GLManager gl_; };
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index 26be952..b3bfa9fd 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@ { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "7.14", + "version": "7.16", "entries": [ { "id": 1, @@ -1118,6 +1118,34 @@ "features": [ "use_non_zero_size_for_client_side_stream_buffers" ] + }, + { + "id": 99, + "description": "Qualcomm driver before Lollipop deletes egl sync objects after context destruction", + "cr_bugs": [453857], + "os": { + "type": "android", + "version": { + "op": "<", + "value": "5.0.0" + } + }, + "gl_vendor": "Qualcomm.*", + "features": [ + "ignore_egl_sync_failures" + ] + }, + { + "id": 100, + "description": "Disable Direct3D11 on systems with AMD switchable graphics", + "cr_bugs": [451420], + "os": { + "type": "win" + }, + "multi_gpu_style": "amd_switchable", + "features": [ + "disable_d3d11" + ] } ] }
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 77d721b9..f03b7a2 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -58,6 +58,8 @@ gl_begin_gl_end_on_fbo_change_to_backbuffer) \ GPU_OP(GL_CLEAR_BROKEN, \ gl_clear_broken) \ + GPU_OP(IGNORE_EGL_SYNC_FAILURES, \ + ignore_egl_sync_failures) \ GPU_OP(INIT_GL_POSITION_IN_VERTEX_SHADER, \ init_gl_position_in_vertex_shader) \ GPU_OP(INIT_TEXTURE_MAX_ANISOTROPY, \
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc index 04f66fa..a5686a9de6 100644 --- a/gpu/config/gpu_info_collector_win.cc +++ b/gpu/config/gpu_info_collector_win.cc
@@ -8,6 +8,7 @@ #include "third_party/re2/re2/re2.h" #include <windows.h> +#include <cfgmgr32.h> #include <d3d9.h> #include <d3d11.h> #include <dxgi.h> @@ -363,6 +364,24 @@ base::Bind(CollectD3D11SupportOnWorkerThread), false); } + +void DeviceIDToVendorAndDevice(const std::wstring& id, + uint32* vendor_id, + uint32* device_id) { + *vendor_id = 0; + *device_id = 0; + if (id.length() < 21) + return; + base::string16 vendor_id_string = id.substr(8, 4); + base::string16 device_id_string = id.substr(17, 4); + int vendor = 0; + int device = 0; + base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor); + base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device); + *vendor_id = vendor; + *device_id = device; +} + } // namespace anonymous #if defined(GOOGLE_CHROME_BUILD) && defined(OFFICIAL_BUILD) @@ -380,17 +399,35 @@ GPUInfo* gpu_info) { TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); + // Display adapter class GUID from + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx + GUID display_class = {0x4d36e968, + 0xe325, + 0x11ce, + {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; + // create device info for the display device - HDEVINFO device_info = SetupDiGetClassDevsW( - NULL, device_id.c_str(), NULL, - DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); + HDEVINFO device_info = + SetupDiGetClassDevsW(&display_class, NULL, NULL, DIGCF_PRESENT); if (device_info == INVALID_HANDLE_VALUE) { LOG(ERROR) << "Creating device info failed"; return kCollectInfoNonFatalFailure; } + struct GPUDriver { + GPUInfo::GPUDevice device; + std::string driver_vendor; + std::string driver_version; + std::string driver_date; + }; + + std::vector<GPUDriver> drivers; + + int primary_device = -1; + bool found_amd = false; + bool found_intel = false; + DWORD index = 0; - bool found = false; SP_DEVINFO_DATA device_info_data; device_info_data.cbSize = sizeof(device_info_data); while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { @@ -429,35 +466,85 @@ result = RegQueryValueExW( key, L"ProviderName", NULL, NULL, reinterpret_cast<LPBYTE>(value), &dwcb_data); - if (result == ERROR_SUCCESS) { + if (result == ERROR_SUCCESS) driver_vendor = base::UTF16ToASCII(std::wstring(value)); - if (driver_vendor == "Advanced Micro Devices, Inc." || - driver_vendor == "ATI Technologies Inc.") { - // We are conservative and assume that in the absence of a clear - // signal the videocard is assumed to be switchable. Additionally, - // some switchable systems with Intel GPUs aren't correctly - // detected, so always count them. - GetAMDVideocardInfo(gpu_info); - if (!gpu_info->amd_switchable && - gpu_info->gpu.vendor_id == 0x8086) { - gpu_info->amd_switchable = true; - gpu_info->secondary_gpus.push_back(gpu_info->gpu); - gpu_info->gpu.vendor_id = 0x1002; - gpu_info->gpu.device_id = 0; // Unknown discrete AMD GPU. - } - } + + wchar_t new_device_id[MAX_DEVICE_ID_LEN]; + CONFIGRET status = CM_Get_Device_ID( + device_info_data.DevInst, new_device_id, MAX_DEVICE_ID_LEN, 0); + + if (status == CR_SUCCESS) { + GPUDriver driver; + + driver.driver_vendor = driver_vendor; + driver.driver_version = driver_version; + driver.driver_date = driver_date; + std::wstring id = new_device_id; + + if (id.compare(0, device_id.size(), device_id) == 0) + primary_device = drivers.size(); + + uint32 vendor_id = 0, device_id = 0; + DeviceIDToVendorAndDevice(id, &vendor_id, &device_id); + driver.device.vendor_id = vendor_id; + driver.device.device_id = device_id; + drivers.push_back(driver); + + if (vendor_id == 0x8086) + found_intel = true; + if (vendor_id == 0x1002) + found_amd = true; } - gpu_info->driver_vendor = driver_vendor; - gpu_info->driver_version = driver_version; - gpu_info->driver_date = driver_date; - found = true; RegCloseKey(key); - break; } } } SetupDiDestroyDeviceInfoList(device_info); + bool found = false; + if (found_amd && found_intel) { + // AMD Switchable system found. + for (const auto& driver : drivers) { + if (driver.device.vendor_id == 0x8086) { + gpu_info->gpu = driver.device; + } + + if (driver.device.vendor_id == 0x1002) { + gpu_info->driver_vendor = driver.driver_vendor; + gpu_info->driver_version = driver.driver_version; + gpu_info->driver_date = driver.driver_date; + } + } + GetAMDVideocardInfo(gpu_info); + + if (!gpu_info->amd_switchable) { + // Some machines aren't properly detected as AMD switchable, but count + // them anyway. + gpu_info->amd_switchable = true; + for (const auto& driver : drivers) { + if (driver.device.vendor_id == 0x1002) { + gpu_info->gpu = driver.device; + } else { + gpu_info->secondary_gpus.push_back(driver.device); + } + } + } + found = true; + } else { + for (size_t i = 0; i < drivers.size(); ++i) { + const GPUDriver& driver = drivers[i]; + if (static_cast<int>(i) == primary_device) { + found = true; + gpu_info->gpu = driver.device; + gpu_info->driver_vendor = driver.driver_vendor; + gpu_info->driver_version = driver.driver_version; + gpu_info->driver_date = driver.driver_date; + } else { + gpu_info->secondary_gpus.push_back(driver.device); + } + } + } + return found ? kCollectInfoSuccess : kCollectInfoNonFatalFailure; } @@ -551,13 +638,7 @@ } if (id.length() > 20) { - int vendor = 0, device = 0; - std::wstring vendor_string = id.substr(8, 4); - std::wstring device_string = id.substr(17, 4); - base::HexStringToInt(base::UTF16ToASCII(vendor_string), &vendor); - base::HexStringToInt(base::UTF16ToASCII(device_string), &device); - *vendor_id = vendor; - *device_id = device; + DeviceIDToVendorAndDevice(id, vendor_id, device_id); if (*vendor_id != 0 && *device_id != 0) return kCollectInfoSuccess; } @@ -609,13 +690,8 @@ return kCollectInfoNonFatalFailure; } - int vendor_id = 0, device_id = 0; - base::string16 vendor_id_string = id.substr(8, 4); - base::string16 device_id_string = id.substr(17, 4); - base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor_id); - base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device_id); - gpu_info->gpu.vendor_id = vendor_id; - gpu_info->gpu.device_id = device_id; + DeviceIDToVendorAndDevice(id, &gpu_info->gpu.vendor_id, + &gpu_info->gpu.device_id); // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. if (!CollectDriverInfoD3D(id, gpu_info)) { gpu_info->basic_info_state = kCollectInfoNonFatalFailure;
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc index b822056..93afd1a 100644 --- a/gpu/config/software_rendering_list_json.cc +++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@ { "name": "software rendering list", // Please update the version number whenever you change this file. - "version": "9.16", + "version": "9.17", "entries": [ { "id": 1, @@ -621,22 +621,6 @@ ] }, { - "id": 62, - "description": "Accelerated 2D canvas buggy on old Qualcomm Adreno", - "cr_bugs": [161575], - "os": { - "type": "android" - }, - "gl_renderer": ".*Adreno.*", - "driver_version": { - "op": "<", - "value": "4.1" - }, - "features": [ - "accelerated_2d_canvas" - ] - }, - { "id": 64, "description": "Hardware video decode is only supported in win7+", "cr_bugs": [159458], @@ -1035,7 +1019,7 @@ }, { "id": 96, - "description": "GPU rasterization whitelist", + "description": "Blacklist GPU raster/canvas on all except known good GPUs and newer Android releases", "cr_bugs": [362779,424970], "os": { "type": "android" @@ -1090,7 +1074,8 @@ } ], "features": [ - "gpu_rasterization" + "gpu_rasterization", + "accelerated_2d_canvas" ] }, { @@ -1110,11 +1095,15 @@ }, { "id": 100, - "description": "GPU rasterization is blacklisted on Nexus 10", + "description": "GPU rasterization and canvas is blacklisted on Nexus 10", "cr_bugs": [407144], + "os": { + "type": "android" + }, "gl_renderer": ".*Mali-T604.*", "features": [ - "gpu_rasterization" + "gpu_rasterization", + "accelerated_2d_canvas" ] }, {
diff --git a/gpu/ipc/gpu_command_buffer_traits_multi.h b/gpu/ipc/gpu_command_buffer_traits_multi.h index 8201f32..2f834a02 100644 --- a/gpu/ipc/gpu_command_buffer_traits_multi.h +++ b/gpu/ipc/gpu_command_buffer_traits_multi.h
@@ -42,6 +42,9 @@ IPC_STRUCT_TRAITS_MEMBER(num_compressed_texture_formats) IPC_STRUCT_TRAITS_MEMBER(num_shader_binary_formats) IPC_STRUCT_TRAITS_MEMBER(bind_generates_resource_chromium) + IPC_STRUCT_TRAITS_MEMBER(max_transform_feedback_separate_attribs) + IPC_STRUCT_TRAITS_MEMBER(max_uniform_buffer_bindings) + IPC_STRUCT_TRAITS_MEMBER(uniform_buffer_offset_alignment) IPC_STRUCT_TRAITS_MEMBER(post_sub_buffer) IPC_STRUCT_TRAITS_MEMBER(egl_image_external) IPC_STRUCT_TRAITS_MEMBER(texture_format_bgra8888)
diff --git a/ipc/ipc_channel_nacl.cc b/ipc/ipc_channel_nacl.cc index a88461c..53397f47 100644 --- a/ipc/ipc_channel_nacl.cc +++ b/ipc/ipc_channel_nacl.cc
@@ -200,6 +200,7 @@ } bool ChannelNacl::Send(Message* message) { + DCHECK(!message->HasAttachments()); DVLOG(2) << "sending message @" << message << " on channel @" << this << " with type " << message->type(); scoped_ptr<Message> message_ptr(message);
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index d853e4e..aac7e795 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc
@@ -556,6 +556,7 @@ } bool ChannelPosix::Send(Message* message) { + DCHECK(!message->HasMojoHandles()); DVLOG(2) << "sending message @" << message << " on channel @" << this << " with type " << message->type() << " (" << output_queue_.size() << " in queue)";
diff --git a/ipc/ipc_channel_win.cc b/ipc/ipc_channel_win.cc index 384c892..2704373 100644 --- a/ipc/ipc_channel_win.cc +++ b/ipc/ipc_channel_win.cc
@@ -78,6 +78,7 @@ } bool ChannelWin::Send(Message* message) { + DCHECK(!message->HasAttachments()); DCHECK(thread_check_->CalledOnValidThread()); DVLOG(2) << "sending message @" << message << " on channel @" << this << " with type " << message->type()
diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc index c5a5a83c..99c56efa 100644 --- a/ipc/ipc_message.cc +++ b/ipc/ipc_message.cc
@@ -155,4 +155,8 @@ return attachment_set_.get() && !attachment_set_->empty(); } +bool Message::HasMojoHandles() const { + return attachment_set_.get() && 0 < attachment_set_->num_mojo_handles(); +} + } // namespace IPC
diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h index e57008b..64d85d4d 100644 --- a/ipc/ipc_message.h +++ b/ipc/ipc_message.h
@@ -175,6 +175,8 @@ scoped_refptr<MessageAttachment>* attachment) const; // Returns true if there are any attachment in this message. bool HasAttachments() const; + // Returns true if there are any MojoHandleAttachments in this message. + bool HasMojoHandles() const; #ifdef IPC_MESSAGE_LOG_ENABLED // Adds the outgoing time from Time::Now() at the end of the message and sets
diff --git a/ipc/ipc_message_attachment.h b/ipc/ipc_message_attachment.h index 4ab6970..ba7f0e8 100644 --- a/ipc/ipc_message_attachment.h +++ b/ipc/ipc_message_attachment.h
@@ -18,12 +18,15 @@ : public base::RefCounted<MessageAttachment> { public: enum Type { - TYPE_PLATFORM_FILE, // The instance is |PlatformFileAttachment|. - TYPE_MOJO_MESSAGE_PIPE, // The instance is a mojo-based class. + TYPE_PLATFORM_FILE, // The instance is |PlatformFileAttachment|. + TYPE_MOJO_HANDLE, // The instance is |MojoHandleAttachment|. }; virtual Type GetType() const = 0; + +#if defined(OS_POSIX) virtual base::PlatformFile TakePlatformFile() = 0; +#endif // OS_POSIX protected: friend class base::RefCounted<MessageAttachment>;
diff --git a/ipc/ipc_message_attachment_set.cc b/ipc/ipc_message_attachment_set.cc index dd881c5..cb74a5a 100644 --- a/ipc/ipc_message_attachment_set.cc +++ b/ipc/ipc_message_attachment_set.cc
@@ -45,6 +45,13 @@ }); } +unsigned MessageAttachmentSet::num_mojo_handles() const { + return std::count_if(attachments_.begin(), attachments_.end(), + [](scoped_refptr<MessageAttachment> i) { + return i->GetType() == MessageAttachment::TYPE_MOJO_HANDLE; + }); +} + unsigned MessageAttachmentSet::size() const { return static_cast<unsigned>(attachments_.size()); } @@ -52,7 +59,7 @@ bool MessageAttachmentSet::AddAttachment( scoped_refptr<MessageAttachment> attachment) { #if defined(OS_POSIX) - if (attachment->GetType() != MessageAttachment::TYPE_PLATFORM_FILE || + if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE && num_descriptors() == kMaxDescriptorsPerMessage) { DLOG(WARNING) << "Cannot add file descriptor. MessageAttachmentSet full."; return false; @@ -102,6 +109,11 @@ return attachments_[index]; } +void MessageAttachmentSet::CommitAll() { + attachments_.clear(); + consumed_descriptor_highwater_ = 0; +} + #if defined(OS_POSIX) void MessageAttachmentSet::PeekDescriptors(base::PlatformFile* buffer) const { @@ -120,11 +132,6 @@ return false; } -void MessageAttachmentSet::CommitAll() { - attachments_.clear(); - consumed_descriptor_highwater_ = 0; -} - void MessageAttachmentSet::ReleaseFDsToClose( std::vector<base::PlatformFile>* fds) { for (size_t i = 0; i < attachments_.size(); ++i) {
diff --git a/ipc/ipc_message_attachment_set.h b/ipc/ipc_message_attachment_set.h index a216493..7e848bd 100644 --- a/ipc/ipc_message_attachment_set.h +++ b/ipc/ipc_message_attachment_set.h
@@ -35,6 +35,9 @@ unsigned size() const; // Return the number of file descriptors unsigned num_descriptors() const; + // Return the number of mojo handles in the attachment set + unsigned num_mojo_handles() const; + // Return true if no unconsumed descriptors remain bool empty() const { return 0 == size(); } @@ -48,6 +51,11 @@ // returns: an attachment, or nullptr on error scoped_refptr<MessageAttachment> GetAttachmentAt(unsigned index); + // This must be called after transmitting the descriptors returned by + // PeekDescriptors. It marks all the descriptors as consumed and closes those + // which are auto-close. + void CommitAll(); + #if defined(OS_POSIX) // This is the maximum number of descriptors per message. We need to know this // because the control message kernel interface has to be given a buffer which @@ -66,10 +74,6 @@ // must be called after these descriptors have been transmitted. // buffer: (output) a buffer of, at least, size() integers. void PeekDescriptors(base::PlatformFile* buffer) const; - // This must be called after transmitting the descriptors returned by - // PeekDescriptors. It marks all the descriptors as consumed and closes those - // which are auto-close. - void CommitAll(); // Returns true if any contained file descriptors appear to be handles to a // directory. bool ContainsDirectoryDescriptor() const;
diff --git a/ipc/ipc_perftest_support.cc b/ipc/ipc_perftest_support.cc index d0cbe5e..0a6a03e 100644 --- a/ipc/ipc_perftest_support.cc +++ b/ipc/ipc_perftest_support.cc
@@ -229,7 +229,7 @@ list.push_back(PingPongTestParams(144, 50000)); list.push_back(PingPongTestParams(1728, 50000)); list.push_back(PingPongTestParams(20736, 12000)); - list.push_back(PingPongTestParams(248832, 100)); + list.push_back(PingPongTestParams(248832, 1000)); return list; }
diff --git a/ipc/mojo/BUILD.gn b/ipc/mojo/BUILD.gn index 2c169a91..051937c2 100644 --- a/ipc/mojo/BUILD.gn +++ b/ipc/mojo/BUILD.gn
@@ -22,6 +22,10 @@ "ipc_channel_mojo_host.h", "ipc_mojo_bootstrap.cc", "ipc_mojo_bootstrap.h", + "ipc_mojo_handle_attachment.cc", + "ipc_mojo_handle_attachment.h", + "ipc_mojo_message_helper.cc", + "ipc_mojo_message_helper.h", "ipc_message_pipe_reader.cc", "ipc_message_pipe_reader.h", ]
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc index d2d7fe5..c3c6e0c 100644 --- a/ipc/mojo/ipc_channel_mojo.cc +++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -13,6 +13,7 @@ #include "ipc/ipc_message_macros.h" #include "ipc/mojo/client_channel.mojom.h" #include "ipc/mojo/ipc_mojo_bootstrap.h" +#include "ipc/mojo/ipc_mojo_handle_attachment.h" #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" @@ -341,29 +342,7 @@ base::ScopedFD ChannelMojo::TakeClientFileDescriptor() { return bootstrap_->TakeClientFileDescriptor(); } - -// static -MojoResult ChannelMojo::WriteToMessageAttachmentSet( - const std::vector<MojoHandle>& handle_buffer, - Message* message) { - for (size_t i = 0; i < handle_buffer.size(); ++i) { - mojo::embedder::ScopedPlatformHandle platform_handle; - MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( - handle_buffer[i], &platform_handle); - if (unwrap_result != MOJO_RESULT_OK) { - DLOG(WARNING) << "Pipe failed to covert handles. Closing: " - << unwrap_result; - return unwrap_result; - } - - bool ok = message->attachment_set()->AddAttachment( - new internal::PlatformFileAttachment( - base::ScopedFD(platform_handle.release().fd))); - DCHECK(ok); - } - - return MOJO_RESULT_OK; -} +#endif // defined(OS_POSIX) && !defined(OS_NACL) // static MojoResult ChannelMojo::ReadFromMessageAttachmentSet( @@ -373,38 +352,71 @@ // IPC::MessageAttachmentSet has intricate lifecycle semantics // of FDs, so just to dup()-and-own them is the safest option. if (message->HasAttachments()) { - MessageAttachmentSet* fdset = message->attachment_set(); - std::vector<base::PlatformFile> fds_to_send(fdset->size()); - fdset->PeekDescriptors(&fds_to_send[0]); - for (size_t i = 0; i < fds_to_send.size(); ++i) { - int fd_to_send = dup(fds_to_send[i]); - if (-1 == fd_to_send) { - DPLOG(WARNING) << "Failed to dup FD to transmit."; - fdset->CommitAll(); - return MOJO_RESULT_UNKNOWN; - } + MessageAttachmentSet* set = message->attachment_set(); + for (unsigned i = 0; i < set->size(); ++i) { + scoped_refptr<MessageAttachment> attachment = set->GetAttachmentAt(i); + switch (attachment->GetType()) { + case MessageAttachment::TYPE_PLATFORM_FILE: +#if defined(OS_POSIX) && !defined(OS_NACL) + { + base::PlatformFile file = + dup(static_cast<IPC::internal::PlatformFileAttachment*>( + attachment.get())->file()); + if (file == -1) { + DPLOG(WARNING) << "Failed to dup FD to transmit."; + set->CommitAll(); + return MOJO_RESULT_UNKNOWN; + } - MojoHandle wrapped_handle; - MojoResult wrap_result = CreatePlatformHandleWrapper( - mojo::embedder::ScopedPlatformHandle( - mojo::embedder::PlatformHandle(fd_to_send)), - &wrapped_handle); - if (MOJO_RESULT_OK != wrap_result) { - DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " - << wrap_result; - fdset->CommitAll(); - return wrap_result; - } + MojoHandle wrapped_handle; + MojoResult wrap_result = CreatePlatformHandleWrapper( + mojo::embedder::ScopedPlatformHandle( + mojo::embedder::PlatformHandle(file)), + &wrapped_handle); + if (MOJO_RESULT_OK != wrap_result) { + DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " + << wrap_result; + set->CommitAll(); + return wrap_result; + } - handles->push_back(wrapped_handle); + handles->push_back(wrapped_handle); + } +#else + NOTREACHED(); +#endif // defined(OS_POSIX) && !defined(OS_NACL) + break; + case MessageAttachment::TYPE_MOJO_HANDLE: { + mojo::ScopedHandle handle = + static_cast<IPC::internal::MojoHandleAttachment*>( + attachment.get())->TakeHandle(); + handles->push_back(handle.release().value()); + } break; + } } - fdset->CommitAll(); + set->CommitAll(); } return MOJO_RESULT_OK; } -#endif // defined(OS_POSIX) && !defined(OS_NACL) +// static +MojoResult ChannelMojo::WriteToMessageAttachmentSet( + const std::vector<MojoHandle>& handle_buffer, + Message* message) { + for (size_t i = 0; i < handle_buffer.size(); ++i) { + bool ok = message->attachment_set()->AddAttachment( + new IPC::internal::MojoHandleAttachment( + mojo::MakeScopedHandle(mojo::Handle(handle_buffer[i])))); + DCHECK(ok); + if (!ok) { + DLOG(ERROR) << "Failed to add new Mojo handle."; + return MOJO_RESULT_UNKNOWN; + } + } + + return MOJO_RESULT_OK; +} } // namespace IPC
diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h index 5062577..71d1d10 100644 --- a/ipc/mojo/ipc_channel_mojo.h +++ b/ipc/mojo/ipc_channel_mojo.h
@@ -92,6 +92,7 @@ #if defined(OS_POSIX) && !defined(OS_NACL) int GetClientFileDescriptor() const override; base::ScopedFD TakeClientFileDescriptor() override; +#endif // defined(OS_POSIX) && !defined(OS_NACL) // These access protected API of IPC::Message, which has ChannelMojo // as a friend class. @@ -102,8 +103,6 @@ Message* message, std::vector<MojoHandle>* handles); -#endif // defined(OS_POSIX) && !defined(OS_NACL) - // MojoBootstrapDelegate implementation void OnBootstrapError() override;
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc index 6ebaa73..556e65a 100644 --- a/ipc/mojo/ipc_channel_mojo_unittest.cc +++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -14,6 +14,8 @@ #include "ipc/ipc_test_base.h" #include "ipc/ipc_test_channel_listener.h" #include "ipc/mojo/ipc_channel_mojo_host.h" +#include "ipc/mojo/ipc_mojo_handle_attachment.h" +#include "ipc/mojo/ipc_mojo_message_helper.h" #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" @@ -257,6 +259,147 @@ DestroyChannel(); } +struct TestingMessagePipe { + TestingMessagePipe() { + EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer)); + } + + mojo::ScopedMessagePipeHandle self; + mojo::ScopedMessagePipeHandle peer; +}; + +class HandleSendingHelper { + public: + static std::string GetSendingFileContent() { return "Hello"; } + + static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) { + std::string content = HandleSendingHelper::GetSendingFileContent(); + EXPECT_EQ(MOJO_RESULT_OK, + mojo::WriteMessageRaw(pipe->self.get(), &content[0], + static_cast<uint32_t>(content.size()), + nullptr, 0, 0)); + EXPECT_TRUE( + IPC::MojoMessageHelper::WriteMessagePipeTo(message, pipe->peer.Pass())); + } + + static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) { + IPC::Message* message = + new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); + WritePipe(message, pipe); + ASSERT_TRUE(sender->Send(message)); + } + + static void ReadReceivedPipe(const IPC::Message& message, + PickleIterator* iter) { + mojo::ScopedMessagePipeHandle pipe; + EXPECT_TRUE( + IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe)); + std::string content(GetSendingFileContent().size(), ' '); + + uint32_t num_bytes = static_cast<uint32_t>(content.size()); + EXPECT_EQ(MOJO_RESULT_OK, + mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr, + nullptr, 0)); + EXPECT_EQ(content, GetSendingFileContent()); + } + +#if defined(OS_POSIX) + static base::FilePath GetSendingFilePath() { + base::FilePath path; + bool ok = PathService::Get(base::DIR_CACHE, &path); + EXPECT_TRUE(ok); + return path.Append("ListenerThatExpectsFile.txt"); + } + + static void WriteFile(IPC::Message* message, base::File& file) { + std::string content = GetSendingFileContent(); + file.WriteAtCurrentPos(content.data(), content.size()); + file.Flush(); + message->WriteAttachment(new IPC::internal::PlatformFileAttachment( + base::ScopedFD(file.TakePlatformFile()))); + } + + static void WriteFileThenSend(IPC::Sender* sender, base::File& file) { + IPC::Message* message = + new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); + WriteFile(message, file); + ASSERT_TRUE(sender->Send(message)); + } + + static void WriteFileAndPipeThenSend(IPC::Sender* sender, + base::File& file, + TestingMessagePipe* pipe) { + IPC::Message* message = + new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); + WriteFile(message, file); + WritePipe(message, pipe); + ASSERT_TRUE(sender->Send(message)); + } + + static void ReadReceivedFile(const IPC::Message& message, + PickleIterator* iter) { + base::ScopedFD fd; + scoped_refptr<IPC::MessageAttachment> attachment; + EXPECT_TRUE(message.ReadAttachment(iter, &attachment)); + base::File file(attachment->TakePlatformFile()); + std::string content(GetSendingFileContent().size(), ' '); + file.Read(0, &content[0], content.size()); + EXPECT_EQ(content, GetSendingFileContent()); + } +#endif +}; + +class ListenerThatExpectsMessagePipe : public IPC::Listener { + public: + ListenerThatExpectsMessagePipe() : sender_(NULL) {} + + ~ListenerThatExpectsMessagePipe() override {} + + bool OnMessageReceived(const IPC::Message& message) override { + PickleIterator iter(message); + HandleSendingHelper::ReadReceivedPipe(message, &iter); + base::MessageLoop::current()->Quit(); + ListenerThatExpectsOK::SendOK(sender_); + return true; + } + + void OnChannelError() override { NOTREACHED(); } + + void set_sender(IPC::Sender* sender) { sender_ = sender; } + + private: + IPC::Sender* sender_; +}; + +TEST_F(IPCChannelMojoTest, SendMessagePipe) { + Init("IPCChannelMojoTestSendMessagePipeClient"); + + ListenerThatExpectsOK listener; + CreateChannel(&listener); + ASSERT_TRUE(ConnectChannel()); + ASSERT_TRUE(StartClient()); + + TestingMessagePipe pipe; + HandleSendingHelper::WritePipeThenSend(channel(), &pipe); + + base::MessageLoop::current()->Run(); + this->channel()->Close(); + + EXPECT_TRUE(WaitForClientShutdown()); + DestroyChannel(); +} + +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) { + ListenerThatExpectsMessagePipe listener; + ChannelClient client(&listener, "IPCChannelMojoTestSendPlatformHandleClient"); + client.Connect(); + listener.set_sender(client.channel()); + + base::MessageLoop::current()->Run(); + + return 0; +} + #if defined(OS_WIN) class IPCChannelMojoDeadHandleTest : public IPCTestBase { protected: @@ -327,14 +470,7 @@ bool OnMessageReceived(const IPC::Message& message) override { PickleIterator iter(message); - - base::ScopedFD fd; - scoped_refptr<IPC::MessageAttachment> attachment; - EXPECT_TRUE(message.ReadAttachment(&iter, &attachment)); - base::File file(attachment->TakePlatformFile()); - std::string content(GetSendingFileContent().size(), ' '); - file.Read(0, &content[0], content.size()); - EXPECT_EQ(content, GetSendingFileContent()); + HandleSendingHelper::ReadReceivedFile(message, &iter); base::MessageLoop::current()->Quit(); ListenerThatExpectsOK::SendOK(sender_); return true; @@ -344,28 +480,6 @@ NOTREACHED(); } - static std::string GetSendingFileContent() { - return "Hello"; - } - - static base::FilePath GetSendingFilePath() { - base::FilePath path; - bool ok = PathService::Get(base::DIR_CACHE, &path); - EXPECT_TRUE(ok); - return path.Append("ListenerThatExpectsFile.txt"); - } - - static void WriteAndSendFile(IPC::Sender* sender, base::File& file) { - std::string content = GetSendingFileContent(); - file.WriteAtCurrentPos(content.data(), content.size()); - file.Flush(); - IPC::Message* message = new IPC::Message( - 0, 2, IPC::Message::PRIORITY_NORMAL); - message->WriteAttachment(new IPC::internal::PlatformFileAttachment( - base::ScopedFD(file.TakePlatformFile()))); - ASSERT_TRUE(sender->Send(message)); - } - void set_sender(IPC::Sender* sender) { sender_ = sender; } private: @@ -381,10 +495,10 @@ ASSERT_TRUE(ConnectChannel()); ASSERT_TRUE(StartClient()); - base::File file(ListenerThatExpectsFile::GetSendingFilePath(), + base::File file(HandleSendingHelper::GetSendingFilePath(), base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | - base::File::FLAG_READ); - ListenerThatExpectsFile::WriteAndSendFile(channel(), file); + base::File::FLAG_READ); + HandleSendingHelper::WriteFileThenSend(channel(), file); base::MessageLoop::current()->Run(); this->channel()->Close(); @@ -404,6 +518,64 @@ return 0; } + +class ListenerThatExpectsFileAndPipe : public IPC::Listener { + public: + ListenerThatExpectsFileAndPipe() : sender_(NULL) {} + + ~ListenerThatExpectsFileAndPipe() override {} + + bool OnMessageReceived(const IPC::Message& message) override { + PickleIterator iter(message); + HandleSendingHelper::ReadReceivedFile(message, &iter); + HandleSendingHelper::ReadReceivedPipe(message, &iter); + base::MessageLoop::current()->Quit(); + ListenerThatExpectsOK::SendOK(sender_); + return true; + } + + void OnChannelError() override { NOTREACHED(); } + + void set_sender(IPC::Sender* sender) { sender_ = sender; } + + private: + IPC::Sender* sender_; +}; + +TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) { + Init("IPCChannelMojoTestSendPlatformHandleAndPipeClient"); + + ListenerThatExpectsOK listener; + CreateChannel(&listener); + ASSERT_TRUE(ConnectChannel()); + ASSERT_TRUE(StartClient()); + + base::File file(HandleSendingHelper::GetSendingFilePath(), + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | + base::File::FLAG_READ); + TestingMessagePipe pipe; + HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe); + + base::MessageLoop::current()->Run(); + this->channel()->Close(); + + EXPECT_TRUE(WaitForClientShutdown()); + DestroyChannel(); +} + +MULTIPROCESS_IPC_TEST_CLIENT_MAIN( + IPCChannelMojoTestSendPlatformHandleAndPipeClient) { + ListenerThatExpectsFileAndPipe listener; + ChannelClient client(&listener, + "IPCChannelMojoTestSendPlatformHandleAndPipeClient"); + client.Connect(); + listener.set_sender(client.channel()); + + base::MessageLoop::current()->Run(); + + return 0; +} + #endif } // namespace
diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp index 505f536..0f746fc8 100644 --- a/ipc/mojo/ipc_mojo.gyp +++ b/ipc/mojo/ipc_mojo.gyp
@@ -36,6 +36,10 @@ 'ipc_channel_mojo_host.h', 'ipc_mojo_bootstrap.cc', 'ipc_mojo_bootstrap.h', + 'ipc_mojo_handle_attachment.cc', + 'ipc_mojo_handle_attachment.h', + 'ipc_mojo_message_helper.cc', + 'ipc_mojo_message_helper.h', 'ipc_message_pipe_reader.cc', 'ipc_message_pipe_reader.h', ],
diff --git a/ipc/mojo/ipc_mojo_handle_attachment.cc b/ipc/mojo/ipc_mojo_handle_attachment.cc new file mode 100644 index 0000000..46acd02 --- /dev/null +++ b/ipc/mojo/ipc_mojo_handle_attachment.cc
@@ -0,0 +1,43 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ipc/mojo/ipc_mojo_handle_attachment.h" + +#include "ipc/ipc_message_attachment_set.h" +#include "third_party/mojo/src/mojo/edk/embedder/embedder.h" + +namespace IPC { +namespace internal { + +MojoHandleAttachment::MojoHandleAttachment(mojo::ScopedHandle handle) + : handle_(handle.Pass()) { +} + +MojoHandleAttachment::~MojoHandleAttachment() { +} + +MessageAttachment::Type MojoHandleAttachment::GetType() const { + return TYPE_MOJO_HANDLE; +} + +#if defined(OS_POSIX) +base::PlatformFile MojoHandleAttachment::TakePlatformFile() { + mojo::embedder::ScopedPlatformHandle platform_handle; + MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( + handle_.release().value(), &platform_handle); + if (unwrap_result != MOJO_RESULT_OK) { + DLOG(ERROR) << "Pipe failed to covert handles. Closing: " << unwrap_result; + return -1; + } + + return platform_handle.release().fd; +} +#endif // OS_POSIX + +mojo::ScopedHandle MojoHandleAttachment::TakeHandle() { + return handle_.Pass(); +} + +} // namespace internal +} // namespace IPC
diff --git a/ipc/mojo/ipc_mojo_handle_attachment.h b/ipc/mojo/ipc_mojo_handle_attachment.h new file mode 100644 index 0000000..ef5a318 --- /dev/null +++ b/ipc/mojo/ipc_mojo_handle_attachment.h
@@ -0,0 +1,50 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_MOJO_IPC_MOJO_HANDLE_ATTACHMENT_H_ +#define IPC_MOJO_IPC_MOJO_HANDLE_ATTACHMENT_H_ + +#include "base/files/file.h" +#include "ipc/ipc_export.h" +#include "ipc/ipc_message_attachment.h" +#include "third_party/mojo/src/mojo/public/cpp/system/handle.h" + +namespace IPC { + +namespace internal { + +// A MessageAttachment that holds a MojoHandle. +// * On the sending side, every Mojo handle is a MessagePipe. This is because +// any platform files are wrapped by PlatformFileAttachment. +// * On the receiving side, the handle can be either MessagePipe or wrapped +// platform file: All files, not only MessagePipes are wrapped as a +// MojoHandle. The message deserializer should know which type of the object +// the handle wraps. +class IPC_MOJO_EXPORT MojoHandleAttachment : public MessageAttachment { + public: + explicit MojoHandleAttachment(mojo::ScopedHandle handle); + + Type GetType() const override; + +#if defined(OS_POSIX) + // Returns wrapped file if it wraps a file, or + // an invalid fd otherwise. The ownership of handle + // is passed to the caller. + base::PlatformFile TakePlatformFile() override; +#endif // OS_POSIX + + // Returns the owning handle transferring the ownership. + mojo::ScopedHandle TakeHandle(); + + private: + ~MojoHandleAttachment() override; + mojo::ScopedHandle handle_; + + DISALLOW_COPY_AND_ASSIGN(MojoHandleAttachment); +}; + +} // namespace internal +} // namespace IPC + +#endif // IPC_MOJO_IPC_MOJO_HANDLE_ATTACHMENT_H_
diff --git a/ipc/mojo/ipc_mojo_message_helper.cc b/ipc/mojo/ipc_mojo_message_helper.cc new file mode 100644 index 0000000..c6f6dbfa5 --- /dev/null +++ b/ipc/mojo/ipc_mojo_message_helper.cc
@@ -0,0 +1,47 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ipc/mojo/ipc_mojo_message_helper.h" + +#include "ipc/mojo/ipc_mojo_handle_attachment.h" + +namespace IPC { + +// static +bool MojoMessageHelper::WriteMessagePipeTo( + Message* message, + mojo::ScopedMessagePipeHandle handle) { + message->WriteAttachment(new internal::MojoHandleAttachment( + mojo::ScopedHandle::From(handle.Pass()))); + return true; +} + +// static +bool MojoMessageHelper::ReadMessagePipeFrom( + const Message* message, + PickleIterator* iter, + mojo::ScopedMessagePipeHandle* handle) { + scoped_refptr<MessageAttachment> attachment; + if (!message->ReadAttachment(iter, &attachment)) { + DLOG(ERROR) << "Failed to read attachment for message pipe."; + return false; + } + + if (attachment->GetType() != MessageAttachment::TYPE_MOJO_HANDLE) { + DLOG(ERROR) << "Unxpected attachment type:" << attachment->GetType(); + return false; + } + + handle->reset(mojo::MessagePipeHandle( + static_cast<internal::MojoHandleAttachment*>(attachment.get()) + ->TakeHandle() + .release() + .value())); + return true; +} + +MojoMessageHelper::MojoMessageHelper() { +} + +} // namespace IPC
diff --git a/ipc/mojo/ipc_mojo_message_helper.h b/ipc/mojo/ipc_mojo_message_helper.h new file mode 100644 index 0000000..efb48c3 --- /dev/null +++ b/ipc/mojo/ipc_mojo_message_helper.h
@@ -0,0 +1,29 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_MOJO_IPC_MOJO_MESSAGE_HELPER_H_ +#define IPC_MOJO_IPC_MOJO_MESSAGE_HELPER_H_ + +#include "ipc/ipc_export.h" +#include "ipc/ipc_message.h" +#include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h" + +namespace IPC { + +// Reads and writes |mojo::MessagePipe| from/to |Message|. +class IPC_MOJO_EXPORT MojoMessageHelper { + public: + static bool WriteMessagePipeTo(Message* message, + mojo::ScopedMessagePipeHandle handle); + static bool ReadMessagePipeFrom(const Message* message, + PickleIterator* iter, + mojo::ScopedMessagePipeHandle* handle); + + private: + MojoMessageHelper(); +}; + +} // namespace IPC + +#endif // IPC_MOJO_IPC_MOJO_MESSAGE_HELPER_H_
diff --git a/jingle/glue/proxy_resolving_client_socket.cc b/jingle/glue/proxy_resolving_client_socket.cc index 0b35559d..916f4178 100644 --- a/jingle/glue/proxy_resolving_client_socket.cc +++ b/jingle/glue/proxy_resolving_client_socket.cc
@@ -9,6 +9,7 @@ #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/profiler/scoped_tracker.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -214,6 +215,10 @@ } void ProxyResolvingClientSocket::ProcessConnectDone(int status) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455884 ProxyResolvingClientSocket::ProcessConnectDone")); if (status != net::OK) { // If the connection fails, try another proxy. status = ReconsiderProxyAfterError(status);
diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc index 1da84ca..f182fa64 100644 --- a/media/audio/android/audio_android_unittest.cc +++ b/media/audio/android/audio_android_unittest.cc
@@ -172,14 +172,13 @@ DVLOG(0) << "Reading from file: " << file_path.value().c_str(); } - virtual ~FileAudioSource() {} + ~FileAudioSource() override {} // AudioOutputStream::AudioSourceCallback implementation. // Use samples read from a data file and fill up the audio buffer // provided to us in the callback. - virtual int OnMoreData(AudioBus* audio_bus, - uint32 total_bytes_delay) override { + int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override { bool stop_playing = false; int max_size = audio_bus->frames() * audio_bus->channels() * kBytesPerSample; @@ -207,7 +206,7 @@ return frames; } - virtual void OnError(AudioOutputStream* stream) override {} + void OnError(AudioOutputStream* stream) override {} int file_size() { return file_->data_size(); } @@ -243,7 +242,7 @@ DVLOG(0) << "Writing to file: " << file_path.value().c_str(); } - virtual ~FileAudioSink() { + ~FileAudioSink() override { int bytes_written = 0; while (bytes_written < buffer_->forward_capacity()) { const uint8* chunk; @@ -263,10 +262,10 @@ } // AudioInputStream::AudioInputCallback implementation. - virtual void OnData(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume) override { + void OnData(AudioInputStream* stream, + const AudioBus* src, + uint32 hardware_delay_bytes, + double volume) override { const int num_samples = src->frames() * src->channels(); scoped_ptr<int16> interleaved(new int16[num_samples]); const int bytes_per_sample = sizeof(*interleaved); @@ -280,7 +279,7 @@ event_->Signal(); } - virtual void OnError(AudioInputStream* stream) override {} + void OnError(AudioInputStream* stream) override {} private: base::WaitableEvent* event_; @@ -308,13 +307,13 @@ buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); } - virtual ~FullDuplexAudioSinkSource() {} + ~FullDuplexAudioSinkSource() override {} // AudioInputStream::AudioInputCallback implementation - virtual void OnData(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume) override { + void OnData(AudioInputStream* stream, + const AudioBus* src, + uint32 hardware_delay_bytes, + double volume) override { const base::TimeTicks now_time = base::TimeTicks::Now(); const int diff = (now_time - previous_time_).InMilliseconds(); @@ -351,11 +350,10 @@ } } - virtual void OnError(AudioInputStream* stream) override {} + void OnError(AudioInputStream* stream) override {} // AudioOutputStream::AudioSourceCallback implementation - virtual int OnMoreData(AudioBus* dest, - uint32 total_bytes_delay) override { + int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override { const int size_in_bytes = (params_.bits_per_sample() / 8) * dest->frames() * dest->channels(); EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer()); @@ -383,7 +381,7 @@ return dest->frames(); } - virtual void OnError(AudioOutputStream* stream) override {} + void OnError(AudioOutputStream* stream) override {} private: // Converts from bytes to milliseconds given number of bytes and existing @@ -414,8 +412,7 @@ audio_output_stream_(NULL) { } - virtual ~AudioAndroidOutputTest() { - } + ~AudioAndroidOutputTest() override {} protected: AudioManager* audio_manager() { return audio_manager_.get(); }
diff --git a/media/audio/android/audio_manager_android.h b/media/audio/android/audio_manager_android.h index d1a8c8b..496b8cb 100644 --- a/media/audio/android/audio_manager_android.h +++ b/media/audio/android/audio_manager_android.h
@@ -23,34 +23,31 @@ AudioManagerAndroid(AudioLogFactory* audio_log_factory); // Implementation of AudioManager. - virtual bool HasAudioOutputDevices() override; - virtual bool HasAudioInputDevices() override; - virtual void GetAudioInputDeviceNames( - AudioDeviceNames* device_names) override; - virtual void GetAudioOutputDeviceNames( - AudioDeviceNames* device_names) override; - virtual AudioParameters GetInputStreamParameters( + bool HasAudioOutputDevices() override; + bool HasAudioInputDevices() override; + void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override; + void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override; + AudioParameters GetInputStreamParameters( const std::string& device_id) override; - virtual AudioOutputStream* MakeAudioOutputStream( + AudioOutputStream* MakeAudioOutputStream( const AudioParameters& params, const std::string& device_id) override; - virtual AudioInputStream* MakeAudioInputStream( - const AudioParameters& params, - const std::string& device_id) override; - virtual void ReleaseOutputStream(AudioOutputStream* stream) override; - virtual void ReleaseInputStream(AudioInputStream* stream) override; + AudioInputStream* MakeAudioInputStream(const AudioParameters& params, + const std::string& device_id) override; + void ReleaseOutputStream(AudioOutputStream* stream) override; + void ReleaseInputStream(AudioInputStream* stream) override; // Implementation of AudioManagerBase. - virtual AudioOutputStream* MakeLinearOutputStream( + AudioOutputStream* MakeLinearOutputStream( const AudioParameters& params) override; - virtual AudioOutputStream* MakeLowLatencyOutputStream( + AudioOutputStream* MakeLowLatencyOutputStream( const AudioParameters& params, const std::string& device_id) override; - virtual AudioInputStream* MakeLinearInputStream( + AudioInputStream* MakeLinearInputStream( const AudioParameters& params, const std::string& device_id) override; - virtual AudioInputStream* MakeLowLatencyInputStream( + AudioInputStream* MakeLowLatencyInputStream( const AudioParameters& params, const std::string& device_id) override; @@ -59,9 +56,9 @@ void SetMute(JNIEnv* env, jobject obj, jboolean muted); protected: - virtual ~AudioManagerAndroid(); + ~AudioManagerAndroid() override; - virtual AudioParameters GetPreferredOutputStreamParameters( + AudioParameters GetPreferredOutputStreamParameters( const std::string& output_device_id, const AudioParameters& input_params) override;
diff --git a/media/audio/android/audio_record_input.h b/media/audio/android/audio_record_input.h index f3ef519..1a35fdd4 100644 --- a/media/audio/android/audio_record_input.h +++ b/media/audio/android/audio_record_input.h
@@ -28,19 +28,19 @@ AudioRecordInputStream(AudioManagerAndroid* manager, const AudioParameters& params); - virtual ~AudioRecordInputStream(); + ~AudioRecordInputStream() override; // Implementation of AudioInputStream. - virtual bool Open() override; - virtual void Start(AudioInputCallback* callback) override; - virtual void Stop() override; - virtual void Close() override; - virtual double GetMaxVolume() override; - virtual void SetVolume(double volume) override; - virtual double GetVolume() override; - virtual bool SetAutomaticGainControl(bool enabled) override; - virtual bool GetAutomaticGainControl() override; - virtual bool IsMuted() override; + bool Open() override; + void Start(AudioInputCallback* callback) override; + void Stop() override; + void Close() override; + double GetMaxVolume() override; + void SetVolume(double volume) override; + double GetVolume() override; + bool SetAutomaticGainControl(bool enabled) override; + bool GetAutomaticGainControl() override; + bool IsMuted() override; static bool RegisterAudioRecordInput(JNIEnv* env);
diff --git a/media/audio/android/opensles_input.h b/media/audio/android/opensles_input.h index ff945353..e4ec082 100644 --- a/media/audio/android/opensles_input.h +++ b/media/audio/android/opensles_input.h
@@ -31,19 +31,19 @@ OpenSLESInputStream(AudioManagerAndroid* manager, const AudioParameters& params); - virtual ~OpenSLESInputStream(); + ~OpenSLESInputStream() override; // Implementation of AudioInputStream. - virtual bool Open() override; - virtual void Start(AudioInputCallback* callback) override; - virtual void Stop() override; - virtual void Close() override; - virtual double GetMaxVolume() override; - virtual void SetVolume(double volume) override; - virtual double GetVolume() override; - virtual bool SetAutomaticGainControl(bool enabled) override; - virtual bool GetAutomaticGainControl() override; - virtual bool IsMuted() override; + bool Open() override; + void Start(AudioInputCallback* callback) override; + void Stop() override; + void Close() override; + double GetMaxVolume() override; + void SetVolume(double volume) override; + double GetVolume() override; + bool SetAutomaticGainControl(bool enabled) override; + bool GetAutomaticGainControl() override; + bool IsMuted() override; private: bool CreateRecorder();
diff --git a/media/audio/android/opensles_output.h b/media/audio/android/opensles_output.h index 914fa6e6..0fef1bd 100644 --- a/media/audio/android/opensles_output.h +++ b/media/audio/android/opensles_output.h
@@ -31,15 +31,15 @@ const AudioParameters& params, SLint32 stream_type); - virtual ~OpenSLESOutputStream(); + ~OpenSLESOutputStream() override; // Implementation of AudioOutputStream. - virtual bool Open() override; - virtual void Close() override; - virtual void Start(AudioSourceCallback* callback) override; - virtual void Stop() override; - virtual void SetVolume(double volume) override; - virtual void GetVolume(double* volume) override; + bool Open() override; + void Close() override; + void Start(AudioSourceCallback* callback) override; + void Stop() override; + void SetVolume(double volume) override; + void GetVolume(double* volume) override; // Set the value of |muted_|. It does not affect |volume_| which can be // got by calling GetVolume(). See comments for |muted_| below.
diff --git a/media/audio/audio_output_dispatcher_impl.cc b/media/audio/audio_output_dispatcher_impl.cc index 0cb3db8..521f91d 100644 --- a/media/audio/audio_output_dispatcher_impl.cc +++ b/media/audio/audio_output_dispatcher_impl.cc
@@ -130,6 +130,10 @@ DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference"; } +bool AudioOutputDispatcherImpl::HasOutputProxies() const { + return idle_proxies_ || !proxy_to_physical_map_.empty(); +} + bool AudioOutputDispatcherImpl::CreateAndOpenStream() { DCHECK(task_runner_->BelongsToCurrentThread()); AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(
diff --git a/media/audio/audio_output_dispatcher_impl.h b/media/audio/audio_output_dispatcher_impl.h index 1aa5a32d..d271784 100644 --- a/media/audio/audio_output_dispatcher_impl.h +++ b/media/audio/audio_output_dispatcher_impl.h
@@ -60,6 +60,9 @@ void Shutdown() override; + // Returns true if there are any open AudioOutputProxy objects. + bool HasOutputProxies() const; + private: friend class base::RefCountedThreadSafe<AudioOutputDispatcherImpl>; ~AudioOutputDispatcherImpl() override;
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc index 66f8987..b0750cc 100644 --- a/media/audio/audio_output_proxy_unittest.cc +++ b/media/audio/audio_output_proxy_unittest.cc
@@ -674,4 +674,57 @@ EXPECT_TRUE(stream2.start_called()); } +// Simulate failures to open both the low latency and the fallback high latency +// stream and ensure AudioOutputResampler falls back to a fake stream. Ensure +// that after the close delay elapses, opening another stream succeeds with a +// non-fake stream. +TEST_F(AudioOutputResamplerTest, FallbackRecovery) { + MockAudioOutputStream fake_stream(&manager_, params_); + + // Trigger the fallback mechanism until a fake output stream is created. +#if defined(OS_WIN) + static const int kFallbackCount = 2; +#else + static const int kFallbackCount = 1; +#endif + EXPECT_CALL(manager(), MakeAudioOutputStream(_, _)) + .Times(kFallbackCount) + .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); + EXPECT_CALL(manager(), + MakeAudioOutputStream( + AllOf(testing::Property(&AudioParameters::format, + AudioParameters::AUDIO_FAKE), + testing::Property(&AudioParameters::sample_rate, + params_.sample_rate()), + testing::Property(&AudioParameters::frames_per_buffer, + params_.frames_per_buffer())), + _)).WillOnce(Return(&fake_stream)); + EXPECT_CALL(fake_stream, Open()).WillOnce(Return(true)); + AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); + EXPECT_TRUE(proxy->Open()); + CloseAndWaitForCloseTimer(proxy, &fake_stream); + + // Once all proxies have been closed, AudioOutputResampler will start the + // reinitialization timer and execute it after the close delay elapses. + base::RunLoop run_loop; + message_loop_.PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(2 * kTestCloseDelayMs)); + run_loop.Run(); + + // Verify a non-fake stream can be created. + MockAudioOutputStream real_stream(&manager_, params_); + EXPECT_CALL(manager(), + MakeAudioOutputStream( + testing::Property(&AudioParameters::format, + testing::Ne(AudioParameters::AUDIO_FAKE)), + _)).WillOnce(Return(&real_stream)); + + // Stream1 should be able to successfully open and start. + EXPECT_CALL(real_stream, Open()).WillOnce(Return(true)); + proxy = new AudioOutputProxy(resampler_.get()); + EXPECT_TRUE(proxy->Open()); + CloseAndWaitForCloseTimer(proxy, &real_stream); +} + } // namespace media
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 7aa3284..f053444 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc
@@ -11,6 +11,7 @@ #include "base/numerics/safe_conversions.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "media/audio/audio_io.h" #include "media/audio/audio_output_dispatcher_impl.h" @@ -153,7 +154,13 @@ : AudioOutputDispatcher(audio_manager, input_params, output_device_id), close_delay_(close_delay), output_params_(output_params), - streams_opened_(false) { + original_output_params_(output_params), + streams_opened_(false), + reinitialize_timer_(FROM_HERE, + close_delay_, + base::Bind(&AudioOutputResampler::Reinitialize, + base::Unretained(this)), + false) { DCHECK(input_params.IsValid()); DCHECK(output_params.IsValid()); DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); @@ -168,6 +175,24 @@ DCHECK(callbacks_.empty()); } +void AudioOutputResampler::Reinitialize() { + DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(streams_opened_); + + // We can only reinitialize the dispatcher if it has no active proxies. Check + // if one has been created since the reinitialization timer was started. + if (dispatcher_->HasOutputProxies()) + return; + + // Log a trace event so we can get feedback in the field when this happens. + TRACE_EVENT0("audio", "AudioOutputResampler::Reinitialize"); + + dispatcher_->Shutdown(); + output_params_ = original_output_params_; + streams_opened_ = false; + Initialize(); +} + void AudioOutputResampler::Initialize() { DCHECK(!streams_opened_); DCHECK(callbacks_.empty()); @@ -282,6 +307,14 @@ delete it->second; callbacks_.erase(it); } + + // Start the reinitialization timer if there are no active proxies and we're + // not using the originally requested output parameters. This allows us to + // recover from transient output creation errors. + if (!dispatcher_->HasOutputProxies() && callbacks_.empty() && + !output_params_.Equals(original_output_params_)) { + reinitialize_timer_.Reset(); + } } void AudioOutputResampler::Shutdown() {
diff --git a/media/audio/audio_output_resampler.h b/media/audio/audio_output_resampler.h index 4c7be29..18d4905 100644 --- a/media/audio/audio_output_resampler.h +++ b/media/audio/audio_output_resampler.h
@@ -10,9 +10,10 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "media/audio/audio_io.h" #include "media/audio/audio_manager.h" -#include "media/audio/audio_output_dispatcher.h" +#include "media/audio/audio_output_dispatcher_impl.h" #include "media/audio/audio_parameters.h" namespace media { @@ -29,12 +30,7 @@ // // AOR will automatically fall back from AUDIO_PCM_LOW_LATENCY to // AUDIO_PCM_LINEAR if the output device fails to open at the requested output -// parameters. -// -// TODO(dalecurtis): Ideally the low latency path will be as reliable as the -// high latency path once we have channel mixing and support querying for the -// hardware's configured bit depth. Monitor the UMA stats for fallback and -// remove fallback support once it's stable. http://crbug.com/148418 +// parameters. If opening still fails, it will fallback to AUDIO_FAKE. class MEDIA_EXPORT AudioOutputResampler : public AudioOutputDispatcher { public: AudioOutputResampler(AudioManager* audio_manager, @@ -60,11 +56,14 @@ // appropriate output parameters in error situations. void SetupFallbackParams(); - // Used to initialize and reinitialize |dispatcher_|. + // Used to reinitialize |dispatcher_|. + void Reinitialize(); + + // Used to initialize |dispatcher_|. void Initialize(); // Dispatcher to proxy all AudioOutputDispatcher calls too. - scoped_refptr<AudioOutputDispatcher> dispatcher_; + scoped_refptr<AudioOutputDispatcherImpl> dispatcher_; // Map of outstanding OnMoreDataConverter objects. A new object is created // on every StartStream() call and destroyed on CloseStream(). @@ -74,13 +73,22 @@ // Used by AudioOutputDispatcherImpl; kept so we can reinitialize on the fly. base::TimeDelta close_delay_; - // AudioParameters used to setup the output stream. + // AudioParameters used to setup the output stream; changed upon fallback. AudioParameters output_params_; + // The original AudioParameters we were constructed with. + const AudioParameters original_output_params_; + // Whether any streams have been opened through |dispatcher_|, if so we can't // fallback on future OpenStream() failures. bool streams_opened_; + // The reinitialization timer provides a way to recover from temporary failure + // states by clearing the dispatcher if all proxies have been closed and none + // have been created within |close_delay_|. Without this, audio may be lost + // to a fake stream indefinitely for transient errors. + base::Timer reinitialize_timer_; + DISALLOW_COPY_AND_ASSIGN(AudioOutputResampler); };
diff --git a/media/base/android/audio_decoder_job.cc b/media/base/android/audio_decoder_job.cc index 6fbf93a..25de5a1 100644 --- a/media/base/android/audio_decoder_job.cc +++ b/media/base/android/audio_decoder_job.cc
@@ -66,6 +66,8 @@ config_sampling_rate_ = configs.audio_sampling_rate; set_is_content_encrypted(configs.is_audio_encrypted); audio_extra_data_ = configs.audio_extra_data; + audio_codec_delay_ns_ = configs.audio_codec_delay_ns; + audio_seek_preroll_ns_ = configs.audio_seek_preroll_ns; bytes_per_frame_ = kBytesPerAudioOutputSample * num_channels_; if (!media_codec_bridge_) output_sampling_rate_ = config_sampling_rate_; @@ -135,16 +137,18 @@ configs.audio_extra_data.begin()); } -bool AudioDecoderJob::CreateMediaCodecBridgeInternal() { +MediaDecoderJob::MediaDecoderJobStatus + AudioDecoderJob::CreateMediaCodecBridgeInternal() { media_codec_bridge_.reset(AudioCodecBridge::Create(audio_codec_)); if (!media_codec_bridge_) - return false; + return STATUS_FAILURE; if (!(static_cast<AudioCodecBridge*>(media_codec_bridge_.get()))->Start( audio_codec_, config_sampling_rate_, num_channels_, &audio_extra_data_[0], - audio_extra_data_.size(), true, GetMediaCrypto().obj())) { + audio_extra_data_.size(), audio_codec_delay_ns_, audio_seek_preroll_ns_, + true, GetMediaCrypto().obj())) { media_codec_bridge_.reset(); - return false; + return STATUS_FAILURE; } SetVolumeInternal(); @@ -153,7 +157,7 @@ frame_count_ = 0; ResetTimestampHelper(); - return true; + return STATUS_SUCCESS; } void AudioDecoderJob::SetVolumeInternal() {
diff --git a/media/base/android/audio_decoder_job.h b/media/base/android/audio_decoder_job.h index 196cd1b1..f218f3e 100644 --- a/media/base/android/audio_decoder_job.h +++ b/media/base/android/audio_decoder_job.h
@@ -25,12 +25,12 @@ // demuxer config has changed. AudioDecoderJob(const base::Closure& request_data_cb, const base::Closure& on_demuxer_config_changed_cb); - virtual ~AudioDecoderJob(); + ~AudioDecoderJob() override; // MediaDecoderJob implementation. - virtual bool HasStream() const override; - virtual void Flush() override; - virtual void SetDemuxerConfigs(const DemuxerConfigs& configs) override; + bool HasStream() const override; + void Flush() override; + void SetDemuxerConfigs(const DemuxerConfigs& configs) override; // Sets the volume of the audio output. void SetVolume(double volume); @@ -40,17 +40,16 @@ private: // MediaDecoderJob implementation. - virtual void ReleaseOutputBuffer( + void ReleaseOutputBuffer( int output_buffer_index, size_t size, bool render_output, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) override; - virtual bool ComputeTimeToRender() const override; - virtual bool AreDemuxerConfigsChanged( - const DemuxerConfigs& configs) const override; - virtual bool CreateMediaCodecBridgeInternal() override; - virtual void OnOutputFormatChanged() override; + bool ComputeTimeToRender() const override; + bool AreDemuxerConfigsChanged(const DemuxerConfigs& configs) const override; + MediaDecoderJobStatus CreateMediaCodecBridgeInternal() override; + void OnOutputFormatChanged() override; // Helper method to set the audio output volume. void SetVolumeInternal(); @@ -62,6 +61,8 @@ int num_channels_; int config_sampling_rate_; std::vector<uint8> audio_extra_data_; + int64 audio_codec_delay_ns_; + int64 audio_seek_preroll_ns_; double volume_; int bytes_per_frame_;
diff --git a/media/base/android/demuxer_stream_player_params.cc b/media/base/android/demuxer_stream_player_params.cc index edabbd42f2..5c2a11f 100644 --- a/media/base/android/demuxer_stream_player_params.cc +++ b/media/base/android/demuxer_stream_player_params.cc
@@ -11,6 +11,8 @@ audio_channels(0), audio_sampling_rate(0), is_audio_encrypted(false), + audio_codec_delay_ns(-1), + audio_seek_preroll_ns(-1), video_codec(kUnknownVideoCodec), is_video_encrypted(false) {}
diff --git a/media/base/android/demuxer_stream_player_params.h b/media/base/android/demuxer_stream_player_params.h index dc2d56e..cb8ae90e 100644 --- a/media/base/android/demuxer_stream_player_params.h +++ b/media/base/android/demuxer_stream_player_params.h
@@ -25,6 +25,8 @@ int audio_sampling_rate; bool is_audio_encrypted; std::vector<uint8> audio_extra_data; + int64 audio_codec_delay_ns; + int64 audio_seek_preroll_ns; VideoCodec video_codec; gfx::Size video_size;
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index b8e2dc68..c060933 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -656,11 +656,23 @@ @CalledByNative private static void setCodecSpecificData(MediaFormat format, int index, byte[] bytes) { - String name = null; - if (index == 0) { - name = "csd-0"; - } else if (index == 1) { - name = "csd-1"; + // Codec Specific Data is set in the MediaFormat as ByteBuffer entries with keys csd-0, + // csd-1, and so on. See: http://developer.android.com/reference/android/media/MediaCodec.html + // for details. + String name; + switch (index) { + case 0: + name = "csd-0"; + break; + case 1: + name = "csd-1"; + break; + case 2: + name = "csd-2"; + break; + default: + name = null; + break; } if (name != null) { format.setByteBuffer(name, ByteBuffer.wrap(bytes));
diff --git a/media/base/android/media_codec_bridge.cc b/media/base/android/media_codec_bridge.cc index 10fbf0f..9128df32 100644 --- a/media/base/android/media_codec_bridge.cc +++ b/media/base/android/media_codec_bridge.cc
@@ -41,6 +41,8 @@ return "audio/mpeg"; case kCodecVorbis: return "audio/vorbis"; + case kCodecOpus: + return "audio/opus"; case kCodecAAC: return "audio/mp4a-latm"; default: @@ -73,6 +75,8 @@ return "video/x-vnd.on2.vp9"; if (codec == "vorbis") return "audio/vorbis"; + if (codec == "opus") + return "audio/opus"; return std::string(); } @@ -92,6 +96,8 @@ return "mp3"; if (mime == "audio/vorbis") return "vorbis"; + if (mime == "audio/opus") + return "opus"; return std::string(); } @@ -525,6 +531,8 @@ int channel_count, const uint8* extra_data, size_t extra_data_size, + int64 codec_delay_ns, + int64 seek_preroll_ns, bool play_audio, jobject media_crypto) { JNIEnv* env = AttachCurrentThread(); @@ -542,8 +550,10 @@ env, j_mime.obj(), sample_rate, channel_count)); DCHECK(!j_format.is_null()); - if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size)) + if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size, + codec_delay_ns, seek_preroll_ns)) { return false; + } if (!Java_MediaCodecBridge_configureAudio( env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) { @@ -556,8 +566,10 @@ bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, const AudioCodec& codec, const uint8* extra_data, - size_t extra_data_size) { - if (extra_data_size == 0) + size_t extra_data_size, + int64 codec_delay_ns, + int64 seek_preroll_ns) { + if (extra_data_size == 0 && codec != kCodecOpus) return true; JNIEnv* env = AttachCurrentThread(); @@ -648,6 +660,33 @@ Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format); break; } + case kCodecOpus: { + if (!extra_data || extra_data_size == 0 || + codec_delay_ns < 0 || seek_preroll_ns < 0) { + LOG(ERROR) << "Invalid Opus Header"; + return false; + } + + // csd0 - Opus Header + ScopedJavaLocalRef<jbyteArray> csd0 = + base::android::ToJavaByteArray(env, extra_data, extra_data_size); + Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, csd0.obj()); + + // csd1 - Codec Delay + ScopedJavaLocalRef<jbyteArray> csd1 = + base::android::ToJavaByteArray( + env, reinterpret_cast<const uint8*>(&codec_delay_ns), + sizeof(int64_t)); + Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, csd1.obj()); + + // csd2 - Seek Preroll + ScopedJavaLocalRef<jbyteArray> csd2 = + base::android::ToJavaByteArray( + env, reinterpret_cast<const uint8*>(&seek_preroll_ns), + sizeof(int64_t)); + Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2.obj()); + break; + } default: LOG(ERROR) << "Invalid header encountered for codec: " << AudioCodecToAndroidMimeType(codec);
diff --git a/media/base/android/media_codec_bridge.h b/media/base/android/media_codec_bridge.h index 61b4aec..c5eef44 100644 --- a/media/base/android/media_codec_bridge.h +++ b/media/base/android/media_codec_bridge.h
@@ -229,6 +229,7 @@ // Start the audio codec bridge. bool Start(const AudioCodec& codec, int sample_rate, int channel_count, const uint8* extra_data, size_t extra_data_size, + int64 codec_delay_ns, int64 seek_preroll_ns, bool play_audio, jobject media_crypto) WARN_UNUSED_RESULT; // Play the output buffer. This call must be called after @@ -244,7 +245,8 @@ // Configure the java MediaFormat object with the extra codec data passed in. bool ConfigureMediaFormat(jobject j_format, const AudioCodec& codec, - const uint8* extra_data, size_t extra_data_size); + const uint8* extra_data, size_t extra_data_size, + int64 codec_delay_ns, int64 seek_preroll_ns); }; class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge {
diff --git a/media/base/android/media_codec_bridge_unittest.cc b/media/base/android/media_codec_bridge_unittest.cc index 960e33e3..f1c04711 100644 --- a/media/base/android/media_codec_bridge_unittest.cc +++ b/media/base/android/media_codec_bridge_unittest.cc
@@ -160,7 +160,8 @@ scoped_ptr<media::AudioCodecBridge> media_codec; media_codec.reset(AudioCodecBridge::Create(kCodecMP3)); - ASSERT_TRUE(media_codec->Start(kCodecMP3, 44100, 2, NULL, 0, false, NULL)); + ASSERT_TRUE(media_codec->Start( + kCodecMP3, 44100, 2, NULL, 0, 0, 0, false, NULL)); int input_buf_index = -1; MediaCodecStatus status = @@ -229,12 +230,13 @@ uint8 invalid_first_byte[] = { 0x00, 0xff, 0xff, 0xff, 0xff }; EXPECT_FALSE(media_codec->Start( kCodecVorbis, 44100, 2, invalid_first_byte, sizeof(invalid_first_byte), - false, NULL)); + 0, 0, false, NULL)); // Size of the header does not match with the data we passed in. uint8 invalid_size[] = { 0x02, 0x01, 0xff, 0x01, 0xff }; EXPECT_FALSE(media_codec->Start( - kCodecVorbis, 44100, 2, invalid_size, sizeof(invalid_size), false, NULL)); + kCodecVorbis, 44100, 2, invalid_size, sizeof(invalid_size), + 0, 0, false, NULL)); // Size of the header is too large. size_t large_size = 8 * 1024 * 1024 + 2; @@ -244,10 +246,33 @@ very_large_header[i] = 0xff; very_large_header[large_size - 1] = 0xfe; EXPECT_FALSE(media_codec->Start( - kCodecVorbis, 44100, 2, very_large_header, 0x80000000, false, NULL)); + kCodecVorbis, 44100, 2, very_large_header, 0x80000000, + 0, 0, false, NULL)); delete[] very_large_header; } +TEST(MediaCodecBridgeTest, InvalidOpusHeader) { + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); + + scoped_ptr<media::AudioCodecBridge> media_codec; + media_codec.reset(AudioCodecBridge::Create(kCodecOpus)); + uint8 dummy_extra_data[] = { 0, 0 }; + + // Extra Data is NULL. + EXPECT_FALSE(media_codec->Start( + kCodecOpus, 48000, 2, NULL, 0, -1, 0, false, NULL)); + + // Codec Delay is < 0. + EXPECT_FALSE(media_codec->Start( + kCodecOpus, 48000, 2, dummy_extra_data, sizeof(dummy_extra_data), + -1, 0, false, NULL)); + + // Seek Preroll is < 0. + EXPECT_FALSE(media_codec->Start( + kCodecOpus, 48000, 2, dummy_extra_data, sizeof(dummy_extra_data), + 0, -1, false, NULL)); +} + TEST(MediaCodecBridgeTest, PresentationTimestampsDoNotDecrease) { SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
diff --git a/media/base/android/media_decoder_job.cc b/media/base/android/media_decoder_job.cc index 41b74a0..9009443 100644 --- a/media/base/android/media_decoder_job.cc +++ b/media/base/android/media_decoder_job.cc
@@ -110,7 +110,7 @@ RequestData(prefetch_cb); } -bool MediaDecoderJob::Decode( +MediaDecoderJob::MediaDecoderJobStatus MediaDecoderJob::Decode( base::TimeTicks start_time_ticks, base::TimeDelta start_presentation_timestamp, const DecoderCallback& callback) { @@ -120,10 +120,11 @@ if (!media_codec_bridge_ || need_to_reconfig_decoder_job_) { if (drain_decoder_) OnDecoderDrained(); - need_to_reconfig_decoder_job_ = !CreateMediaCodecBridge(); + MediaDecoderJobStatus status = CreateMediaCodecBridge(); + need_to_reconfig_decoder_job_ = (status != STATUS_SUCCESS); skip_eos_enqueue_ = true; if (need_to_reconfig_decoder_job_) - return false; + return status; } decode_cb_ = callback; @@ -133,11 +134,11 @@ base::Unretained(this), start_time_ticks, start_presentation_timestamp)); - return true; + return STATUS_SUCCESS; } DecodeCurrentAccessUnit(start_time_ticks, start_presentation_timestamp); - return true; + return STATUS_SUCCESS; } void MediaDecoderJob::StopDecode() { @@ -205,6 +206,32 @@ return media_crypto; } +bool MediaDecoderJob::SetCurrentFrameToPreviouslyCachedKeyFrame() { + const std::vector<AccessUnit>& access_units = + received_data_[current_demuxer_data_index_].access_units; + // If the current data chunk is empty, the player must be in an initial or + // seek state. The next access unit will always be a key frame. + if (access_units.size() == 0) + return true; + + // Find key frame in all the access units the decoder have decoded, + // or is about to decode. + int i = std::min(access_unit_index_[current_demuxer_data_index_], + access_units.size() - 1); + for (; i >= 0; --i) { + // Config change is always the last access unit, and it always come with + // a key frame afterwards. + if (access_units[i].status == DemuxerStream::kConfigChanged) + return true; + if (access_units[i].is_key_frame) { + access_unit_index_[current_demuxer_data_index_] = i; + return true; + } + } + return false; +} + + void MediaDecoderJob::Release() { DCHECK(ui_task_runner_->BelongsToCurrentThread()); DVLOG(1) << __FUNCTION__; @@ -518,11 +545,8 @@ case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: case MEDIA_CODEC_OUTPUT_END_OF_STREAM: - if (!input_eos_encountered_) { - CurrentDataConsumed( - CurrentAccessUnit().status == DemuxerStream::kConfigChanged); + if (!input_eos_encountered_) access_unit_index_[current_demuxer_data_index_]++; - } break; case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: @@ -589,7 +613,7 @@ // Requests new data if the the last access unit of the next chunk is not EOS. current_demuxer_data_index_ = inactive_demuxer_data_index(); - const AccessUnit last_access_unit = + const AccessUnit& last_access_unit = received_data_[current_demuxer_data_index_].access_units.back(); if (!last_access_unit.is_end_of_stream && last_access_unit.status != DemuxerStream::kAborted) { @@ -616,26 +640,26 @@ // Increase the access unit index so that the new decoder will not handle // the config change again. access_unit_index_[current_demuxer_data_index_]++; - CurrentDataConsumed(true); } -bool MediaDecoderJob::CreateMediaCodecBridge() { +MediaDecoderJob::MediaDecoderJobStatus + MediaDecoderJob::CreateMediaCodecBridge() { DVLOG(1) << __FUNCTION__; DCHECK(ui_task_runner_->BelongsToCurrentThread()); DCHECK(decode_cb_.is_null()); if (!HasStream()) { ReleaseMediaCodecBridge(); - return false; + return STATUS_FAILURE; } // Create |media_codec_bridge_| only if config changes. if (media_codec_bridge_ && !need_to_reconfig_decoder_job_) - return true; + return STATUS_SUCCESS; base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); if (is_content_encrypted_ && media_crypto.is_null()) - return false; + return STATUS_FAILURE; ReleaseMediaCodecBridge(); DVLOG(1) << __FUNCTION__ << " : creating new media codec bridge";
diff --git a/media/base/android/media_decoder_job.h b/media/base/android/media_decoder_job.h index 9a3e76a..83ec5e1 100644 --- a/media/base/android/media_decoder_job.h +++ b/media/base/android/media_decoder_job.h
@@ -27,6 +27,13 @@ // data request will be sent to the renderer. class MediaDecoderJob { public: + // Return value when Decode() is called. + enum MediaDecoderJobStatus { + STATUS_SUCCESS, + STATUS_KEY_FRAME_REQUIRED, + STATUS_FAILURE, + }; + struct Deleter { inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); } }; @@ -57,13 +64,12 @@ // Called by MediaSourcePlayer to decode some data. // |callback| - Run when decode operation has completed. // - // Returns true if the next decode was started and |callback| will be - // called when the decode operation is complete. - // Returns false if |media_codec_bridge_| cannot be created; |callback| is - // ignored and will not be called. - bool Decode(base::TimeTicks start_time_ticks, - base::TimeDelta start_presentation_timestamp, - const DecoderCallback& callback); + // Returns STATUS_SUCCESS on success, or STATUS_FAILURE on failure, or + // STATUS_KEY_FRAME_REQUIRED if a browser seek is required. |callback| is + // ignored and will not be called for the latter 2 cases. + MediaDecoderJobStatus Decode(base::TimeTicks start_time_ticks, + base::TimeDelta start_presentation_timestamp, + const DecoderCallback& callback); // Called to stop the last Decode() early. // If the decoder is in the process of decoding the next frame, then @@ -132,6 +138,11 @@ // Releases the |media_codec_bridge_|. void ReleaseMediaCodecBridge(); + // Sets the current frame to a previously cached key frame. Returns true if + // a key frame is found, or false otherwise. + // TODO(qinmin): add UMA to study the cache hit ratio for key frames. + bool SetCurrentFrameToPreviouslyCachedKeyFrame(); + MediaDrmBridge* drm_bridge() { return drm_bridge_; } void set_is_content_encrypted(bool is_content_encrypted) { @@ -209,18 +220,16 @@ // Called when the decoder is completely drained and is ready to be released. void OnDecoderDrained(); - // Creates |media_codec_bridge_| for decoding purpose. Returns true if it is - // created, or false otherwise. - bool CreateMediaCodecBridge(); - - // Called when an access unit is consumed by the decoder. |is_config_change| - // indicates whether the current access unit is a config change. If it is - // true, the next access unit is guarateed to be an I-frame. - virtual void CurrentDataConsumed(bool is_config_change) {} + // Creates |media_codec_bridge_| for decoding purpose. + // Returns STATUS_SUCCESS on success, or STATUS_FAILURE on failure, or + // STATUS_KEY_FRAME_REQUIRED if a browser seek is required. + MediaDecoderJobStatus CreateMediaCodecBridge(); // Implemented by the child class to create |media_codec_bridge_| for a - // particular stream. Returns true if it is created, or false otherwise. - virtual bool CreateMediaCodecBridgeInternal() = 0; + // particular stream. + // Returns STATUS_SUCCESS on success, or STATUS_FAILURE on failure, or + // STATUS_KEY_FRAME_REQUIRED if a browser seek is required. + virtual MediaDecoderJobStatus CreateMediaCodecBridgeInternal() = 0; // Returns true if the |configs| doesn't match the current demuxer configs // the decoder job has.
diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index 5566739f..e774470 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h
@@ -35,7 +35,7 @@ typedef base::Callback<void(bool)> ResetCredentialsCB; - virtual ~MediaDrmBridge(); + ~MediaDrmBridge() override; // Checks whether MediaDRM is available. // All other static methods check IsAvailable() internally. There's no need
diff --git a/media/base/android/media_player_bridge.h b/media/base/android/media_player_bridge.h index 9dd6eec..291aa979 100644 --- a/media/base/android/media_player_bridge.h +++ b/media/base/android/media_player_bridge.h
@@ -50,29 +50,29 @@ const RequestMediaResourcesCB& request_media_resources_cb, const GURL& frame_url, bool allow_credentials); - virtual ~MediaPlayerBridge(); + ~MediaPlayerBridge() override; // Initialize this object and extract the metadata from the media. virtual void Initialize(); // MediaPlayerAndroid implementation. - virtual void SetVideoSurface(gfx::ScopedJavaSurface surface) override; - virtual void Start() override; - virtual void Pause(bool is_media_related_action) override; - virtual void SeekTo(base::TimeDelta timestamp) override; - virtual void Release() override; - virtual void SetVolume(double volume) override; - virtual int GetVideoWidth() override; - virtual int GetVideoHeight() override; - virtual base::TimeDelta GetCurrentTime() override; - virtual base::TimeDelta GetDuration() override; - virtual bool IsPlaying() override; - virtual bool CanPause() override; - virtual bool CanSeekForward() override; - virtual bool CanSeekBackward() override; - virtual bool IsPlayerReady() override; - virtual GURL GetUrl() override; - virtual GURL GetFirstPartyForCookies() override; + void SetVideoSurface(gfx::ScopedJavaSurface surface) override; + void Start() override; + void Pause(bool is_media_related_action) override; + void SeekTo(base::TimeDelta timestamp) override; + void Release() override; + void SetVolume(double volume) override; + int GetVideoWidth() override; + int GetVideoHeight() override; + base::TimeDelta GetCurrentTime() override; + base::TimeDelta GetDuration() override; + bool IsPlaying() override; + bool CanPause() override; + bool CanSeekForward() override; + bool CanSeekBackward() override; + bool IsPlayerReady() override; + GURL GetUrl() override; + GURL GetFirstPartyForCookies() override; void OnDidSetDataUriDataSource(JNIEnv* env, jobject obj, jboolean success); @@ -87,10 +87,10 @@ virtual void Prepare(); // MediaPlayerAndroid implementation. - virtual void OnVideoSizeChanged(int width, int height) override; - virtual void OnPlaybackComplete() override; - virtual void OnMediaInterrupted() override; - virtual void OnMediaPrepared() override; + void OnVideoSizeChanged(int width, int height) override; + void OnPlaybackComplete() override; + void OnMediaInterrupted() override; + void OnMediaPrepared() override; // Create the corresponding Java class instance. virtual void CreateJavaMediaPlayerBridge();
diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 53df8d3..bb42ac28 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc
@@ -564,18 +564,25 @@ DCHECK(!audio_decoder_job_->is_decoding()); DCHECK(!AudioFinished()); - if (audio_decoder_job_->Decode( + MediaDecoderJob::MediaDecoderJobStatus status = audio_decoder_job_->Decode( start_time_ticks_, start_presentation_timestamp_, - base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true))) { - TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", - audio_decoder_job_.get()); - return; - } + base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true)); - is_waiting_for_audio_decoder_ = true; - if (!IsEventPending(DECODER_CREATION_EVENT_PENDING)) - SetPendingEvent(DECODER_CREATION_EVENT_PENDING); + switch (status) { + case MediaDecoderJob::STATUS_SUCCESS: + TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", + audio_decoder_job_.get()); + break; + case MediaDecoderJob::STATUS_KEY_FRAME_REQUIRED: + NOTREACHED(); + break; + case MediaDecoderJob::STATUS_FAILURE: + is_waiting_for_audio_decoder_ = true; + if (!IsEventPending(DECODER_CREATION_EVENT_PENDING)) + SetPendingEvent(DECODER_CREATION_EVENT_PENDING); + break; + } } void MediaSourcePlayer::DecodeMoreVideo() { @@ -583,25 +590,26 @@ DCHECK(!video_decoder_job_->is_decoding()); DCHECK(!VideoFinished()); - if (video_decoder_job_->Decode( + MediaDecoderJob::MediaDecoderJobStatus status = video_decoder_job_->Decode( start_time_ticks_, start_presentation_timestamp_, base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, - false))) { - TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", - video_decoder_job_.get()); - return; - } + false)); - // If the decoder is waiting for iframe, trigger a browser seek. - if (!video_decoder_job_->next_video_data_is_iframe()) { - BrowserSeekToCurrentTime(); - return; + switch (status) { + case MediaDecoderJob::STATUS_SUCCESS: + TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", + video_decoder_job_.get()); + break; + case MediaDecoderJob::STATUS_KEY_FRAME_REQUIRED: + BrowserSeekToCurrentTime(); + break; + case MediaDecoderJob::STATUS_FAILURE: + is_waiting_for_video_decoder_ = true; + if (!IsEventPending(DECODER_CREATION_EVENT_PENDING)) + SetPendingEvent(DECODER_CREATION_EVENT_PENDING); + break; } - - is_waiting_for_video_decoder_ = true; - if (!IsEventPending(DECODER_CREATION_EVENT_PENDING)) - SetPendingEvent(DECODER_CREATION_EVENT_PENDING); } void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
diff --git a/media/base/android/media_source_player.h b/media/base/android/media_source_player.h index 5ef684ea..874e61a 100644 --- a/media/base/android/media_source_player.h +++ b/media/base/android/media_source_player.h
@@ -43,32 +43,31 @@ const RequestMediaResourcesCB& request_media_resources_cb, scoped_ptr<DemuxerAndroid> demuxer, const GURL& frame_url); - virtual ~MediaSourcePlayer(); + ~MediaSourcePlayer() override; // MediaPlayerAndroid implementation. - virtual void SetVideoSurface(gfx::ScopedJavaSurface surface) override; - virtual void Start() override; - virtual void Pause(bool is_media_related_action) override; - virtual void SeekTo(base::TimeDelta timestamp) override; - virtual void Release() override; - virtual void SetVolume(double volume) override; - virtual int GetVideoWidth() override; - virtual int GetVideoHeight() override; - virtual base::TimeDelta GetCurrentTime() override; - virtual base::TimeDelta GetDuration() override; - virtual bool IsPlaying() override; - virtual bool CanPause() override; - virtual bool CanSeekForward() override; - virtual bool CanSeekBackward() override; - virtual bool IsPlayerReady() override; - virtual void SetCdm(BrowserCdm* cdm) override; + void SetVideoSurface(gfx::ScopedJavaSurface surface) override; + void Start() override; + void Pause(bool is_media_related_action) override; + void SeekTo(base::TimeDelta timestamp) override; + void Release() override; + void SetVolume(double volume) override; + int GetVideoWidth() override; + int GetVideoHeight() override; + base::TimeDelta GetCurrentTime() override; + base::TimeDelta GetDuration() override; + bool IsPlaying() override; + bool CanPause() override; + bool CanSeekForward() override; + bool CanSeekBackward() override; + bool IsPlayerReady() override; + void SetCdm(BrowserCdm* cdm) override; // DemuxerAndroidClient implementation. - virtual void OnDemuxerConfigsAvailable(const DemuxerConfigs& params) override; - virtual void OnDemuxerDataAvailable(const DemuxerData& params) override; - virtual void OnDemuxerSeekDone( - base::TimeDelta actual_browser_seek_time) override; - virtual void OnDemuxerDurationChanged(base::TimeDelta duration) override; + void OnDemuxerConfigsAvailable(const DemuxerConfigs& params) override; + void OnDemuxerDataAvailable(const DemuxerData& params) override; + void OnDemuxerSeekDone(base::TimeDelta actual_browser_seek_time) override; + void OnDemuxerDurationChanged(base::TimeDelta duration) override; private: friend class MediaSourcePlayerTest;
diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc index 5b9a0e9..9ac934e 100644 --- a/media/base/android/media_source_player_unittest.cc +++ b/media/base/android/media_source_player_unittest.cc
@@ -47,42 +47,39 @@ num_resources_requested_(0), num_metadata_changes_(0), timestamp_updated_(false) {} - virtual ~MockMediaPlayerManager() {} + ~MockMediaPlayerManager() override {} // MediaPlayerManager implementation. - virtual MediaResourceGetter* GetMediaResourceGetter() override { - return NULL; - } - virtual MediaUrlInterceptor* GetMediaUrlInterceptor() override { - return NULL; - } - virtual void OnTimeUpdate(int player_id, - base::TimeDelta current_time, - base::TimeTicks current_time_ticks) override { + MediaResourceGetter* GetMediaResourceGetter() override { return NULL; } + MediaUrlInterceptor* GetMediaUrlInterceptor() override { return NULL; } + void OnTimeUpdate(int player_id, + base::TimeDelta current_time, + base::TimeTicks current_time_ticks) override { timestamp_updated_ = true; } - virtual void OnMediaMetadataChanged( - int player_id, base::TimeDelta duration, int width, int height, - bool success) override { + void OnMediaMetadataChanged(int player_id, + base::TimeDelta duration, + int width, + int height, + bool success) override { num_metadata_changes_++; } - virtual void OnPlaybackComplete(int player_id) override { + void OnPlaybackComplete(int player_id) override { playback_completed_ = true; if (message_loop_->is_running()) message_loop_->Quit(); } - virtual void OnMediaInterrupted(int player_id) override {} - virtual void OnBufferingUpdate(int player_id, int percentage) override {} - virtual void OnSeekComplete(int player_id, - const base::TimeDelta& current_time) override {} - virtual void OnError(int player_id, int error) override {} - virtual void OnVideoSizeChanged(int player_id, int width, - int height) override {} - virtual MediaPlayerAndroid* GetFullscreenPlayer() override { return NULL; } - virtual MediaPlayerAndroid* GetPlayer(int player_id) override { return NULL; } - virtual void RequestFullScreen(int player_id) override {} + void OnMediaInterrupted(int player_id) override {} + void OnBufferingUpdate(int player_id, int percentage) override {} + void OnSeekComplete(int player_id, + const base::TimeDelta& current_time) override {} + void OnError(int player_id, int error) override {} + void OnVideoSizeChanged(int player_id, int width, int height) override {} + MediaPlayerAndroid* GetFullscreenPlayer() override { return NULL; } + MediaPlayerAndroid* GetPlayer(int player_id) override { return NULL; } + void RequestFullScreen(int player_id) override {} #if defined(VIDEO_HOLE) - virtual bool ShouldUseVideoOverlayForEmbeddedEncryptedVideo() override { + bool ShouldUseVideoOverlayForEmbeddedEncryptedVideo() override { return false; } #endif // defined(VIDEO_HOLE) @@ -131,16 +128,16 @@ num_data_requests_(0), num_seek_requests_(0), num_browser_seek_requests_(0) {} - virtual ~MockDemuxerAndroid() {} + ~MockDemuxerAndroid() override {} - virtual void Initialize(DemuxerAndroidClient* client) override {} - virtual void RequestDemuxerData(DemuxerStream::Type type) override { + void Initialize(DemuxerAndroidClient* client) override {} + void RequestDemuxerData(DemuxerStream::Type type) override { num_data_requests_++; if (message_loop_->is_running()) message_loop_->Quit(); } - virtual void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, - bool is_browser_seek) override { + void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, + bool is_browser_seek) override { num_seek_requests_++; if (is_browser_seek) num_browser_seek_requests_++; @@ -177,7 +174,7 @@ GURL()), decoder_callback_hook_executed_(false), surface_texture_a_is_next_(true) {} - virtual ~MediaSourcePlayerTest() {} + ~MediaSourcePlayerTest() override {} protected: // Get the decoder job from the MediaSourcePlayer. The return value must not @@ -435,6 +432,10 @@ return data; } + bool HasData(bool is_audio) { + return GetMediaDecoderJob(is_audio)->HasData(); + } + // Helper method for use at test start. It starts an audio decoder job and // immediately feeds it some data to decode. Then, without letting the decoder // job complete a decode cycle, it also starts player SeekTo(). Upon return, @@ -1043,7 +1044,9 @@ // Playback resumes once a non-empty surface is passed. CreateNextTextureAndSetVideoSurface(); - EXPECT_EQ(1, demuxer_->num_browser_seek_requests()); + EXPECT_EQ(0, demuxer_->num_browser_seek_requests()); + while(demuxer_->num_browser_seek_requests() != 1) + message_loop_.RunUntilIdle(); WaitForVideoDecodeDone(); } @@ -1534,6 +1537,34 @@ EXPECT_EQ(1, demuxer_->num_seek_requests()); } +TEST_F(MediaSourcePlayerTest, NoBrowserSeekWithKeyFrameInCache) { + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); + + // Test that browser seek is not needed if a key frame is found in data + // cache. + CreateNextTextureAndSetVideoSurface(); + StartVideoDecoderJob(); + DemuxerData data = CreateReadFromDemuxerAckForVideo(false); + data.access_units[0].is_key_frame = true; + + // Simulate demuxer's response to the video data request. + player_.OnDemuxerDataAvailable(data); + + // Trigger decoder recreation later by changing surfaces. + CreateNextTextureAndSetVideoSurface(); + + // Wait for the media codec bridge to finish decoding and be reset. + WaitForVideoDecodeDone(); + EXPECT_FALSE(HasData(false)); + + // Send a non key frame to decoder so that decoder can continue. This will + // not trigger any browser seeks as the previous key frame is still in the + // buffer. + player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false)); + WaitForVideoDecodeDone(); + EXPECT_EQ(0, demuxer_->num_browser_seek_requests()); +} + TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) { SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
diff --git a/media/base/android/video_decoder_job.cc b/media/base/android/video_decoder_job.cc index e69426d..d34ea28 100644 --- a/media/base/android/video_decoder_job.cc +++ b/media/base/android/video_decoder_job.cc
@@ -37,8 +37,7 @@ config_height_(0), output_width_(0), output_height_(0), - request_resources_cb_(request_resources_cb), - next_video_data_is_iframe_(true) { + request_resources_cb_(request_resources_cb) { } VideoDecoderJob::~VideoDecoderJob() {} @@ -61,11 +60,6 @@ return video_codec_ != kUnknownVideoCodec; } -void VideoDecoderJob::Flush() { - MediaDecoderJob::Flush(); - next_video_data_is_iframe_ = true; -} - void VideoDecoderJob::ReleaseDecoderResources() { MediaDecoderJob::ReleaseDecoderResources(); surface_ = gfx::ScopedJavaSurface(); @@ -124,16 +118,17 @@ config_height_ != configs.video_size.height(); } -bool VideoDecoderJob::CreateMediaCodecBridgeInternal() { +MediaDecoderJob::MediaDecoderJobStatus + VideoDecoderJob::CreateMediaCodecBridgeInternal() { if (surface_.IsEmpty()) { ReleaseMediaCodecBridge(); - return false; + return STATUS_FAILURE; } - // If the next data is not iframe, return false so that the player need to - // perform a browser seek. - if (!next_video_data_is_iframe_) - return false; + // If we cannot find a key frame in cache, browser seek is needed. + bool next_video_data_is_iframe = SetCurrentFrameToPreviouslyCachedKeyFrame(); + if (!next_video_data_is_iframe) + return STATUS_KEY_FRAME_REQUIRED; bool is_secure = is_content_encrypted() && drm_bridge() && drm_bridge()->IsProtectedSurfaceRequired(); @@ -143,14 +138,10 @@ surface_.j_surface().obj(), GetMediaCrypto().obj())); if (!media_codec_bridge_) - return false; + return STATUS_FAILURE; request_resources_cb_.Run(); - return true; -} - -void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) { - next_video_data_is_iframe_ = is_config_change; + return STATUS_SUCCESS; } bool VideoDecoderJob::UpdateOutputFormat() {
diff --git a/media/base/android/video_decoder_job.h b/media/base/android/video_decoder_job.h index ea99a533..36f70d83 100644 --- a/media/base/android/video_decoder_job.h +++ b/media/base/android/video_decoder_job.h
@@ -25,41 +25,33 @@ const base::Closure& request_data_cb, const base::Closure& request_resources_cb, const base::Closure& on_demuxer_config_changed_cb); - virtual ~VideoDecoderJob(); + ~VideoDecoderJob() override; // Passes a java surface object to the codec. Returns true if the surface // can be used by the decoder, or false otherwise. bool SetVideoSurface(gfx::ScopedJavaSurface surface); // MediaDecoderJob implementation. - virtual bool HasStream() const override; - virtual void Flush() override; - virtual void ReleaseDecoderResources() override; - virtual void SetDemuxerConfigs(const DemuxerConfigs& configs) override; - - bool next_video_data_is_iframe() { - return next_video_data_is_iframe_; - } + bool HasStream() const override; + void ReleaseDecoderResources() override; + void SetDemuxerConfigs(const DemuxerConfigs& configs) override; int output_width() const { return output_width_; } int output_height() const { return output_height_; } private: // MediaDecoderJob implementation. - virtual void ReleaseOutputBuffer( + void ReleaseOutputBuffer( int output_buffer_index, size_t size, bool render_output, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) override; - virtual bool ComputeTimeToRender() const override; - virtual bool IsCodecReconfigureNeeded( - const DemuxerConfigs& configs) const override; - virtual bool AreDemuxerConfigsChanged( - const DemuxerConfigs& configs) const override; - virtual bool CreateMediaCodecBridgeInternal() override; - virtual void CurrentDataConsumed(bool is_config_change) override; - virtual bool UpdateOutputFormat() override; + bool ComputeTimeToRender() const override; + bool IsCodecReconfigureNeeded(const DemuxerConfigs& configs) const override; + bool AreDemuxerConfigsChanged(const DemuxerConfigs& configs) const override; + MediaDecoderJobStatus CreateMediaCodecBridgeInternal() override; + bool UpdateOutputFormat() override; // Returns true if a protected surface is required for video playback. bool IsProtectedSurfaceRequired(); @@ -80,11 +72,6 @@ base::Closure request_resources_cb_; base::Closure release_resources_cb_; - // Track whether the next access unit is an I-frame. The first access - // unit after Flush() and CurrentDataConsumed(true) is guaranteed to be an - // I-frame. - bool next_video_data_is_iframe_; - DISALLOW_COPY_AND_ASSIGN(VideoDecoderJob); };
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index f97660c3..d4f4387 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc
@@ -120,7 +120,8 @@ bool IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, - const std::string& key_system); + const std::string& key_system, + bool reportToUma); std::string GetKeySystemNameForUMA(const std::string& key_system) const; @@ -475,7 +476,8 @@ bool KeySystems::IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, - const std::string& key_system) { + const std::string& key_system, + bool reportToUma) { DCHECK(thread_checker_.CalledOnValidThread()); // If |key_system| is a parent key system, use its concrete child. @@ -483,7 +485,8 @@ bool has_type = !mime_type.empty(); - key_systems_support_uma_.ReportKeySystemQuery(key_system, has_type); + if (reportToUma) + key_systems_support_uma_.ReportKeySystemQuery(key_system, has_type); // Check key system support. KeySystemPropertiesMap::const_iterator key_system_iter = @@ -491,7 +494,8 @@ if (key_system_iter == concrete_key_system_map_.end()) return false; - key_systems_support_uma_.ReportKeySystemSupport(key_system, false); + if (reportToUma) + key_systems_support_uma_.ReportKeySystemSupport(key_system, false); if (!has_type) { DCHECK(codecs.empty()); @@ -510,7 +514,8 @@ return false; } - key_systems_support_uma_.ReportKeySystemSupport(key_system, true); + if (reportToUma) + key_systems_support_uma_.ReportKeySystemSupport(key_system, true); return true; } @@ -621,7 +626,15 @@ const std::vector<std::string>& codecs, const std::string& key_system) { return KeySystems::GetInstance().IsSupportedKeySystemWithMediaMimeType( - mime_type, codecs, key_system); + mime_type, codecs, key_system, false); +} + +bool PrefixedIsSupportedKeySystemWithMediaMimeType( + const std::string& mime_type, + const std::vector<std::string>& codecs, + const std::string& key_system) { + return KeySystems::GetInstance().IsSupportedKeySystemWithMediaMimeType( + mime_type, codecs, key_system, true); } std::string GetKeySystemNameForUMA(const std::string& key_system) {
diff --git a/media/base/key_systems.h b/media/base/key_systems.h index 4eea042..d761abf 100644 --- a/media/base/key_systems.h +++ b/media/base/key_systems.h
@@ -52,12 +52,19 @@ // systems. MEDIA_EXPORT bool IsConcreteSupportedKeySystem(const std::string& key_system); -// Returns whether |key_sytem| supports the specified media type and codec(s). +// Returns whether |key_system| supports the specified media type and codec(s). MEDIA_EXPORT bool IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, const std::string& key_system); +// Returns whether |key_system| supports the specified media type and codec(s). +// To be used with prefixed EME only as it generates UMAs based on the query. +MEDIA_EXPORT bool PrefixedIsSupportedKeySystemWithMediaMimeType( + const std::string& mime_type, + const std::vector<std::string>& codecs, + const std::string& key_system); + // Returns a name for |key_system| suitable to UMA logging. MEDIA_EXPORT std::string GetKeySystemNameForUMA(const std::string& key_system);
diff --git a/media/base/key_systems_unittest.cc b/media/base/key_systems_unittest.cc index afd9dc06..07bc5ec 100644 --- a/media/base/key_systems_unittest.cc +++ b/media/base/key_systems_unittest.cc
@@ -718,4 +718,22 @@ kVideoWebM, no_codecs(), kExternal)); } +TEST_F(KeySystemsTest, PrefixedKeySystemsUpdate) { + EXPECT_TRUE(IsConcreteSupportedKeySystem(kUsesAes)); + EXPECT_TRUE(PrefixedIsSupportedKeySystemWithMediaMimeType( + kVideoWebM, no_codecs(), kUsesAes)); + EXPECT_TRUE(IsConcreteSupportedKeySystem(kExternal)); + EXPECT_TRUE(PrefixedIsSupportedKeySystemWithMediaMimeType( + kVideoWebM, no_codecs(), kExternal)); + + UpdateClientKeySystems(); + + EXPECT_TRUE(IsConcreteSupportedKeySystem(kUsesAes)); + EXPECT_TRUE(PrefixedIsSupportedKeySystemWithMediaMimeType( + kVideoWebM, no_codecs(), kUsesAes)); + EXPECT_FALSE(IsConcreteSupportedKeySystem(kExternal)); + EXPECT_FALSE(PrefixedIsSupportedKeySystemWithMediaMimeType( + kVideoWebM, no_codecs(), kExternal)); +} + } // namespace media
diff --git a/media/blink/cdm_session_adapter.cc b/media/blink/cdm_session_adapter.cc index 9fe248c..f02ff4e 100644 --- a/media/blink/cdm_session_adapter.cc +++ b/media/blink/cdm_session_adapter.cc
@@ -29,6 +29,7 @@ bool CdmSessionAdapter::Initialize(CdmFactory* cdm_factory, const std::string& key_system, const GURL& security_origin) { + key_system_ = key_system; key_system_uma_prefix_ = kMediaEME + GetKeySystemNameForUMA(key_system) + kDot; @@ -110,6 +111,10 @@ return media_keys_->GetCdmContext(); } +const std::string& CdmSessionAdapter::GetKeySystem() const { + return key_system_; +} + const std::string& CdmSessionAdapter::GetKeySystemUMAPrefix() const { return key_system_uma_prefix_; }
diff --git a/media/blink/cdm_session_adapter.h b/media/blink/cdm_session_adapter.h index d1b9b9aa..bfbdb4ee 100644 --- a/media/blink/cdm_session_adapter.h +++ b/media/blink/cdm_session_adapter.h
@@ -89,6 +89,9 @@ // after WebContentDecryptionModule is freed. http://crbug.com/330324 CdmContext* GetCdmContext(); + // Returns the key system name. + const std::string& GetKeySystem() const; + // Returns a prefix to use for UMAs. const std::string& GetKeySystemUMAPrefix() const; @@ -124,6 +127,7 @@ SessionMap sessions_; + std::string key_system_; std::string key_system_uma_prefix_; // NOTE: Weak pointers must be invalidated before all other member variables.
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc index 2fba8d0..02d9f5e 100644 --- a/media/blink/webcontentdecryptionmodulesession_impl.cc +++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "media/base/cdm_key_information.h" #include "media/base/cdm_promise.h" +#include "media/base/key_systems.h" #include "media/base/media_keys.h" #include "media/blink/cdm_result_promise.h" #include "media/blink/cdm_session_adapter.h" @@ -137,6 +138,22 @@ << "init_data_type '" << init_data_type_as_ascii << "' may be a MIME type"; + // Step 5 from https://w3c.github.io/encrypted-media/#generateRequest. + // 5. If the Key System implementation represented by this object's cdm + // implementation value does not support initDataType as an Initialization + // Data Type, return a promise rejected with a new DOMException whose name + // is NotSupportedError. String comparison is case-sensitive. + if (!IsSupportedKeySystemWithInitDataType(adapter_->GetKeySystem(), + init_data_type_as_ascii)) { + std::string message = "The initialization data type " + + init_data_type_as_ascii + + " is not supported by the key system."; + result.completeWithError( + blink::WebContentDecryptionModuleExceptionNotSupportedError, 0, + blink::WebString::fromUTF8(message)); + return; + } + MediaKeys::SessionType session_type_enum; if (session_type == kPersistentLicenseSessionType) { session_type_enum = MediaKeys::PERSISTENT_LICENSE_SESSION;
diff --git a/media/cast/cast_config.h b/media/cast/cast_config.h index f22f1d0..89af430 100644 --- a/media/cast/cast_config.h +++ b/media/cast/cast_config.h
@@ -176,8 +176,11 @@ typedef Packet Packet; typedef PacketList PacketList; -typedef base::Callback<void(CastInitializationStatus)> - CastInitializationCallback; +// Callback that is run to update the client with current status. This is used +// to allow the client to wait for asynchronous initialization to complete +// before sending frames, and also to be notified of any runtime errors that +// have halted the session. +typedef base::Callback<void(OperationalStatus)> StatusChangeCallback; typedef base::Callback<void(scoped_refptr<base::SingleThreadTaskRunner>, scoped_ptr<media::VideoEncodeAccelerator>)>
diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h index 661c095..582729ef 100644 --- a/media/cast/cast_defines.h +++ b/media/cast/cast_defines.h
@@ -36,18 +36,33 @@ const int64 kCastMessageUpdateIntervalMs = 33; const int64 kNackRepeatIntervalMs = 30; -enum CastInitializationStatus { - STATUS_AUDIO_UNINITIALIZED, - STATUS_VIDEO_UNINITIALIZED, - STATUS_AUDIO_INITIALIZED, - STATUS_VIDEO_INITIALIZED, - STATUS_INVALID_CAST_ENVIRONMENT, - STATUS_INVALID_CRYPTO_CONFIGURATION, - STATUS_UNSUPPORTED_AUDIO_CODEC, - STATUS_UNSUPPORTED_VIDEO_CODEC, - STATUS_INVALID_AUDIO_CONFIGURATION, - STATUS_INVALID_VIDEO_CONFIGURATION, - STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED, +// Success/in-progress/failure status codes bubbled up to clients via +// StatusChangeCallbacks. +enum OperationalStatus { + // Client should not send frames yet (sender), or should not expect to receive + // frames yet (receiver). + STATUS_UNINITIALIZED, + + // Client may now send or receive frames. + STATUS_INITIALIZED, + + // Codec is being re-initialized. Client may continue sending frames, but + // some may be ignored/dropped until a transition back to STATUS_INITIALIZED. + STATUS_CODEC_REINIT_PENDING, + + // Session has halted due to invalid configuration. + STATUS_INVALID_CONFIGURATION, + + // Session has halted due to an unsupported codec. + STATUS_UNSUPPORTED_CODEC, + + // Session has halted due to a codec initialization failure. Note that this + // can be reported after STATUS_INITIALIZED/STATUS_CODEC_REINIT_PENDING if the + // codec was re-initialized during the session. + STATUS_CODEC_INIT_FAILED, + + // Session has halted due to a codec runtime failure. + STATUS_CODEC_RUNTIME_ERROR, }; enum DefaultSettings {
diff --git a/media/cast/cast_sender.h b/media/cast/cast_sender.h index 841e1ba..1ccebd1 100644 --- a/media/cast/cast_sender.h +++ b/media/cast/cast_sender.h
@@ -87,16 +87,18 @@ virtual scoped_refptr<AudioFrameInput> audio_frame_input() = 0; // Initialize the audio stack. Must be called in order to send audio frames. - // Status of the initialization will be returned on cast_initialization_cb. + // |status_change_cb| will be run as operational status changes. virtual void InitializeAudio( const AudioSenderConfig& audio_config, - const CastInitializationCallback& cast_initialization_cb) = 0; + const StatusChangeCallback& status_change_cb) = 0; // Initialize the video stack. Must be called in order to send video frames. - // Status of the initialization will be returned on cast_initialization_cb. + // |status_change_cb| will be run as operational status changes. + // + // TODO(miu): Remove the VEA-specific callbacks. http://crbug.com/454029 virtual void InitializeVideo( const VideoSenderConfig& video_config, - const CastInitializationCallback& cast_initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) = 0;
diff --git a/media/cast/cast_sender_impl.cc b/media/cast/cast_sender_impl.cc index 83048d7..b47ae9c 100644 --- a/media/cast/cast_sender_impl.cc +++ b/media/cast/cast_sender_impl.cc
@@ -107,7 +107,7 @@ void CastSenderImpl::InitializeAudio( const AudioSenderConfig& audio_config, - const CastInitializationCallback& cast_initialization_cb) { + const StatusChangeCallback& status_change_cb) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); CHECK(audio_config.use_external_encoder || cast_environment_->HasAudioThread()); @@ -115,14 +115,12 @@ VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()"; audio_sender_.reset( - new AudioSender(cast_environment_, audio_config, transport_sender_)); - - const CastInitializationStatus status = audio_sender_->InitializationResult(); - if (status == STATUS_AUDIO_INITIALIZED) { - audio_frame_input_ = - new LocalAudioFrameInput(cast_environment_, audio_sender_->AsWeakPtr()); - } - cast_initialization_cb.Run(status); + new AudioSender(cast_environment_, + audio_config, + base::Bind(&CastSenderImpl::OnAudioStatusChange, + weak_factory_.GetWeakPtr(), + status_change_cb), + transport_sender_)); if (video_sender_) { DCHECK(audio_sender_->GetTargetPlayoutDelay() == video_sender_->GetTargetPlayoutDelay()); @@ -131,7 +129,7 @@ void CastSenderImpl::InitializeVideo( const VideoSenderConfig& video_config, - const CastInitializationCallback& cast_initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); @@ -141,8 +139,9 @@ video_sender_.reset(new VideoSender( cast_environment_, video_config, - base::Bind(&CastSenderImpl::OnVideoInitialized, - weak_factory_.GetWeakPtr(), cast_initialization_cb), + base::Bind(&CastSenderImpl::OnVideoStatusChange, + weak_factory_.GetWeakPtr(), + status_change_cb), create_vea_cb, create_video_encode_mem_cb, transport_sender_, @@ -178,16 +177,27 @@ } } -void CastSenderImpl::OnVideoInitialized( - const CastInitializationCallback& initialization_cb, - media::cast::CastInitializationStatus result) { +void CastSenderImpl::OnAudioStatusChange( + const StatusChangeCallback& status_change_cb, + OperationalStatus status) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); - if (result == STATUS_VIDEO_INITIALIZED) { + if (status == STATUS_INITIALIZED && !audio_frame_input_) { + audio_frame_input_ = + new LocalAudioFrameInput(cast_environment_, audio_sender_->AsWeakPtr()); + } + status_change_cb.Run(status); +} + +void CastSenderImpl::OnVideoStatusChange( + const StatusChangeCallback& status_change_cb, + OperationalStatus status) { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + if (status == STATUS_INITIALIZED && !video_frame_input_) { video_frame_input_ = new LocalVideoFrameInput(cast_environment_, video_sender_->AsWeakPtr(), video_sender_->CreateVideoFrameFactory()); } - initialization_cb.Run(result); + status_change_cb.Run(status); } } // namespace cast
diff --git a/media/cast/cast_sender_impl.h b/media/cast/cast_sender_impl.h index b76603e..3a3a247 100644 --- a/media/cast/cast_sender_impl.h +++ b/media/cast/cast_sender_impl.h
@@ -27,12 +27,11 @@ CastSenderImpl(scoped_refptr<CastEnvironment> cast_environment, CastTransportSender* const transport_sender); - void InitializeAudio( - const AudioSenderConfig& audio_config, - const CastInitializationCallback& cast_initialization_cb) override; + void InitializeAudio(const AudioSenderConfig& audio_config, + const StatusChangeCallback& status_change_cb) override; void InitializeVideo( const VideoSenderConfig& video_config, - const CastInitializationCallback& cast_initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) override; @@ -46,11 +45,11 @@ private: void ReceivedPacket(scoped_ptr<Packet> packet); - void OnVideoInitialized( - const CastInitializationCallback& initialization_cb, - media::cast::CastInitializationStatus result); + void OnAudioStatusChange(const StatusChangeCallback& status_change_cb, + OperationalStatus status); + void OnVideoStatusChange(const StatusChangeCallback& status_change_cb, + OperationalStatus status); - CastInitializationCallback initialization_callback_; scoped_ptr<AudioSender> audio_sender_; scoped_ptr<VideoSender> video_sender_; scoped_refptr<AudioFrameInput> audio_frame_input_;
diff --git a/media/cast/receiver/audio_decoder.cc b/media/cast/receiver/audio_decoder.cc index 53ac3f0..bc5b596 100644 --- a/media/cast/receiver/audio_decoder.cc +++ b/media/cast/receiver/audio_decoder.cc
@@ -29,19 +29,19 @@ : cast_environment_(cast_environment), codec_(codec), num_channels_(num_channels), - cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), + operational_status_(STATUS_UNINITIALIZED), seen_first_frame_(false) { if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0) - cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION; + operational_status_ = STATUS_INVALID_CONFIGURATION; } - CastInitializationStatus InitializationResult() const { - return cast_initialization_status_; + OperationalStatus InitializationResult() const { + return operational_status_; } void DecodeFrame(scoped_ptr<EncodedFrame> encoded_frame, const DecodeFrameCallback& callback) { - DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED); + DCHECK_EQ(operational_status_, STATUS_INITIALIZED); static_assert(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_), "size of frame_id types do not match"); @@ -80,8 +80,8 @@ const Codec codec_; const int num_channels_; - // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. - CastInitializationStatus cast_initialization_status_; + // Subclass' ctor is expected to set this to STATUS_INITIALIZED. + OperationalStatus operational_status_; private: bool seen_first_frame_; @@ -104,15 +104,14 @@ max_samples_per_frame_( kOpusMaxFrameDurationMillis * sampling_rate / 1000), buffer_(new float[max_samples_per_frame_ * num_channels]) { - if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) return; if (opus_decoder_init(opus_decoder_, sampling_rate, num_channels) != OPUS_OK) { - ImplBase::cast_initialization_status_ = - STATUS_INVALID_AUDIO_CONFIGURATION; + ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION; return; } - ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; } private: @@ -169,9 +168,9 @@ CODEC_AUDIO_PCM16, num_channels, sampling_rate) { - if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) return; - ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; } private: @@ -219,10 +218,10 @@ AudioDecoder::~AudioDecoder() {} -CastInitializationStatus AudioDecoder::InitializationResult() const { +OperationalStatus AudioDecoder::InitializationResult() const { if (impl_.get()) return impl_->InitializationResult(); - return STATUS_UNSUPPORTED_AUDIO_CODEC; + return STATUS_UNSUPPORTED_CODEC; } void AudioDecoder::DecodeFrame( @@ -230,8 +229,7 @@ const DecodeFrameCallback& callback) { DCHECK(encoded_frame.get()); DCHECK(!callback.is_null()); - if (!impl_.get() || - impl_->InitializationResult() != STATUS_AUDIO_INITIALIZED) { + if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) { callback.Run(make_scoped_ptr<AudioBus>(NULL), false); return; }
diff --git a/media/cast/receiver/audio_decoder.h b/media/cast/receiver/audio_decoder.h index 0b13eae..a68b6fb 100644 --- a/media/cast/receiver/audio_decoder.h +++ b/media/cast/receiver/audio_decoder.h
@@ -32,10 +32,10 @@ Codec codec); virtual ~AudioDecoder(); - // Returns STATUS_AUDIO_INITIALIZED if the decoder was successfully - // constructed from the given FrameReceiverConfig. If this method returns any - // other value, calls to DecodeFrame() will not succeed. - CastInitializationStatus InitializationResult() const; + // Returns STATUS_INITIALIZED if the decoder was successfully constructed from + // the given FrameReceiverConfig. If this method returns any other value, + // calls to DecodeFrame() will not succeed. + OperationalStatus InitializationResult() const; // Decode the payload in |encoded_frame| asynchronously. |callback| will be // invoked on the CastEnvironment::MAIN thread with the result.
diff --git a/media/cast/receiver/audio_decoder_unittest.cc b/media/cast/receiver/audio_decoder_unittest.cc index ac13af10..6cd4f4e0 100644 --- a/media/cast/receiver/audio_decoder_unittest.cc +++ b/media/cast/receiver/audio_decoder_unittest.cc
@@ -46,7 +46,7 @@ GetParam().num_channels, GetParam().sampling_rate, GetParam().codec)); - CHECK_EQ(STATUS_AUDIO_INITIALIZED, audio_decoder_->InitializationResult()); + CHECK_EQ(STATUS_INITIALIZED, audio_decoder_->InitializationResult()); audio_bus_factory_.reset( new TestAudioBusFactory(GetParam().num_channels,
diff --git a/media/cast/receiver/video_decoder.cc b/media/cast/receiver/video_decoder.cc index d7bed12..a30394c 100644 --- a/media/cast/receiver/video_decoder.cc +++ b/media/cast/receiver/video_decoder.cc
@@ -33,16 +33,16 @@ Codec codec) : cast_environment_(cast_environment), codec_(codec), - cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), + operational_status_(STATUS_UNINITIALIZED), seen_first_frame_(false) {} - CastInitializationStatus InitializationResult() const { - return cast_initialization_status_; + OperationalStatus InitializationResult() const { + return operational_status_; } void DecodeFrame(scoped_ptr<EncodedFrame> encoded_frame, const DecodeFrameCallback& callback) { - DCHECK_EQ(cast_initialization_status_, STATUS_VIDEO_INITIALIZED); + DCHECK_EQ(operational_status_, STATUS_INITIALIZED); static_assert(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_), "size of frame_id types do not match"); @@ -79,8 +79,8 @@ const scoped_refptr<CastEnvironment> cast_environment_; const Codec codec_; - // Subclass' ctor is expected to set this to STATUS_VIDEO_INITIALIZED. - CastInitializationStatus cast_initialization_status_; + // Subclass' ctor is expected to set this to STATUS_INITIALIZED. + OperationalStatus operational_status_; private: bool seen_first_frame_; @@ -93,7 +93,7 @@ public: explicit Vp8Impl(const scoped_refptr<CastEnvironment>& cast_environment) : ImplBase(cast_environment, CODEC_VIDEO_VP8) { - if (ImplBase::cast_initialization_status_ != STATUS_VIDEO_UNINITIALIZED) + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) return; vpx_codec_dec_cfg_t cfg = {0}; @@ -106,16 +106,15 @@ vpx_codec_vp8_dx(), &cfg, VPX_CODEC_USE_POSTPROC) != VPX_CODEC_OK) { - ImplBase::cast_initialization_status_ = - STATUS_INVALID_VIDEO_CONFIGURATION; + ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION; return; } - ImplBase::cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; } private: ~Vp8Impl() override { - if (ImplBase::cast_initialization_status_ == STATUS_VIDEO_INITIALIZED) + if (ImplBase::operational_status_ == STATUS_INITIALIZED) CHECK_EQ(VPX_CODEC_OK, vpx_codec_destroy(&context_)); } @@ -175,9 +174,9 @@ explicit FakeImpl(const scoped_refptr<CastEnvironment>& cast_environment) : ImplBase(cast_environment, CODEC_VIDEO_FAKE), last_decoded_id_(-1) { - if (ImplBase::cast_initialization_status_ != STATUS_VIDEO_UNINITIALIZED) + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) return; - ImplBase::cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; } private: @@ -237,10 +236,10 @@ VideoDecoder::~VideoDecoder() {} -CastInitializationStatus VideoDecoder::InitializationResult() const { +OperationalStatus VideoDecoder::InitializationResult() const { if (impl_.get()) return impl_->InitializationResult(); - return STATUS_UNSUPPORTED_VIDEO_CODEC; + return STATUS_UNSUPPORTED_CODEC; } void VideoDecoder::DecodeFrame( @@ -248,8 +247,7 @@ const DecodeFrameCallback& callback) { DCHECK(encoded_frame.get()); DCHECK(!callback.is_null()); - if (!impl_.get() || - impl_->InitializationResult() != STATUS_VIDEO_INITIALIZED) { + if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) { callback.Run(make_scoped_refptr<VideoFrame>(NULL), false); return; }
diff --git a/media/cast/receiver/video_decoder.h b/media/cast/receiver/video_decoder.h index f3d8ca2..2b6c859 100644 --- a/media/cast/receiver/video_decoder.h +++ b/media/cast/receiver/video_decoder.h
@@ -31,10 +31,10 @@ Codec codec); virtual ~VideoDecoder(); - // Returns STATUS_VIDEO_INITIALIZED if the decoder was successfully - // constructed from the given FrameReceiverConfig. If this method returns any - // other value, calls to DecodeFrame() will not succeed. - CastInitializationStatus InitializationResult() const; + // Returns STATUS_INITIALIZED if the decoder was successfully constructed from + // the given FrameReceiverConfig. If this method returns any other value, + // calls to DecodeFrame() will not succeed. + OperationalStatus InitializationResult() const; // Decode the payload in |encoded_frame| asynchronously. |callback| will be // invoked on the CastEnvironment::MAIN thread with the result.
diff --git a/media/cast/receiver/video_decoder_unittest.cc b/media/cast/receiver/video_decoder_unittest.cc index 6fcde7af..a51ea1d 100644 --- a/media/cast/receiver/video_decoder_unittest.cc +++ b/media/cast/receiver/video_decoder_unittest.cc
@@ -52,7 +52,7 @@ protected: void SetUp() override { video_decoder_.reset(new VideoDecoder(cast_environment_, GetParam())); - CHECK_EQ(STATUS_VIDEO_INITIALIZED, video_decoder_->InitializationResult()); + CHECK_EQ(STATUS_INITIALIZED, video_decoder_->InitializationResult()); next_frame_size_ = gfx::Size(kStartingWidth, kStartingHeight); next_frame_timestamp_ = base::TimeDelta();
diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc index bf41c9e3..588b942 100644 --- a/media/cast/sender/audio_encoder.cc +++ b/media/cast/sender/audio_encoder.cc
@@ -56,7 +56,7 @@ num_channels_(num_channels), samples_per_frame_(samples_per_frame), callback_(callback), - cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), + operational_status_(STATUS_UNINITIALIZED), frame_duration_(base::TimeDelta::FromMicroseconds( base::Time::kMicrosecondsPerSecond * samples_per_frame_ / sampling_rate)), @@ -69,12 +69,12 @@ if (num_channels_ <= 0 || samples_per_frame_ <= 0 || frame_duration_ == base::TimeDelta() || samples_per_frame_ * num_channels_ > kMaxSamplesTimesChannelsPerFrame) { - cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION; + operational_status_ = STATUS_INVALID_CONFIGURATION; } } - CastInitializationStatus InitializationResult() const { - return cast_initialization_status_; + OperationalStatus InitializationResult() const { + return operational_status_; } int samples_per_frame() const { @@ -85,7 +85,7 @@ void EncodeAudio(scoped_ptr<AudioBus> audio_bus, const base::TimeTicks& recorded_time) { - DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED); + DCHECK_EQ(operational_status_, STATUS_INITIALIZED); DCHECK(!recorded_time.is_null()); // Determine whether |recorded_time| is consistent with the amount of audio @@ -169,8 +169,8 @@ const int samples_per_frame_; const FrameEncodedCallback callback_; - // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED. - CastInitializationStatus cast_initialization_status_; + // Subclass' ctor is expected to set this to STATUS_INITIALIZED. + OperationalStatus operational_status_; // The duration of one frame of encoded audio samples. Derived from // |samples_per_frame_| and the sampling rate. @@ -223,7 +223,7 @@ encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]), opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())), buffer_(new float[num_channels * samples_per_frame_]) { - if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED || + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED || sampling_rate % samples_per_frame_ != 0 || !IsValidFrameDuration(frame_duration_)) { return; @@ -232,11 +232,10 @@ sampling_rate, num_channels, OPUS_APPLICATION_AUDIO) != OPUS_OK) { - ImplBase::cast_initialization_status_ = - STATUS_INVALID_AUDIO_CONFIGURATION; + ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION; return; } - ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; if (bitrate <= 0) { // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a @@ -343,15 +342,14 @@ file_(nullptr), num_access_units_(0), can_resume_(true) { - if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) { + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) { return; } if (!Initialize(sampling_rate, bitrate)) { - ImplBase::cast_initialization_status_ = - STATUS_INVALID_AUDIO_CONFIGURATION; + ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION; return; } - ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; + ImplBase::operational_status_ = STATUS_INITIALIZED; } private: @@ -707,9 +705,9 @@ sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */ callback), buffer_(new int16[num_channels * samples_per_frame_]) { - if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) + if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) return; - cast_initialization_status_ = STATUS_AUDIO_INITIALIZED; + operational_status_ = STATUS_INITIALIZED; } private: @@ -787,17 +785,17 @@ AudioEncoder::~AudioEncoder() {} -CastInitializationStatus AudioEncoder::InitializationResult() const { +OperationalStatus AudioEncoder::InitializationResult() const { DCHECK(insert_thread_checker_.CalledOnValidThread()); if (impl_.get()) { return impl_->InitializationResult(); } - return STATUS_UNSUPPORTED_AUDIO_CODEC; + return STATUS_UNSUPPORTED_CODEC; } int AudioEncoder::GetSamplesPerFrame() const { DCHECK(insert_thread_checker_.CalledOnValidThread()); - if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { + if (InitializationResult() != STATUS_INITIALIZED) { NOTREACHED(); return std::numeric_limits<int>::max(); } @@ -806,7 +804,7 @@ base::TimeDelta AudioEncoder::GetFrameDuration() const { DCHECK(insert_thread_checker_.CalledOnValidThread()); - if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { + if (InitializationResult() != STATUS_INITIALIZED) { NOTREACHED(); return base::TimeDelta(); } @@ -817,7 +815,7 @@ const base::TimeTicks& recorded_time) { DCHECK(insert_thread_checker_.CalledOnValidThread()); DCHECK(audio_bus.get()); - if (InitializationResult() != STATUS_AUDIO_INITIALIZED) { + if (InitializationResult() != STATUS_INITIALIZED) { NOTREACHED(); return; }
diff --git a/media/cast/sender/audio_encoder.h b/media/cast/sender/audio_encoder.h index 8c5bafa..e692242 100644 --- a/media/cast/sender/audio_encoder.h +++ b/media/cast/sender/audio_encoder.h
@@ -33,7 +33,7 @@ const FrameEncodedCallback& frame_encoded_callback); virtual ~AudioEncoder(); - CastInitializationStatus InitializationResult() const; + OperationalStatus InitializationResult() const; int GetSamplesPerFrame() const; base::TimeDelta GetFrameDuration() const;
diff --git a/media/cast/sender/audio_sender.cc b/media/cast/sender/audio_sender.cc index 262064f..261a35d 100644 --- a/media/cast/sender/audio_sender.cc +++ b/media/cast/sender/audio_sender.cc
@@ -16,6 +16,7 @@ AudioSender::AudioSender(scoped_refptr<CastEnvironment> cast_environment, const AudioSenderConfig& audio_config, + const StatusChangeCallback& status_change_cb, CastTransportSender* const transport_sender) : FrameSender(cast_environment, true, @@ -29,8 +30,6 @@ NewFixedCongestionControl(audio_config.bitrate)), samples_in_encoder_(0), weak_factory_(this) { - cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED; - if (!audio_config.use_external_encoder) { audio_encoder_.reset( new AudioEncoder(cast_environment, @@ -41,12 +40,18 @@ base::Bind(&AudioSender::OnEncodedAudioFrame, weak_factory_.GetWeakPtr(), audio_config.bitrate))); - cast_initialization_status_ = audio_encoder_->InitializationResult(); - } else { - NOTREACHED(); // No support for external audio encoding. - cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED; } + // AudioEncoder provides no operational status changes during normal use. + // Post a task now with its initialization result status to allow the client + // to start sending frames. + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb, + audio_encoder_ ? audio_encoder_->InitializationResult() : + STATUS_INVALID_CONFIGURATION)); + // The number of samples per encoded audio frame depends on the codec and its // initialization parameters. Now that we have an encoder, we can calculate // the maximum frame rate. @@ -73,11 +78,11 @@ void AudioSender::InsertAudio(scoped_ptr<AudioBus> audio_bus, const base::TimeTicks& recorded_time) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); - if (cast_initialization_status_ != STATUS_AUDIO_INITIALIZED) { + + if (!audio_encoder_) { NOTREACHED(); return; } - DCHECK(audio_encoder_.get()) << "Invalid internal state"; const base::TimeDelta next_frame_duration = RtpDeltaToTimeDelta(audio_bus->frames(), rtp_timebase());
diff --git a/media/cast/sender/audio_sender.h b/media/cast/sender/audio_sender.h index d7f8c694..6148d0e9 100644 --- a/media/cast/sender/audio_sender.h +++ b/media/cast/sender/audio_sender.h
@@ -33,20 +33,14 @@ public: AudioSender(scoped_refptr<CastEnvironment> cast_environment, const AudioSenderConfig& audio_config, + const StatusChangeCallback& status_change_cb, CastTransportSender* const transport_sender); ~AudioSender() override; - CastInitializationStatus InitializationResult() const { - return cast_initialization_status_; - } - // Note: It is not guaranteed that |audio_frame| will actually be encoded and // sent, if AudioSender detects too many frames in flight. Therefore, clients // should be careful about the rate at which this method is called. - // - // Note: It is invalid to call this method if InitializationResult() returns - // anything but STATUS_AUDIO_INITIALIZED. void InsertAudio(scoped_ptr<AudioBus> audio_bus, const base::TimeTicks& recorded_time);
diff --git a/media/cast/sender/audio_sender_unittest.cc b/media/cast/sender/audio_sender_unittest.cc index 7bbfd1a3..0e33da0f 100644 --- a/media/cast/sender/audio_sender_unittest.cc +++ b/media/cast/sender/audio_sender_unittest.cc
@@ -21,6 +21,17 @@ namespace media { namespace cast { +namespace { + +void SaveOperationalStatus(OperationalStatus* out_status, + OperationalStatus in_status) { + DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to " + << in_status; + *out_status = in_status; +} + +} // namespace + class TestPacketSender : public PacketSender { public: TestPacketSender() : number_of_rtp_packets_(0), number_of_rtcp_packets_(0) {} @@ -86,9 +97,14 @@ task_runner_, PacketReceiverCallback(), &transport_)); + OperationalStatus operational_status = STATUS_UNINITIALIZED; audio_sender_.reset(new AudioSender( - cast_environment_, audio_config_, transport_sender_.get())); + cast_environment_, + audio_config_, + base::Bind(&SaveOperationalStatus, &operational_status), + transport_sender_.get())); task_runner_->RunTasks(); + CHECK_EQ(STATUS_INITIALIZED, operational_status); } ~AudioSenderTest() override {}
diff --git a/media/cast/sender/external_video_encoder.cc b/media/cast/sender/external_video_encoder.cc index d09dcfe2..c5685e5 100644 --- a/media/cast/sender/external_video_encoder.cc +++ b/media/cast/sender/external_video_encoder.cc
@@ -63,10 +63,12 @@ const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, scoped_ptr<media::VideoEncodeAccelerator> vea, int max_frame_rate, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) : cast_environment_(cast_environment), task_runner_(encoder_task_runner), max_frame_rate_(max_frame_rate), + status_change_cb_(status_change_cb), create_video_encode_memory_cb_(create_video_encode_memory_cb), video_encode_accelerator_(vea.Pass()), encoder_active_(false), @@ -80,8 +82,7 @@ void Initialize(const gfx::Size& frame_size, VideoCodecProfile codec_profile, - int start_bit_rate, - const CastInitializationCallback& initialization_cb) { + int start_bit_rate) { DCHECK(task_runner_->RunsTasksOnCurrentThread()); DCHECK(!frame_size.IsEmpty()); @@ -95,14 +96,12 @@ UMA_HISTOGRAM_BOOLEAN("Cast.Sender.VideoEncodeAcceleratorInitializeSuccess", encoder_active_); - if (!initialization_cb.is_null()) { - cast_environment_->PostTask( - CastEnvironment::MAIN, - FROM_HERE, - base::Bind(initialization_cb, - encoder_active_ ? STATUS_VIDEO_INITIALIZED : - STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED)); - } + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb_, + encoder_active_ ? STATUS_INITIALIZED : + STATUS_CODEC_INIT_FAILED)); } void SetBitRate(int bit_rate) { @@ -134,11 +133,17 @@ protected: void NotifyError(VideoEncodeAccelerator::Error error) override { DCHECK(task_runner_->RunsTasksOnCurrentThread()); - VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; + + DCHECK(error != VideoEncodeAccelerator::kInvalidArgumentError && + error != VideoEncodeAccelerator::kIllegalStateError); encoder_active_ = false; - // TODO(miu): Plumbing is required to bubble this up to the CastSession and - // beyond. + + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb_, STATUS_CODEC_RUNTIME_ERROR)); + // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so // pending frames do not become stuck, freezing VideoSender. } @@ -281,6 +286,7 @@ const scoped_refptr<CastEnvironment> cast_environment_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const int max_frame_rate_; + const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; bool encoder_active_; @@ -301,7 +307,7 @@ const scoped_refptr<CastEnvironment>& cast_environment, const VideoSenderConfig& video_config, const gfx::Size& frame_size, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) : cast_environment_(cast_environment), @@ -312,6 +318,7 @@ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); DCHECK_GT(video_config.max_frame_rate, 0); DCHECK(!frame_size.IsEmpty()); + DCHECK(!status_change_cb.is_null()); DCHECK(!create_vea_cb.is_null()); DCHECK(!create_video_encode_memory_cb_.is_null()); DCHECK_GT(bit_rate_, 0); @@ -331,7 +338,7 @@ cast_environment_->PostTask( CastEnvironment::MAIN, FROM_HERE, - base::Bind(initialization_cb, STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED)); + base::Bind(status_change_cb, STATUS_UNSUPPORTED_CODEC)); return; } @@ -341,7 +348,7 @@ frame_size, codec_profile, video_config.max_frame_rate, - initialization_cb)); + status_change_cb)); } ExternalVideoEncoder::~ExternalVideoEncoder() { @@ -397,7 +404,7 @@ const gfx::Size& frame_size, VideoCodecProfile codec_profile, int max_frame_rate, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, scoped_ptr<media::VideoEncodeAccelerator> vea) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); @@ -406,12 +413,10 @@ // system does not support or lacks the resources to provide GPU-accelerated // video encoding. if (!encoder_task_runner || !vea) { - if (!initialization_cb.is_null()) { - cast_environment_->PostTask( - CastEnvironment::MAIN, - FROM_HERE, - base::Bind(initialization_cb, STATUS_INVALID_VIDEO_CONFIGURATION)); - } + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb, STATUS_CODEC_INIT_FAILED)); return; } @@ -420,14 +425,14 @@ encoder_task_runner, vea.Pass(), max_frame_rate, + status_change_cb, create_video_encode_memory_cb_); client_->task_runner()->PostTask(FROM_HERE, base::Bind(&VEAClientImpl::Initialize, client_, frame_size, codec_profile, - bit_rate_, - initialization_cb)); + bit_rate_)); } } // namespace cast
diff --git a/media/cast/sender/external_video_encoder.h b/media/cast/sender/external_video_encoder.h index 105a3ae..e560c575 100644 --- a/media/cast/sender/external_video_encoder.h +++ b/media/cast/sender/external_video_encoder.h
@@ -25,7 +25,7 @@ const scoped_refptr<CastEnvironment>& cast_environment, const VideoSenderConfig& video_config, const gfx::Size& frame_size, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb); @@ -51,7 +51,7 @@ const gfx::Size& frame_size, VideoCodecProfile codec_profile, int max_frame_rate, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, scoped_ptr<media::VideoEncodeAccelerator> vea);
diff --git a/media/cast/sender/external_video_encoder_unittest.cc b/media/cast/sender/external_video_encoder_unittest.cc index 2518a40..0ade1ed 100644 --- a/media/cast/sender/external_video_encoder_unittest.cc +++ b/media/cast/sender/external_video_encoder_unittest.cc
@@ -80,7 +80,7 @@ task_runner_, task_runner_)), vea_factory_(task_runner_), - init_status_(STATUS_VIDEO_UNINITIALIZED), + operational_status_(STATUS_UNINITIALIZED), test_video_encoder_callback_(new TestVideoEncoderCallback()) { testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); @@ -105,7 +105,7 @@ cast_environment_, video_config_, size, - base::Bind(&ExternalVideoEncoderTest::SaveInitializationStatus, + base::Bind(&ExternalVideoEncoderTest::SaveOperationalStatus, base::Unretained(this)), base::Bind( &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator, @@ -122,16 +122,16 @@ video_frame_->timestamp() + base::TimeDelta::FromMilliseconds(33)); } - void SaveInitializationStatus(CastInitializationStatus result) { - EXPECT_EQ(STATUS_VIDEO_UNINITIALIZED, init_status_); - init_status_ = result; + void SaveOperationalStatus(OperationalStatus result) { + EXPECT_EQ(STATUS_UNINITIALIZED, operational_status_); + operational_status_ = result; } base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; const scoped_refptr<CastEnvironment> cast_environment_; FakeVideoEncodeAcceleratorFactory vea_factory_; - CastInitializationStatus init_status_; + OperationalStatus operational_status_; scoped_refptr<TestVideoEncoderCallback> test_video_encoder_callback_; VideoSenderConfig video_config_; scoped_ptr<VideoEncoder> video_encoder_; @@ -143,7 +143,7 @@ TEST_F(ExternalVideoEncoderTest, EncodePattern30fpsRunningOutOfAck) { vea_factory_.SetAutoRespond(true); task_runner_->RunTasks(); // Run the initializer on the correct thread. - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, init_status_); + EXPECT_EQ(STATUS_INITIALIZED, operational_status_); VideoEncoder::FrameEncodedCallback frame_encoded_callback = base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, @@ -183,7 +183,7 @@ TEST_F(ExternalVideoEncoderTest, StreamHeader) { vea_factory_.SetAutoRespond(true); task_runner_->RunTasks(); // Run the initializer on the correct thread. - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, init_status_); + EXPECT_EQ(STATUS_INITIALIZED, operational_status_); VideoEncoder::FrameEncodedCallback frame_encoded_callback = base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, @@ -216,7 +216,7 @@ vea_factory_.SetAutoRespond(true); task_runner_->RunTasks(); EXPECT_EQ(1, vea_factory_.vea_response_count()); - EXPECT_EQ(STATUS_VIDEO_UNINITIALIZED, init_status_); + EXPECT_EQ(STATUS_UNINITIALIZED, operational_status_); } } // namespace cast
diff --git a/media/cast/sender/frame_sender.h b/media/cast/sender/frame_sender.h index a3ef1e5..c4aef58 100644 --- a/media/cast/sender/frame_sender.h +++ b/media/cast/sender/frame_sender.h
@@ -150,10 +150,6 @@ // case, VideoSender will trigger a re-send of the next frame. int duplicate_ack_counter_; - // If this sender is ready for use, this is STATUS_AUDIO_INITIALIZED or - // STATUS_VIDEO_INITIALIZED. - CastInitializationStatus cast_initialization_status_; - // This object controls how we change the bitrate to make sure the // buffer doesn't overflow. scoped_ptr<CongestionControl> congestion_control_;
diff --git a/media/cast/sender/h264_vt_encoder.cc b/media/cast/sender/h264_vt_encoder.cc index 5d19284..364a416 100644 --- a/media/cast/sender/h264_vt_encoder.cc +++ b/media/cast/sender/h264_vt_encoder.cc
@@ -227,29 +227,25 @@ const scoped_refptr<CastEnvironment>& cast_environment, const VideoSenderConfig& video_config, const gfx::Size& frame_size, - const CastInitializationCallback& initialization_cb) + const StatusChangeCallback& status_change_cb) : cast_environment_(cast_environment), - videotoolbox_glue_(VideoToolboxGlue::Get()), frame_id_(kStartFrameId), encode_next_frame_as_keyframe_(false) { DCHECK(!frame_size.IsEmpty()); + DCHECK(!status_change_cb.is_null()); - CastInitializationStatus initialization_status; - if (videotoolbox_glue_) { - initialization_status = (Initialize(video_config, frame_size)) - ? STATUS_VIDEO_INITIALIZED - : STATUS_INVALID_VIDEO_CONFIGURATION; + OperationalStatus operational_status; + if (video_config.codec == CODEC_VIDEO_H264 && videotoolbox_glue_) { + operational_status = Initialize(video_config, frame_size) ? + STATUS_INITIALIZED : STATUS_INVALID_CONFIGURATION; } else { - LOG(ERROR) << " VideoToolbox is not available"; - initialization_status = STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED; + operational_status = STATUS_UNSUPPORTED_CODEC; } - if (!initialization_cb.is_null()) { - cast_environment_->PostTask( - CastEnvironment::MAIN, - FROM_HERE, - base::Bind(initialization_cb, initialization_status)); - } + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb, operational_status)); } H264VideoToolboxEncoder::~H264VideoToolboxEncoder() {
diff --git a/media/cast/sender/h264_vt_encoder.h b/media/cast/sender/h264_vt_encoder.h index 68f53f1d..349075a5 100644 --- a/media/cast/sender/h264_vt_encoder.h +++ b/media/cast/sender/h264_vt_encoder.h
@@ -26,7 +26,7 @@ const scoped_refptr<CastEnvironment>& cast_environment, const VideoSenderConfig& video_config, const gfx::Size& frame_size, - const CastInitializationCallback& initialization_cb); + const StatusChangeCallback& status_change_cb); ~H264VideoToolboxEncoder() override; // media::cast::VideoEncoder implementation
diff --git a/media/cast/sender/h264_vt_encoder_unittest.cc b/media/cast/sender/h264_vt_encoder_unittest.cc index e2dc073..78012eb7 100644 --- a/media/cast/sender/h264_vt_encoder_unittest.cc +++ b/media/cast/sender/h264_vt_encoder_unittest.cc
@@ -67,8 +67,8 @@ *out_status = in_status; } -void SaveInitializationStatus(CastInitializationStatus* out_status, - CastInitializationStatus in_status) { +void SaveOperationalStatus(OperationalStatus* out_status, + OperationalStatus in_status) { *out_status = in_status; } @@ -190,8 +190,8 @@ class H264VideoToolboxEncoderTest : public ::testing::Test { protected: - H264VideoToolboxEncoderTest() { - cast_initialization_status_ = STATUS_VIDEO_UNINITIALIZED; + H264VideoToolboxEncoderTest() + : operational_status_(STATUS_UNINITIALIZED) { frame_->set_timestamp(base::TimeDelta()); } @@ -207,9 +207,9 @@ cast_environment_, video_sender_config_, gfx::Size(kVideoWidth, kVideoHeight), - base::Bind(&SaveInitializationStatus, &cast_initialization_status_))); + base::Bind(&SaveOperationalStatus, &operational_status_))); message_loop_.RunUntilIdle(); - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, cast_initialization_status_); + EXPECT_EQ(STATUS_INITIALIZED, operational_status_); } void TearDown() override { @@ -242,7 +242,7 @@ base::MessageLoop message_loop_; scoped_refptr<CastEnvironment> cast_environment_; scoped_ptr<VideoEncoder> encoder_; - CastInitializationStatus cast_initialization_status_; + OperationalStatus operational_status_; private: DISALLOW_COPY_AND_ASSIGN(H264VideoToolboxEncoderTest);
diff --git a/media/cast/sender/video_encoder_impl.cc b/media/cast/sender/video_encoder_impl.cc index 4efe3204..a2b0da90 100644 --- a/media/cast/sender/video_encoder_impl.cc +++ b/media/cast/sender/video_encoder_impl.cc
@@ -55,9 +55,11 @@ VideoEncoderImpl::VideoEncoderImpl( scoped_refptr<CastEnvironment> cast_environment, const VideoSenderConfig& video_config, - const CastInitializationCallback& initialization_cb) + const StatusChangeCallback& status_change_cb) : cast_environment_(cast_environment) { CHECK(cast_environment_->HasVideoThread()); + DCHECK(!status_change_cb.is_null()); + if (video_config.codec == CODEC_VIDEO_VP8) { encoder_.reset(new Vp8Encoder(video_config)); cast_environment_->PostTask(CastEnvironment::VIDEO, @@ -77,14 +79,12 @@ dynamic_config_.latest_frame_id_to_reference = kStartFrameId; dynamic_config_.bit_rate = video_config.start_bitrate; - if (!initialization_cb.is_null()) { - cast_environment_->PostTask( - CastEnvironment::MAIN, - FROM_HERE, - base::Bind(initialization_cb, - encoder_.get() ? STATUS_VIDEO_INITIALIZED : - STATUS_UNSUPPORTED_VIDEO_CODEC)); - } + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb, + encoder_.get() ? STATUS_INITIALIZED : + STATUS_UNSUPPORTED_CODEC)); } VideoEncoderImpl::~VideoEncoderImpl() {
diff --git a/media/cast/sender/video_encoder_impl.h b/media/cast/sender/video_encoder_impl.h index eb4dbe36..07ed999 100644 --- a/media/cast/sender/video_encoder_impl.h +++ b/media/cast/sender/video_encoder_impl.h
@@ -31,7 +31,7 @@ VideoEncoderImpl(scoped_refptr<CastEnvironment> cast_environment, const VideoSenderConfig& video_config, - const CastInitializationCallback& initialization_cb); + const StatusChangeCallback& status_change_cb); ~VideoEncoderImpl() override;
diff --git a/media/cast/sender/video_encoder_impl_unittest.cc b/media/cast/sender/video_encoder_impl_unittest.cc index bd62846..dab16ea 100644 --- a/media/cast/sender/video_encoder_impl_unittest.cc +++ b/media/cast/sender/video_encoder_impl_unittest.cc
@@ -30,6 +30,7 @@ task_runner_, task_runner_)), video_config_(GetDefaultVideoSenderConfig()), + operational_status_(STATUS_UNINITIALIZED), count_frames_delivered_(0) { testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); first_frame_time_ = testing_clock_->NowTicks(); @@ -47,13 +48,16 @@ } void CreateEncoder(bool three_buffer_mode) { + ASSERT_EQ(STATUS_UNINITIALIZED, operational_status_); video_config_.max_number_of_video_buffers_used = (three_buffer_mode ? 3 : 1); video_encoder_.reset(new VideoEncoderImpl( cast_environment_, video_config_, - CastInitializationCallback())); + base::Bind(&VideoEncoderImplTest::OnOperationalStatusChange, + base::Unretained(this)))); task_runner_->RunTasks(); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); } VideoEncoder* video_encoder() const { @@ -103,6 +107,10 @@ } private: + void OnOperationalStatusChange(OperationalStatus status) { + operational_status_ = status; + } + // Checks that |encoded_frame| matches expected values. This is the method // bound in the callback returned from CreateFrameDeliverCallback(). void DeliverEncodedVideoFrame( @@ -131,6 +139,7 @@ const scoped_refptr<CastEnvironment> cast_environment_; VideoSenderConfig video_config_; base::TimeTicks first_frame_time_; + OperationalStatus operational_status_; scoped_ptr<VideoEncoder> video_encoder_; int count_frames_delivered_;
diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc index c900187..54e474c4 100644 --- a/media/cast/sender/video_sender.cc +++ b/media/cast/sender/video_sender.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" #include "base/trace_event/trace_event.h" #include "media/cast/cast_defines.h" #include "media/cast/net/cast_transport_config.h" @@ -46,7 +45,7 @@ VideoSender::VideoSender( scoped_refptr<CastEnvironment> cast_environment, const VideoSenderConfig& video_config, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, CastTransportSender* const transport_sender, @@ -72,8 +71,6 @@ last_bitrate_(0), playout_delay_change_cb_(playout_delay_change_cb), weak_factory_(this) { - cast_initialization_status_ = STATUS_VIDEO_UNINITIALIZED; - #if defined(OS_MACOSX) // On Apple platforms, use the hardware H.264 encoder if possible. It is the // only reasonable option for iOS. @@ -83,9 +80,7 @@ cast_environment, video_config, gfx::Size(video_config.width, video_config.height), - base::Bind(&VideoSender::OnEncoderInitialized, - weak_factory_.GetWeakPtr(), - initialization_cb))); + status_change_cb)); } #endif // defined(OS_MACOSX) #if !defined(OS_IOS) @@ -94,18 +89,23 @@ cast_environment, video_config, gfx::Size(video_config.width, video_config.height), - base::Bind(&VideoSender::OnEncoderInitialized, - weak_factory_.GetWeakPtr(), initialization_cb), + status_change_cb, create_vea_cb, create_video_encode_mem_cb)); } else if (!video_encoder_) { // Software encoder is initialized immediately. video_encoder_.reset(new VideoEncoderImpl( - cast_environment, video_config, initialization_cb)); - cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; + cast_environment, video_config, status_change_cb)); } #endif // !defined(OS_IOS) + if (!video_encoder_) { + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(status_change_cb, STATUS_UNSUPPORTED_CODEC)); + } + media::cast::CastTransportRtpConfig transport_config; transport_config.ssrc = video_config.ssrc; transport_config.feedback_ssrc = video_config.receiver_ssrc; @@ -128,11 +128,11 @@ const scoped_refptr<media::VideoFrame>& video_frame, const base::TimeTicks& reference_time) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); - if (cast_initialization_status_ != STATUS_VIDEO_INITIALIZED) { + + if (!video_encoder_) { NOTREACHED(); return; } - DCHECK(video_encoder_.get()) << "Invalid state"; const RtpTimestamp rtp_timestamp = TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency); @@ -218,9 +218,7 @@ } scoped_ptr<VideoFrameFactory> VideoSender::CreateVideoFrameFactory() { - DCHECK(cast_initialization_status_ == STATUS_VIDEO_INITIALIZED); - DCHECK(video_encoder_.get()) << "Invalid state"; - return video_encoder_->CreateVideoFrameFactory(); + return video_encoder_ ? video_encoder_->CreateVideoFrameFactory() : nullptr; } int VideoSender::GetNumberOfFramesInEncoder() const { @@ -241,13 +239,6 @@ video_encoder_->LatestFrameIdToReference(frame_id); } -void VideoSender::OnEncoderInitialized( - const CastInitializationCallback& initialization_cb, - CastInitializationStatus status) { - cast_initialization_status_ = status; - initialization_cb.Run(status); -} - void VideoSender::OnEncodedVideoFrame( int encoder_bitrate, scoped_ptr<EncodedFrame> encoded_frame) {
diff --git a/media/cast/sender/video_sender.h b/media/cast/sender/video_sender.h index 506700d6..0cb25fd 100644 --- a/media/cast/sender/video_sender.h +++ b/media/cast/sender/video_sender.h
@@ -40,7 +40,7 @@ public: VideoSender(scoped_refptr<CastEnvironment> cast_environment, const VideoSenderConfig& video_config, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, CastTransportSender* const transport_sender, @@ -51,9 +51,6 @@ // Note: It is not guaranteed that |video_frame| will actually be encoded and // sent, if VideoSender detects too many frames in flight. Therefore, clients // should be careful about the rate at which this method is called. - // - // Note: It is invalid to call this method if InitializationResult() returns - // anything but STATUS_VIDEO_INITIALIZED. void InsertRawVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, const base::TimeTicks& reference_time); @@ -68,11 +65,6 @@ void OnAck(uint32 frame_id) override; private: - // Called when the encoder is initialized or has failed to initialize. - void OnEncoderInitialized( - const CastInitializationCallback& initialization_cb, - CastInitializationStatus status); - // Called by the |video_encoder_| with the next EncodedFrame to send. void OnEncodedVideoFrame(int encoder_bitrate, scoped_ptr<EncodedFrame> encoded_frame);
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index 5c207d5..6c0ba989 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc
@@ -52,8 +52,10 @@ callback.Run(shm.Pass()); } -void SaveInitializationStatus(CastInitializationStatus* out_status, - CastInitializationStatus in_status) { +void SaveOperationalStatus(OperationalStatus* out_status, + OperationalStatus in_status) { + DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to " + << in_status; *out_status = in_status; } @@ -111,18 +113,19 @@ void IgnorePlayoutDelayChanges(base::TimeDelta unused_playout_delay) { } + class PeerVideoSender : public VideoSender { public: PeerVideoSender( scoped_refptr<CastEnvironment> cast_environment, const VideoSenderConfig& video_config, - const CastInitializationCallback& initialization_cb, + const StatusChangeCallback& status_change_cb, const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, CastTransportSender* const transport_sender) : VideoSender(cast_environment, video_config, - initialization_cb, + status_change_cb, create_vea_cb, create_video_encode_mem_cb, transport_sender, @@ -134,15 +137,16 @@ class VideoSenderTest : public ::testing::Test { protected: VideoSenderTest() - : stored_bitrates_(NULL) { - testing_clock_ = new base::SimpleTestTickClock(); + : testing_clock_(new base::SimpleTestTickClock()), + task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), + cast_environment_(new CastEnvironment( + scoped_ptr<base::TickClock>(testing_clock_).Pass(), + task_runner_, + task_runner_, + task_runner_)), + operational_status_(STATUS_UNINITIALIZED), + stored_bitrates_(NULL) { testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); - task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); - cast_environment_ = - new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), - task_runner_, - task_runner_, - task_runner_); last_pixel_value_ = kPixelValue; net::IPEndPoint dummy_endpoint; transport_sender_.reset(new CastTransportSenderImpl( @@ -172,8 +176,7 @@ // If |external| is true then external video encoder (VEA) is used. // |expect_init_sucess| is true if initialization is expected to succeed. - CastInitializationStatus InitEncoder(bool external, - bool expect_init_success) { + void InitEncoder(bool external, bool expect_init_success) { VideoSenderConfig video_config; video_config.ssrc = 1; video_config.receiver_ssrc = 2; @@ -189,7 +192,8 @@ video_config.max_frame_rate = 30; video_config.max_number_of_video_buffers_used = 1; video_config.codec = CODEC_VIDEO_VP8; - CastInitializationStatus status = STATUS_VIDEO_UNINITIALIZED; + + ASSERT_EQ(operational_status_, STATUS_UNINITIALIZED); if (external) { media::FakeVideoEncodeAccelerator* fake_vea = @@ -200,8 +204,8 @@ video_sender_.reset( new PeerVideoSender(cast_environment_, video_config, - base::Bind(&SaveInitializationStatus, - &status), + base::Bind(&SaveOperationalStatus, + &operational_status_), base::Bind(&CreateVideoEncodeAccelerator, task_runner_, base::Passed(&fake_vea_owner)), @@ -211,14 +215,13 @@ video_sender_.reset( new PeerVideoSender(cast_environment_, video_config, - base::Bind(&SaveInitializationStatus, - &status), + base::Bind(&SaveOperationalStatus, + &operational_status_), CreateDefaultVideoEncodeAcceleratorCallback(), CreateDefaultVideoEncodeMemoryCallback(), transport_sender_.get())); } task_runner_->RunTasks(); - return status; } scoped_refptr<media::VideoFrame> GetNewVideoFrame() { @@ -249,13 +252,14 @@ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms)); } - base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. + base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. + const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; + const scoped_refptr<CastEnvironment> cast_environment_; + OperationalStatus operational_status_; TestPacketSender transport_; scoped_ptr<CastTransportSenderImpl> transport_sender_; - scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; scoped_ptr<PeerVideoSender> video_sender_; const std::vector<uint32>* stored_bitrates_; // Owned by |video_sender_|. - scoped_refptr<CastEnvironment> cast_environment_; int last_pixel_value_; base::TimeTicks first_frame_timestamp_; @@ -263,7 +267,9 @@ }; TEST_F(VideoSenderTest, BuiltInEncoder) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); const base::TimeTicks reference_time = testing_clock_->NowTicks(); @@ -275,7 +281,8 @@ } TEST_F(VideoSenderTest, ExternalEncoder) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(true, true)); + InitEncoder(true, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); @@ -295,14 +302,16 @@ } TEST_F(VideoSenderTest, ExternalEncoderInitFails) { - EXPECT_EQ(STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED, - InitEncoder(true, false)); + InitEncoder(true, false); + EXPECT_EQ(STATUS_CODEC_INIT_FAILED, operational_status_); + video_sender_.reset(NULL); task_runner_->RunTasks(); } TEST_F(VideoSenderTest, RtcpTimer) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); @@ -326,7 +335,8 @@ } TEST_F(VideoSenderTest, ResendTimer) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); @@ -354,7 +364,9 @@ } TEST_F(VideoSenderTest, LogAckReceivedEvent) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + SimpleEventSubscriber event_subscriber; cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber); @@ -386,7 +398,9 @@ } TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + // Send a stream of frames and don't ACK; by default we shouldn't have more // than 4 frames in flight. scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); @@ -432,7 +446,9 @@ } TEST_F(VideoSenderTest, DuplicateAckRetransmit) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); RunTasks(33); @@ -472,7 +488,9 @@ } TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); RunTasks(33); @@ -523,7 +541,9 @@ } TEST_F(VideoSenderTest, AcksCancelRetransmits) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + transport_.SetPause(true); scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame(); video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); @@ -541,7 +561,9 @@ } TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, InitEncoder(false, true)); + InitEncoder(false, true); + ASSERT_EQ(STATUS_INITIALIZED, operational_status_); + EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get()); }
diff --git a/media/cast/test/cast_benchmarks.cc b/media/cast/test/cast_benchmarks.cc index 8ef123e5..aa89e94 100644 --- a/media/cast/test/cast_benchmarks.cc +++ b/media/cast/test/cast_benchmarks.cc
@@ -32,6 +32,8 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/debug/profiler.h" +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -81,12 +83,10 @@ EXPECT_TRUE(result); } -void AudioInitializationStatus(CastInitializationStatus status) { - EXPECT_EQ(STATUS_AUDIO_INITIALIZED, status); -} - -void VideoInitializationStatus(CastInitializationStatus status) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, status); +void ExpectSuccessAndRunCallback(const base::Closure& done_cb, + OperationalStatus status) { + EXPECT_EQ(STATUS_INITIALIZED, status); + done_cb.Run(); } void IgnoreRawEvents(const std::vector<PacketEvent>& packet_events, @@ -346,13 +346,22 @@ cast_sender_ = CastSender::Create(cast_environment_sender_, &transport_sender_); - // Initializing audio and video senders. - cast_sender_->InitializeAudio(audio_sender_config_, - base::Bind(&AudioInitializationStatus)); - cast_sender_->InitializeVideo(video_sender_config_, - base::Bind(&VideoInitializationStatus), - CreateDefaultVideoEncodeAcceleratorCallback(), - CreateDefaultVideoEncodeMemoryCallback()); + // Initializing audio and video senders. The funny dance here is to + // synchronize on the asynchronous initialization process. + base::RunLoop run_loop; + base::WeakPtrFactory<RunOneBenchmark> weak_factory(this); + cast_sender_->InitializeAudio( + audio_sender_config_, + base::Bind(&ExpectSuccessAndRunCallback, run_loop.QuitClosure())); + run_loop.Run(); // Wait for quit closure to run. + weak_factory.InvalidateWeakPtrs(); + cast_sender_->InitializeVideo( + video_sender_config_, + base::Bind(&ExpectSuccessAndRunCallback, run_loop.QuitClosure()), + CreateDefaultVideoEncodeAcceleratorCallback(), + CreateDefaultVideoEncodeMemoryCallback()); + run_loop.Run(); // Wait for quit closure to run. + weak_factory.InvalidateWeakPtrs(); receiver_to_sender_.Initialize( CreateSimplePipe(p).Pass(),
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index 46b5d7171..e7a0c147 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc
@@ -103,12 +103,8 @@ EXPECT_TRUE(result); } -void AudioInitializationStatus(CastInitializationStatus status) { - EXPECT_EQ(STATUS_AUDIO_INITIALIZED, status); -} - -void VideoInitializationStatus(CastInitializationStatus status) { - EXPECT_EQ(STATUS_VIDEO_INITIALIZED, status); +void ExpectSuccessOperationalStatus(OperationalStatus status) { + EXPECT_EQ(STATUS_INITIALIZED, status); } // This is wrapped in a struct because it needs to be put into a std::map. @@ -624,12 +620,14 @@ CastSender::Create(cast_environment_sender_, transport_sender_.get()); // Initializing audio and video senders. - cast_sender_->InitializeAudio(audio_sender_config_, - base::Bind(&AudioInitializationStatus)); - cast_sender_->InitializeVideo(video_sender_config_, - base::Bind(&VideoInitializationStatus), - CreateDefaultVideoEncodeAcceleratorCallback(), - CreateDefaultVideoEncodeMemoryCallback()); + cast_sender_->InitializeAudio( + audio_sender_config_, + base::Bind(&ExpectSuccessOperationalStatus)); + cast_sender_->InitializeVideo( + video_sender_config_, + base::Bind(&ExpectSuccessOperationalStatus), + CreateDefaultVideoEncodeAcceleratorCallback(), + CreateDefaultVideoEncodeMemoryCallback()); task_runner_->RunTasks(); receiver_to_sender_.SetPacketReceiver(
diff --git a/media/cast/test/fake_media_source.cc b/media/cast/test/fake_media_source.cc index f17a053..061478d3 100644 --- a/media/cast/test/fake_media_source.cc +++ b/media/cast/test/fake_media_source.cc
@@ -15,7 +15,6 @@ #include "media/base/audio_fifo.h" #include "media/base/audio_timestamp_helper.h" #include "media/base/media.h" -#include "media/base/multi_channel_resampler.h" #include "media/base/video_frame.h" #include "media/base/video_util.h" #include "media/cast/cast_sender.h" @@ -31,8 +30,6 @@ namespace { -static const int kAudioChannels = 2; -static const int kAudioSamplingFrequency = 48000; static const int kSoundFrequency = 440; // Frequency of sinusoid wave. static const float kSoundVolume = 0.10f; static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms. @@ -69,9 +66,15 @@ FakeMediaSource::FakeMediaSource( scoped_refptr<base::SingleThreadTaskRunner> task_runner, base::TickClock* clock, + const AudioSenderConfig& audio_config, const VideoSenderConfig& video_config, bool keep_frames) : task_runner_(task_runner), + output_audio_params_(AudioParameters::AUDIO_PCM_LINEAR, + media::GuessChannelLayout(audio_config.channels), + audio_config.frequency, + 32, + audio_config.frequency / kAudioPacketsPerSecond), video_config_(video_config), keep_frames_(keep_frames), variable_frame_size_mode_(false), @@ -88,8 +91,9 @@ video_first_pts_(0), video_first_pts_set_(false), weak_factory_(this) { - audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, - kAudioSamplingFrequency, + CHECK(output_audio_params_.IsValid()); + audio_bus_factory_.reset(new TestAudioBusFactory(audio_config.channels, + audio_config.frequency, kSoundFrequency, kSoundVolume)); } @@ -161,13 +165,14 @@ LOG(WARNING) << "Found multiple audio streams."; } audio_stream_index_ = static_cast<int>(i); - audio_params_.Reset( + source_audio_params_.Reset( AudioParameters::AUDIO_PCM_LINEAR, layout, av_codec_context->channels, av_codec_context->sample_rate, 8 * av_get_bytes_per_sample(av_codec_context->sample_fmt), av_codec_context->sample_rate / kAudioPacketsPerSecond); + CHECK(source_audio_params_.IsValid()); LOG(INFO) << "Source file has audio."; } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { VideoFrame::Format format = @@ -228,21 +233,18 @@ } // Send transcoding streams. - audio_algo_.Initialize(audio_params_); + audio_algo_.Initialize(source_audio_params_); audio_algo_.FlushBuffers(); - audio_fifo_input_bus_ = - AudioBus::Create( - audio_params_.channels(), audio_params_.frames_per_buffer()); + audio_fifo_input_bus_ = AudioBus::Create( + source_audio_params_.channels(), + source_audio_params_.frames_per_buffer()); // Audio FIFO can carry all data fron AudioRendererAlgorithm. audio_fifo_.reset( - new AudioFifo(audio_params_.channels(), + new AudioFifo(source_audio_params_.channels(), audio_algo_.QueueCapacity())); - audio_resampler_.reset(new media::MultiChannelResampler( - audio_params_.channels(), - static_cast<double>(audio_params_.sample_rate()) / - kAudioSamplingFrequency, - audio_params_.frames_per_buffer(), - base::Bind(&FakeMediaSource::ProvideData, weak_factory_.GetWeakPtr()))); + audio_converter_.reset(new media::AudioConverter( + source_audio_params_, output_audio_params_, true)); + audio_converter_->AddInput(this); task_runner_->PostTask( FROM_HERE, base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr())); @@ -462,7 +464,7 @@ // Not the frequency of the source file. This is because we // increment the frame count by samples we sent. audio_sent_ts_.reset( - new AudioTimestampHelper(kAudioSamplingFrequency)); + new AudioTimestampHelper(output_audio_params_.sample_rate())); // For some files this is an invalid value. base::TimeDelta base_ts; audio_sent_ts_->SetBaseTimestamp(base_ts); @@ -506,16 +508,15 @@ // Make sure there's enough data to resample audio. if (audio_fifo_->frames() < - 2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) { + 2 * source_audio_params_.sample_rate() / kAudioPacketsPerSecond) { continue; } scoped_ptr<media::AudioBus> resampled_bus( media::AudioBus::Create( - audio_params_.channels(), - kAudioSamplingFrequency / kAudioPacketsPerSecond)); - audio_resampler_->Resample(resampled_bus->frames(), - resampled_bus.get()); + output_audio_params_.channels(), + output_audio_params_.sample_rate() / kAudioPacketsPerSecond)); + audio_converter_->Convert(resampled_bus.get()); audio_bus_queue_.push(resampled_bus.release()); } } @@ -588,13 +589,15 @@ } } -void FakeMediaSource::ProvideData(int frame_delay, - media::AudioBus* output_bus) { +double FakeMediaSource::ProvideInput(media::AudioBus* output_bus, + base::TimeDelta buffer_delay) { if (audio_fifo_->frames() >= output_bus->frames()) { audio_fifo_->Consume(output_bus, 0, output_bus->frames()); + return 1.0; } else { LOG(WARNING) << "Not enough audio data for resampling."; output_bus->Zero(); + return 0.0; } }
diff --git a/media/cast/test/fake_media_source.h b/media/cast/test/fake_media_source.h index ef5aa862..f7fc36a 100644 --- a/media/cast/test/fake_media_source.h +++ b/media/cast/test/fake_media_source.h
@@ -19,6 +19,7 @@ #include "base/single_thread_task_runner.h" #include "base/time/tick_clock.h" #include "media/audio/audio_parameters.h" +#include "media/base/audio_converter.h" #include "media/cast/cast_config.h" #include "media/filters/audio_renderer_algorithm.h" #include "media/filters/ffmpeg_demuxer.h" @@ -29,11 +30,11 @@ namespace media { class AudioBus; +class AudioConverter; class AudioFifo; class AudioTimestampHelper; class FFmpegGlue; class InMemoryUrlProtocol; -class MultiChannelResampler; namespace cast { @@ -41,17 +42,19 @@ class VideoFrameInput; class TestAudioBusFactory; -class FakeMediaSource { +class FakeMediaSource : public media::AudioConverter::InputCallback { public: // |task_runner| is to schedule decoding tasks. // |clock| is used by this source but is not owned. + // |audio_config| is the desired audio config. // |video_config| is the desired video config. // |keep_frames| is true if all VideoFrames are saved in a queue. FakeMediaSource(scoped_refptr<base::SingleThreadTaskRunner> task_runner, base::TickClock* clock, + const AudioSenderConfig& audio_config, const VideoSenderConfig& video_config, bool keep_frames); - ~FakeMediaSource(); + ~FakeMediaSource() override; // Transcode this file as the source of video and audio frames. // If |override_fps| is non zero then the file is played at the desired rate. @@ -100,7 +103,9 @@ void DecodeVideo(ScopedAVPacket packet); void Decode(bool decode_audio); - void ProvideData(int frame_delay, media::AudioBus* output_bus); + // media::AudioConverter::InputCallback implementation. + double ProvideInput(media::AudioBus* output_bus, base::TimeDelta buffer_delay) + override; AVStream* av_audio_stream(); AVStream* av_video_stream(); @@ -108,6 +113,7 @@ AVCodecContext* av_video_context(); const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const media::AudioParameters output_audio_params_; const VideoSenderConfig video_config_; const bool keep_frames_; bool variable_frame_size_mode_; @@ -132,7 +138,7 @@ AVFormatContext* av_format_context_; int audio_stream_index_; - AudioParameters audio_params_; + AudioParameters source_audio_params_; double playback_rate_; int video_stream_index_; @@ -140,7 +146,7 @@ int video_frame_rate_denominator_; // These are used for audio resampling. - scoped_ptr<media::MultiChannelResampler> audio_resampler_; + scoped_ptr<media::AudioConverter> audio_converter_; scoped_ptr<media::AudioFifo> audio_fifo_; scoped_ptr<media::AudioBus> audio_fifo_input_bus_; media::AudioRendererAlgorithm audio_algo_;
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc index 7e6fd38a..686efa8 100644 --- a/media/cast/test/sender.cc +++ b/media/cast/test/sender.cc
@@ -101,10 +101,8 @@ } } -void QuitLoopOnInitializationResult( - media::cast::CastInitializationStatus result) { - CHECK(result == media::cast::STATUS_AUDIO_INITIALIZED || - result == media::cast::STATUS_VIDEO_INITIALIZED) +void QuitLoopOnInitializationResult(media::cast::OperationalStatus result) { + CHECK(result == media::cast::STATUS_INITIALIZED) << "Cast sender uninitialized"; base::MessageLoop::current()->Quit(); } @@ -259,7 +257,9 @@ scoped_ptr<media::cast::FakeMediaSource> fake_media_source( new media::cast::FakeMediaSource(test_thread.message_loop_proxy(), cast_environment->Clock(), - video_config, false)); + audio_config, + video_config, + false)); int override_fps = 0; if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps),
diff --git a/media/cast/test/simulator.cc b/media/cast/test/simulator.cc index 1e01085..9b8cc054 100644 --- a/media/cast/test/simulator.cc +++ b/media/cast/test/simulator.cc
@@ -113,11 +113,11 @@ LOG(INFO) << "Cast transport status: " << status; } -void AudioInitializationStatus(CastInitializationStatus status) { +void LogAudioOperationalStatus(OperationalStatus status) { LOG(INFO) << "Audio status: " << status; } -void VideoInitializationStatus(CastInitializationStatus status) { +void LogVideoOperationalStatus(OperationalStatus status) { LOG(INFO) << "Video status: " << status; } @@ -480,6 +480,7 @@ const bool quality_test = !metrics_output_path.empty(); FakeMediaSource media_source(task_runner, &testing_clock, + audio_sender_config, video_sender_config, quality_test); scoped_ptr<EncodedVideoFrameTracker> video_frame_tracker; @@ -501,9 +502,9 @@ // Initializing audio and video senders. cast_sender->InitializeAudio(audio_sender_config, - base::Bind(&AudioInitializationStatus)); + base::Bind(&LogAudioOperationalStatus)); cast_sender->InitializeVideo(media_source.get_video_config(), - base::Bind(&VideoInitializationStatus), + base::Bind(&LogVideoOperationalStatus), CreateDefaultVideoEncodeAcceleratorCallback(), CreateDefaultVideoEncodeMemoryCallback()); task_runner->RunTasks();
diff --git a/media/filters/skcanvas_video_renderer.cc b/media/filters/skcanvas_video_renderer.cc index 9ad70bea..07beeb22 100644 --- a/media/filters/skcanvas_video_renderer.cc +++ b/media/filters/skcanvas_video_renderer.cc
@@ -206,9 +206,10 @@ SkYUVColorSpace* color_space) override { if (!frame_.get() || !IsYUV(frame_->format()) || // TODO(rileya): Skia currently doesn't support Rec709 YUV conversion, - // Remove this case once it does. As-is we will fall back on the - // pure-software path in this case. - frame_->format() == VideoFrame::YV12HD) { + // or YUVA conversion. Remove this case once it does. As-is we will + // fall back on the pure-software path in this case. + frame_->format() == VideoFrame::YV12HD || + frame_->format() == VideoFrame::YV12A) { return false; } @@ -242,8 +243,27 @@ (frame_->visible_rect().y() >> y_shift)) + (frame_->visible_rect().x() >> 1); } - row_bytes[plane] = static_cast<size_t>(frame_->stride(plane)); - planes[plane] = frame_->data(plane) + offset; + + // Copy the frame to the supplied memory. + // TODO: Find a way (API change?) to avoid this copy. + char* out_line = static_cast<char*>(planes[plane]); + int out_line_stride = row_bytes[plane]; + uint8* in_line = frame_->data(plane) + offset; + int in_line_stride = frame_->stride(plane); + int plane_height = sizes[plane].height(); + if (in_line_stride == out_line_stride) { + memcpy(out_line, in_line, plane_height * in_line_stride); + } else { + // Different line padding so need to copy one line at a time. + int bytes_to_copy_per_line = out_line_stride < in_line_stride + ? out_line_stride + : in_line_stride; + for (int line_no = 0; line_no < plane_height; line_no++) { + memcpy(out_line, in_line, bytes_to_copy_per_line); + in_line += in_line_stride; + out_line += out_line_stride; + } + } } } return true;
diff --git a/media/filters/stream_parser_factory.cc b/media/filters/stream_parser_factory.cc index fd8e92b..23218bc 100644 --- a/media/filters/stream_parser_factory.cc +++ b/media/filters/stream_parser_factory.cc
@@ -284,6 +284,11 @@ base::android::BuildInfo::GetInstance()->sdk_int() < 19) { return false; } + // Opus is only supported on Lollipop+ (API Level 21). + if (codec_info->tag == CodecInfo::HISTOGRAM_OPUS && + base::android::BuildInfo::GetInstance()->sdk_int() < 21) { + return false; + } #endif if (video_codecs) video_codecs->push_back(codec_info->tag);
diff --git a/media/midi/usb_midi_device_android.h b/media/midi/usb_midi_device_android.h index 053e50e..19e65b8 100644 --- a/media/midi/usb_midi_device_android.h +++ b/media/midi/usb_midi_device_android.h
@@ -23,12 +23,11 @@ static scoped_ptr<Factory> CreateFactory(); UsbMidiDeviceAndroid(ObjectRef raw_device, UsbMidiDeviceDelegate* delegate); - virtual ~UsbMidiDeviceAndroid(); + ~UsbMidiDeviceAndroid() override; // UsbMidiDevice implementation. - virtual std::vector<uint8> GetDescriptor() override; - virtual void Send(int endpoint_number, - const std::vector<uint8>& data) override; + std::vector<uint8> GetDescriptor() override; + void Send(int endpoint_number, const std::vector<uint8>& data) override; // Called by the Java world. void OnData(JNIEnv* env,
diff --git a/media/midi/usb_midi_device_factory_android.h b/media/midi/usb_midi_device_factory_android.h index fb1792e3..4736375 100644 --- a/media/midi/usb_midi_device_factory_android.h +++ b/media/midi/usb_midi_device_factory_android.h
@@ -22,11 +22,11 @@ class MEDIA_EXPORT UsbMidiDeviceFactoryAndroid : public UsbMidiDevice::Factory { public: UsbMidiDeviceFactoryAndroid(); - virtual ~UsbMidiDeviceFactoryAndroid(); + ~UsbMidiDeviceFactoryAndroid() override; // UsbMidiDevice::Factory implementation. - virtual void EnumerateDevices(UsbMidiDeviceDelegate* delegate, - Callback callback) override; + void EnumerateDevices(UsbMidiDeviceDelegate* delegate, + Callback callback) override; void OnUsbMidiDeviceRequestDone(JNIEnv* env, jobject caller,
diff --git a/media/video/capture/android/video_capture_device_android.h b/media/video/capture/android/video_capture_device_android.h index 0df4c5e..832d64f 100644 --- a/media/video/capture/android/video_capture_device_android.h +++ b/media/video/capture/android/video_capture_device_android.h
@@ -37,7 +37,7 @@ }; explicit VideoCaptureDeviceAndroid(const Name& device_name); - virtual ~VideoCaptureDeviceAndroid(); + ~VideoCaptureDeviceAndroid() override; static VideoCaptureDevice* Create(const Name& device_name); static bool RegisterVideoCaptureDevice(JNIEnv* env); @@ -48,9 +48,9 @@ bool Init(); // VideoCaptureDevice implementation. - virtual void AllocateAndStart(const VideoCaptureParams& params, - scoped_ptr<Client> client) override; - virtual void StopAndDeAllocate() override; + void AllocateAndStart(const VideoCaptureParams& params, + scoped_ptr<Client> client) override; + void StopAndDeAllocate() override; // Implement org.chromium.media.VideoCapture.nativeOnFrameAvailable. void OnFrameAvailable(
diff --git a/media/video/capture/android/video_capture_device_factory_android.h b/media/video/capture/android/video_capture_device_factory_android.h index 4ea4ad5..9941393 100644 --- a/media/video/capture/android/video_capture_device_factory_android.h +++ b/media/video/capture/android/video_capture_device_factory_android.h
@@ -25,12 +25,12 @@ jlong nativeVideoCaptureDeviceAndroid); VideoCaptureDeviceFactoryAndroid() {} - virtual ~VideoCaptureDeviceFactoryAndroid() {} + ~VideoCaptureDeviceFactoryAndroid() override {} - virtual scoped_ptr<VideoCaptureDevice> Create( + scoped_ptr<VideoCaptureDevice> Create( const VideoCaptureDevice::Name& device_name) override; - virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names) override; - virtual void GetDeviceSupportedFormats( + void GetDeviceNames(VideoCaptureDevice::Names* device_names) override; + void GetDeviceSupportedFormats( const VideoCaptureDevice::Name& device, VideoCaptureFormats* supported_formats) override;
diff --git a/media/video/capture/mac/video_capture_device_avfoundation_mac.mm b/media/video/capture/mac/video_capture_device_avfoundation_mac.mm index 6c19d33..f3c7ca7 100644 --- a/media/video/capture/mac/video_capture_device_avfoundation_mac.mm +++ b/media/video/capture/mac/video_capture_device_avfoundation_mac.mm
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/mac/foundation_util.h" -#include "media/base/mac/corevideo_glue.h" #include "media/video/capture/mac/video_capture_device_mac.h" #include "ui/gfx/geometry/size.h" @@ -26,8 +25,6 @@ return media::PIXEL_FORMAT_YUY2; case CoreMediaGlue::kCMVideoCodecType_JPEG_OpenDML: return media::PIXEL_FORMAT_MJPEG; - case CoreVideoGlue::kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: - return media::PIXEL_FORMAT_NV12; default: return media::PIXEL_FORMAT_UNKNOWN; } @@ -282,7 +279,7 @@ // AVFoundation calls from a number of threads, depending on, at least, if // Chrome is on foreground or background. Sample the actual thread here. callback_thread_checker_.DetachFromThread(); - callback_thread_checker_.CalledOnValidThread(); + CHECK(callback_thread_checker_.CalledOnValidThread()); const CoreMediaGlue::CMFormatDescriptionRef formatDescription = CoreMediaGlue::CMSampleBufferGetFormatDescription(sampleBuffer); @@ -315,31 +312,9 @@ // Lock the frame and calculate frame size. if (CVPixelBufferLockBaseAddress(videoFrame, kCVPixelBufferLock_ReadOnly) == kCVReturnSuccess) { - baseAddress = static_cast<char*>( - CVPixelBufferGetPlaneCount(videoFrame) == 0 - ? CVPixelBufferGetBaseAddress(videoFrame) - : CVPixelBufferGetBaseAddressOfPlane(videoFrame, 0)); - // Chromium expects the data to be tightly packed, i.e. no row padding - // and the planes should follow consecutively. - switch (captureFormat.pixel_format) { - case media::PIXEL_FORMAT_YUY2: - case media::PIXEL_FORMAT_UYVY: - CHECK_EQ(CVPixelBufferGetBytesPerRow(videoFrame), - static_cast<size_t>(2 * captureFormat.frame_size.width())); - frameSize = captureFormat.frame_size.GetArea() * 16 / 8; // 16bpp. - break; - case media::PIXEL_FORMAT_NV12: - CHECK_EQ(CVPixelBufferGetBytesPerRowOfPlane(videoFrame, 0), - static_cast<size_t>(captureFormat.frame_size.width())); - CHECK_EQ(CVPixelBufferGetBytesPerRowOfPlane(videoFrame, 1), - static_cast<size_t>(captureFormat.frame_size.width())); - CHECK_EQ(CVPixelBufferGetBaseAddressOfPlane(videoFrame, 1), - baseAddress + captureFormat.frame_size.GetArea()); - frameSize = captureFormat.frame_size.GetArea() * 12 / 8; // 12bpp. - break; - default: - NOTREACHED(); - } + baseAddress = static_cast<char*>(CVPixelBufferGetBaseAddress(videoFrame)); + frameSize = CVPixelBufferGetHeight(videoFrame) * + CVPixelBufferGetBytesPerRow(videoFrame); } else { videoFrame = nil; }
diff --git a/media/video/capture/win/sink_input_pin_win.cc b/media/video/capture/win/sink_input_pin_win.cc index bf2a247..8212e15fe 100644 --- a/media/video/capture/win/sink_input_pin_win.cc +++ b/media/video/capture/win/sink_input_pin_win.cc
@@ -45,6 +45,24 @@ media_type->formattype = FORMAT_VideoInfo; media_type->bTemporalCompression = FALSE; + if (requested_format_.pixel_format == PIXEL_FORMAT_MJPEG) { + // If the requested pixel format is MJPEG, accept only MJPEG. + // This is ok since the capabilities of the capturer have been + // enumerated and we know that it is supported. + if (index != 0) + return false; + + pvi->bmiHeader.biCompression = MAKEFOURCC('M', 'J', 'P', 'G'); + pvi->bmiHeader.biBitCount = 0; + pvi->bmiHeader.biWidth = requested_format_.frame_size.width(); + pvi->bmiHeader.biHeight = requested_format_.frame_size.height(); + pvi->bmiHeader.biSizeImage = 0; + media_type->subtype = MEDIASUBTYPE_MJPG; + media_type->bFixedSizeSamples = FALSE; + media_type->lSampleSize = pvi->bmiHeader.biSizeImage; + return true; + } + switch (index) { case 0: { pvi->bmiHeader.biCompression = MAKEFOURCC('I', '4', '2', '0'); @@ -66,15 +84,6 @@ break; } case 2: { - pvi->bmiHeader.biCompression = MAKEFOURCC('M', 'J', 'P', 'G'); - pvi->bmiHeader.biBitCount = 0; - pvi->bmiHeader.biWidth = requested_format_.frame_size.width(); - pvi->bmiHeader.biHeight = requested_format_.frame_size.height(); - pvi->bmiHeader.biSizeImage = 0; - media_type->subtype = MEDIASUBTYPE_MJPG; - break; - } - case 3: { pvi->bmiHeader.biCompression = BI_RGB; pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biWidth = requested_format_.frame_size.width();
diff --git a/media/video/capture/win/video_capture_device_win.cc b/media/video/capture/win/video_capture_device_win.cc index bd68e3df..0a4ff69 100644 --- a/media/video/capture/win/video_capture_device_win.cc +++ b/media/video/capture/win/video_capture_device_win.cc
@@ -351,22 +351,21 @@ if (hr != S_OK) { SetErrorState("Failed to get capture device capabilities"); return; - } else { - if (media_type->formattype == FORMAT_VideoInfo) { - VIDEOINFOHEADER* h = - reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); - if (format.frame_rate > 0) - h->AvgTimePerFrame = kSecondsToReferenceTime / format.frame_rate; - } - // Set the sink filter to request this format. - sink_filter_->SetRequestedMediaFormat(format); - // Order the capture device to use this format. - hr = stream_config->SetFormat(media_type.get()); - if (FAILED(hr)) { - // TODO(grunell): Log the error. http://crbug.com/405016. - SetErrorState("Failed to set capture device output format"); - return; - } + } + if (media_type->formattype == FORMAT_VideoInfo) { + VIDEOINFOHEADER* h = + reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); + if (format.frame_rate > 0) + h->AvgTimePerFrame = kSecondsToReferenceTime / format.frame_rate; + } + // Set the sink filter to request this format. + sink_filter_->SetRequestedMediaFormat(format); + // Order the capture device to use this format. + hr = stream_config->SetFormat(media_type.get()); + if (FAILED(hr)) { + // TODO(grunell): Log the error. http://crbug.com/405016. + SetErrorState("Failed to set capture device output format"); + return; } SetAntiFlickerInCaptureFilter();
diff --git a/mojo/cc/output_surface_mojo.cc b/mojo/cc/output_surface_mojo.cc index fff13806..c489280d 100644 --- a/mojo/cc/output_surface_mojo.cc +++ b/mojo/cc/output_surface_mojo.cc
@@ -4,6 +4,7 @@ #include "mojo/cc/output_surface_mojo.h" +#include "base/bind.h" #include "cc/output/compositor_frame.h" #include "cc/output/output_surface_client.h" #include "mojo/converters/geometry/geometry_type_converters.h" @@ -20,6 +21,8 @@ surface_(surface.Pass()), id_namespace_(0u), local_id_(0u) { + surface_->GetIdNamespace( + base::Bind(&OutputSurfaceMojo::SetIdNamespace, base::Unretained(this))); capabilities_.delegated_rendering = true; capabilities_.max_frames_pending = 1; } @@ -36,11 +39,7 @@ } } -void OutputSurfaceMojo::ReturnResources(Array<ReturnedResourcePtr> resources) { -} - bool OutputSurfaceMojo::BindToClient(cc::OutputSurfaceClient* client) { - surface_.set_client(this); return cc::OutputSurface::BindToClient(client); }
diff --git a/mojo/cc/output_surface_mojo.h b/mojo/cc/output_surface_mojo.h index a34193e..48c4dbe1 100644 --- a/mojo/cc/output_surface_mojo.h +++ b/mojo/cc/output_surface_mojo.h
@@ -19,7 +19,7 @@ virtual void DidCreateSurface(cc::SurfaceId id) = 0; }; -class OutputSurfaceMojo : public cc::OutputSurface, public SurfaceClient { +class OutputSurfaceMojo : public cc::OutputSurface { public: OutputSurfaceMojo(OutputSurfaceMojoClient* client, const scoped_refptr<cc::ContextProvider>& context_provider, @@ -33,9 +33,7 @@ ~OutputSurfaceMojo() override; private: - // SurfaceClient implementation. - void SetIdNamespace(uint32_t id_namespace) override; - void ReturnResources(Array<ReturnedResourcePtr> resources) override; + void SetIdNamespace(uint32_t id_namespace); OutputSurfaceMojoClient* output_surface_mojo_client_; SurfacePtr surface_;
diff --git a/mojo/mojo_nacl.gyp b/mojo/mojo_nacl.gyp index 0215be4..e49a26c 100644 --- a/mojo/mojo_nacl.gyp +++ b/mojo/mojo_nacl.gyp
@@ -5,11 +5,9 @@ { 'conditions': [ ['disable_nacl==0 and disable_nacl_untrusted==0', { - 'variables': { - 'monacl_codegen_dir': '<(SHARED_INTERMEDIATE_DIR)/<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))/monacl', - }, 'includes': [ '../components/nacl/nacl_defines.gypi', + '../mojo/mojo_nacl.gypi', ], 'targets': [ {
diff --git a/mojo/mojo_nacl.gypi b/mojo/mojo_nacl.gypi new file mode 100644 index 0000000..01cfc21 --- /dev/null +++ b/mojo/mojo_nacl.gypi
@@ -0,0 +1,9 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'monacl_codegen_dir': '<(SHARED_INTERMEDIATE_DIR)/<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))/nacl', + }, +}
diff --git a/mojo/mojo_nacl_untrusted.gyp b/mojo/mojo_nacl_untrusted.gyp index 859c570..39b237c 100644 --- a/mojo/mojo_nacl_untrusted.gyp +++ b/mojo/mojo_nacl_untrusted.gyp
@@ -5,12 +5,10 @@ { 'conditions': [ ['disable_nacl==0 and disable_nacl_untrusted==0', { - 'variables': { - 'monacl_codegen_dir': '<(SHARED_INTERMEDIATE_DIR)/<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))/monacl', - }, 'includes': [ '../build/common_untrusted.gypi', '../components/nacl/nacl_defines.gypi', + '../mojo/mojo_nacl.gypi', '../third_party/mojo/mojo_variables.gypi', ], 'targets': [
diff --git a/mojo/services/html_viewer/html_document.cc b/mojo/services/html_viewer/html_document.cc index cbcfdf5..c85ed07 100644 --- a/mojo/services/html_viewer/html_document.cc +++ b/mojo/services/html_viewer/html_document.cc
@@ -36,7 +36,7 @@ #include "third_party/mojo/src/mojo/public/cpp/application/connect.h" #include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h" #include "third_party/mojo/src/mojo/public/interfaces/application/shell.mojom.h" -#include "third_party/mojo_services/src/surfaces/public/interfaces/surfaces_service.mojom.h" +#include "third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom.h" #include "third_party/mojo_services/src/view_manager/public/cpp/view.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h"
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.cc b/mojo/services/html_viewer/weblayertreeview_impl.cc index a9a6945e..a1d4da8 100644 --- a/mojo/services/html_viewer/weblayertreeview_impl.cc +++ b/mojo/services/html_viewer/weblayertreeview_impl.cc
@@ -80,8 +80,8 @@ } void WebLayerTreeViewImpl::ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) { @@ -101,7 +101,8 @@ } void WebLayerTreeViewImpl::RequestNewOutputSurface() { - layer_tree_host_->SetOutputSurface(output_surface_.Pass()); + if (output_surface_.get()) + layer_tree_host_->SetOutputSurface(output_surface_.Pass()); } void WebLayerTreeViewImpl::DidFailToInitializeOutputSurface() {
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.h b/mojo/services/html_viewer/weblayertreeview_impl.h index 269fc9f4..deb2f50a 100644 --- a/mojo/services/html_viewer/weblayertreeview_impl.h +++ b/mojo/services/html_viewer/weblayertreeview_impl.h
@@ -14,7 +14,7 @@ #include "mojo/cc/output_surface_mojo.h" #include "third_party/WebKit/public/platform/WebLayerTreeView.h" #include "third_party/mojo_services/src/gpu/public/interfaces/gpu.mojom.h" -#include "third_party/mojo_services/src/surfaces/public/interfaces/surfaces_service.mojom.h" +#include "third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom.h" namespace base { class MessageLoopProxy; @@ -52,8 +52,8 @@ void DidBeginMainFrame() override; void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override; - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override;
diff --git a/native_client_sdk/doc_generated/c-api-beta.html b/native_client_sdk/doc_generated/c-api-beta.html index 9bf2d50a..82d3c31 100644 --- a/native_client_sdk/doc_generated/c-api-beta.html +++ b/native_client_sdk/doc_generated/c-api-beta.html
@@ -2,8 +2,8 @@ <span class="target" id="c-api-beta"><span id="pepper-beta-c-index"></span></span><section id="pepper-c-api-reference-beta"> <h1 id="pepper-c-api-reference-beta">Pepper C API Reference (Beta)</h1> -<p>This page lists the C API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher.</p> +<p>This page lists the C API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher.</p> <h2 id="interfaces"><a class="reference external" href="pepper_beta/c/group___interfaces.html">Interfaces</a></h2> <blockquote> <div><ul class="small-gap"> @@ -55,10 +55,10 @@ <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html">PPB_OpenGLES2Query</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></li> -<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></li> +<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___touch_input_event__1__0.html">PPB_TouchInputEvent</a></li> -<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></li> +<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___u_r_l_response_info__1__0.html">PPB_URLResponseInfo</a></li> @@ -66,7 +66,7 @@ <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___var_array__1__0.html">PPB_VarArray</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></li> -<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></li> +<li><a class="reference external" href="pepper_beta/c/struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___view__1__2.html">PPB_View</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a></li> @@ -105,6 +105,7 @@ <li><a class="reference external" href="pepper_beta/c/struct_p_p___touch_point.html">PP_TouchPoint</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p___var.html">PP_Var</a></li> <li><a class="reference external" href="pepper_beta/c/struct_p_p___video_picture.html">PP_VideoPicture</a></li> +<li><a class="reference external" href="pepper_beta/c/struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></li> <li><a class="reference external" href="pepper_beta/c/union_p_p___var_value.html">PP_VarValue</a></li> </ul> </div></blockquote>
diff --git a/native_client_sdk/doc_generated/c-api-dev.html b/native_client_sdk/doc_generated/c-api-dev.html index f505a51..8bab9ea 100644 --- a/native_client_sdk/doc_generated/c-api-dev.html +++ b/native_client_sdk/doc_generated/c-api-dev.html
@@ -2,8 +2,8 @@ <span class="target" id="c-api-dev"><span id="pepper-dev-c-index"></span></span><section id="pepper-c-api-reference-dev"> <h1 id="pepper-c-api-reference-dev">Pepper C API Reference (Dev)</h1> -<p>This page lists the C API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher.</p> +<p>This page lists the C API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher.</p> <h2 id="interfaces"><a class="reference external" href="pepper_dev/c/group___interfaces.html">Interfaces</a></h2> <blockquote> <div><ul class="small-gap"> @@ -55,10 +55,10 @@ <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html">PPB_OpenGLES2Query</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></li> -<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></li> +<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___touch_input_event__1__0.html">PPB_TouchInputEvent</a></li> -<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></li> +<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___u_r_l_response_info__1__0.html">PPB_URLResponseInfo</a></li> @@ -66,7 +66,7 @@ <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___var_array__1__0.html">PPB_VarArray</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></li> -<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></li> +<li><a class="reference external" href="pepper_dev/c/struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___view__1__2.html">PPB_View</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a></li> @@ -105,6 +105,7 @@ <li><a class="reference external" href="pepper_dev/c/struct_p_p___touch_point.html">PP_TouchPoint</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p___var.html">PP_Var</a></li> <li><a class="reference external" href="pepper_dev/c/struct_p_p___video_picture.html">PP_VideoPicture</a></li> +<li><a class="reference external" href="pepper_dev/c/struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></li> <li><a class="reference external" href="pepper_dev/c/union_p_p___var_value.html">PP_VarValue</a></li> </ul> </div></blockquote>
diff --git a/native_client_sdk/doc_generated/c-api.html b/native_client_sdk/doc_generated/c-api.html index 3f1cdb64..08e3630e 100644 --- a/native_client_sdk/doc_generated/c-api.html +++ b/native_client_sdk/doc_generated/c-api.html
@@ -2,8 +2,8 @@ <span class="target" id="c-api"><span id="pepper-stable-c-index"></span></span><section id="pepper-c-api-reference-stable"> <h1 id="pepper-c-api-reference-stable">Pepper C API Reference (Stable)</h1> -<p>This page lists the C API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher.</p> +<p>This page lists the C API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher.</p> <h2 id="interfaces"><a class="reference external" href="pepper_stable/c/group___interfaces.html">Interfaces</a></h2> <blockquote> <div><ul class="small-gap"> @@ -31,7 +31,7 @@ <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___media_stream_audio_track__0__1.html">PPB_MediaStreamAudioTrack</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___media_stream_video_track__1__0.html">PPB_MediaStreamVideoTrack</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___message_loop__1__0.html">PPB_MessageLoop</a></li> -<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___messaging__1__0.html">PPB_Messaging</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___messaging__1__2.html">PPB_Messaging</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___mouse_cursor__1__0.html">PPB_MouseCursor</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___mouse_input_event__1__1.html">PPB_MouseInputEvent</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___mouse_lock__1__0.html">PPB_MouseLock</a></li> @@ -39,6 +39,22 @@ <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___network_list__1__0.html">PPB_NetworkList</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___network_monitor__1__0.html">PPB_NetworkMonitor</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___network_proxy__1__0.html">PPB_NetworkProxy</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2.html">PPB_OpenGLES2</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2__1__0.html">PPB_OpenGLES2</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html">PPB_OpenGLES2ChromiumEnableFeature</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html">PPB_OpenGLES2ChromiumEnableFeature</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html">PPB_OpenGLES2ChromiumMapSub</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html">PPB_OpenGLES2ChromiumMapSub</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html">PPB_OpenGLES2FramebufferBlit</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html">PPB_OpenGLES2FramebufferBlit</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html">PPB_OpenGLES2FramebufferMultisample</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html">PPB_OpenGLES2FramebufferMultisample</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays.html">PPB_OpenGLES2InstancedArrays</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html">PPB_OpenGLES2InstancedArrays</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query.html">PPB_OpenGLES2Query</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html">PPB_OpenGLES2Query</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___touch_input_event__1__0.html">PPB_TouchInputEvent</a></li> @@ -50,7 +66,7 @@ <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___var_array__1__0.html">PPB_VarArray</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></li> -<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___view__1__2.html">PPB_View</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a></li> @@ -58,6 +74,7 @@ <li><a class="reference external" href="pepper_stable/c/struct_p_p_p___graphics3_d__1__0.html">PPP_Graphics3D</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_p___input_event__0__1.html">PPP_InputEvent</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_p___instance__1__1.html">PPP_Instance</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_p___messaging__1__0.html">PPP_Messaging</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p_p___mouse_lock__1__0.html">PPP_MouseLock</a></li> </ul> @@ -88,6 +105,7 @@ <li><a class="reference external" href="pepper_stable/c/struct_p_p___touch_point.html">PP_TouchPoint</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p___var.html">PP_Var</a></li> <li><a class="reference external" href="pepper_stable/c/struct_p_p___video_picture.html">PP_VideoPicture</a></li> +<li><a class="reference external" href="pepper_stable/c/struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></li> <li><a class="reference external" href="pepper_stable/c/union_p_p___var_value.html">PP_VarValue</a></li> </ul> </div></blockquote> @@ -147,6 +165,7 @@ <li><a class="reference external" href="pepper_stable/c/ppb__network__list_8h.html">ppb_network_list.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppb__network__monitor_8h.html">ppb_network_monitor.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppb__network__proxy_8h.html">ppb_network_proxy.h</a></li> +<li><a class="reference external" href="pepper_stable/c/ppb__opengles2_8h.html">ppb_opengles2.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppb__tcp__socket_8h.html">ppb_tcp_socket.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppb__text__input__controller_8h.html">ppb_text_input_controller.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppb__udp__socket_8h.html">ppb_udp_socket.h</a></li> @@ -165,6 +184,7 @@ <li><a class="reference external" href="pepper_stable/c/ppp__graphics__3d_8h.html">ppp_graphics_3d.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppp__input__event_8h.html">ppp_input_event.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppp__instance_8h.html">ppp_instance.h</a></li> +<li><a class="reference external" href="pepper_stable/c/ppp__message__handler_8h.html">ppp_message_handler.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppp__messaging_8h.html">ppp_messaging.h</a></li> <li><a class="reference external" href="pepper_stable/c/ppp__mouse__lock_8h.html">ppp_mouse_lock.h</a></li> </ul>
diff --git a/native_client_sdk/doc_generated/cpp-api-beta.html b/native_client_sdk/doc_generated/cpp-api-beta.html index 6c53ffd..f242e67 100644 --- a/native_client_sdk/doc_generated/cpp-api-beta.html +++ b/native_client_sdk/doc_generated/cpp-api-beta.html
@@ -2,8 +2,8 @@ <span class="target" id="cpp-api-beta"><span id="pepper-beta-cpp-index"></span></span><section id="pepper-c-api-reference-beta"> <h1 id="pepper-c-api-reference-beta">Pepper C++ API Reference (Beta)</h1> -<p>This page lists the C++ API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher.</p> +<p>This page lists the C++ API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher.</p> <h2 id="classes"><a class="reference external" href="pepper_beta/cpp/inherits.html">Classes</a></h2> <blockquote> <div><ul class="small-gap">
diff --git a/native_client_sdk/doc_generated/cpp-api-dev.html b/native_client_sdk/doc_generated/cpp-api-dev.html index 1b436604..72970af 100644 --- a/native_client_sdk/doc_generated/cpp-api-dev.html +++ b/native_client_sdk/doc_generated/cpp-api-dev.html
@@ -2,8 +2,8 @@ <span class="target" id="cpp-api-dev"><span id="pepper-dev-cpp-index"></span></span><section id="pepper-c-api-reference-dev"> <h1 id="pepper-c-api-reference-dev">Pepper C++ API Reference (Dev)</h1> -<p>This page lists the C++ API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher.</p> +<p>This page lists the C++ API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher.</p> <h2 id="classes"><a class="reference external" href="pepper_dev/cpp/inherits.html">Classes</a></h2> <blockquote> <div><ul class="small-gap">
diff --git a/native_client_sdk/doc_generated/cpp-api.html b/native_client_sdk/doc_generated/cpp-api.html index 65fc07e..aecb7fe 100644 --- a/native_client_sdk/doc_generated/cpp-api.html +++ b/native_client_sdk/doc_generated/cpp-api.html
@@ -2,8 +2,8 @@ <span class="target" id="cpp-api"><span id="pepper-stable-cpp-index"></span></span><section id="pepper-c-api-reference-stable"> <h1 id="pepper-c-api-reference-stable">Pepper C++ API Reference (Stable)</h1> -<p>This page lists the C++ API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher.</p> +<p>This page lists the C++ API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher.</p> <h2 id="classes"><a class="reference external" href="pepper_stable/cpp/inherits.html">Classes</a></h2> <blockquote> <div><ul class="small-gap">
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/globals_defs.html b/native_client_sdk/doc_generated/pepper_beta/c/globals_defs.html index cc82f25..ec7106fe 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/globals_defs.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/globals_defs.html
@@ -244,8 +244,8 @@ <li>PPB_TCPSOCKET_INTERFACE : <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">ppb_tcp_socket.h</a> </li> -<li>PPB_TCPSOCKET_INTERFACE_1_1 -: <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">ppb_tcp_socket.h</a> +<li>PPB_TCPSOCKET_INTERFACE_1_2 +: <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">ppb_tcp_socket.h</a> </li> <li>PPB_TEXTINPUTCONTROLLER_INTERFACE : <a class="el" href="ppb__text__input__controller_8h.html#a9a28f7fd2db84c2cd550ed272070c0ee">ppb_text_input_controller.h</a> @@ -262,8 +262,8 @@ <li>PPB_UDPSOCKET_INTERFACE : <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">ppb_udp_socket.h</a> </li> -<li>PPB_UDPSOCKET_INTERFACE_1_0 -: <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">ppb_udp_socket.h</a> +<li>PPB_UDPSOCKET_INTERFACE_1_1 +: <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">ppb_udp_socket.h</a> </li> <li>PPB_URLLOADER_INTERFACE : <a class="el" href="ppb__url__loader_8h.html#ae1fa8c5cdfccb7ea67e184b1e5e1009e">ppb_url_loader.h</a> @@ -310,8 +310,8 @@ <li>PPB_VIDEODECODER_INTERFACE : <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">ppb_video_decoder.h</a> </li> -<li>PPB_VIDEODECODER_INTERFACE_0_2 -: <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">ppb_video_decoder.h</a> +<li>PPB_VIDEODECODER_INTERFACE_1_0 +: <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">ppb_video_decoder.h</a> </li> <li>PPB_VIDEOFRAME_INTERFACE : <a class="el" href="ppb__video__frame_8h.html#ac161d8c49f583eda31622d9fc010cd0d">ppb_video_frame.h</a>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/group___enums.html b/native_client_sdk/doc_generated/pepper_beta/c/group___enums.html index 237129e..3bd2e7d 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/group___enums.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/group___enums.html
@@ -1644,16 +1644,16 @@ <dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0"> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_NO_DELAY" ref="gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10" args="" -->PP_TCPSOCKET_OPTION_NO_DELAY</em> </td><td> <p>Disables coalescing of small writes to make TCP segments, and instead delivers data immediately. </p> -<p>Value's type is <code>PP_VARTYPE_BOOL</code>. This option can only be set after a successful <code>Connect()</code> call. </p> +<p>Value's type is <code>PP_VARTYPE_BOOL</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12a61ce27ba7853d05f7af51be1bed5d1a6"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE" ref="gga1557c0bbce8739a3418e6027a9c44e12a61ce27ba7853d05f7af51be1bed5d1a6" args="" -->PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for sends. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Connect()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12aef57736e294acb30fb7b3b2f4a425f72"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE" ref="gga1557c0bbce8739a3418e6027a9c44e12aef57736e294acb30fb7b3b2f4a425f72" args="" -->PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for receives. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Connect()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> </table> @@ -1741,16 +1741,16 @@ </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2aeceda8fe978a52382b96939de7707c00"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_BROADCAST" ref="gga1a8472fa3e7150615c45c38fa8c12ce2aeceda8fe978a52382b96939de7707c00" args="" -->PP_UDPSOCKET_OPTION_BROADCAST</em> </td><td> <p>Allows sending and receiving packets to and from broadcast addresses. </p> -<p>Value's type should be <code>PP_VARTYPE_BOOL</code>. This option can only be set before calling <code>Bind()</code>. </p> +<p>Value's type should be <code>PP_VARTYPE_BOOL</code>. On version 1.0, this option can only be set before calling <code>Bind()</code>. On version 1.1 or later, there is no such limitation. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2a905f0adde2912a5db26883d45fb75d57"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE" ref="gga1a8472fa3e7150615c45c38fa8c12ce2a905f0adde2912a5db26883d45fb75d57" args="" -->PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for sends. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Bind()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.0, this option can only be set after a successful <code>Bind()</code> call. On version 1.1 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2a1264eb1d6d16eb3a074ee3d21ebb3b64"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE" ref="gga1a8472fa3e7150615c45c38fa8c12ce2a1264eb1d6d16eb3a074ee3d21ebb3b64" args="" -->PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for receives. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Bind()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.0, this option can only be set after a successful <code>Bind()</code> call. On version 1.1 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> </table>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/group___interfaces.html b/native_client_sdk/doc_generated/pepper_beta/c/group___interfaces.html index 14ed4c5..e4a64ed8 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/group___interfaces.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/group___interfaces.html
@@ -90,12 +90,12 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html">PPB_OpenGLES2Query</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__2.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code>PPB_TextInputController</code> provides a set of functions for giving hints to the browser about the text input status of plugins, and functions for controlling input method editors (IMEs). <a href="struct_p_p_b___text_input_controller__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <b>PPB_URLLoader</b> interface contains pointers to functions for loading URLs. <a href="struct_p_p_b___u_r_l_loader__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a></td></tr> @@ -109,8 +109,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_VarArrayBuffer</code> interface provides a way to interact with JavaScript ArrayBuffers, which represent a contiguous sequence of bytes. <a href="struct_p_p_b___var_array_buffer__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">A dictionary var contains key-value pairs with unique keys. <a href="struct_p_p_b___var_dictionary__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__2.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code>PPB_View</code> represents the state of the view of an instance. <a href="struct_p_p_b___view__1__2.html#details">More...</a><br /></td></tr> @@ -166,10 +166,10 @@ <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___network_monitor__1__0.html">PPB_NetworkMonitor</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga873d8c5cd49f7b3c8ad5b4caabd1e8e6">PPB_NetworkMonitor</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___network_proxy__1__0.html">PPB_NetworkProxy</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf8338a682417267c8525446ef1de85b1">PPB_NetworkProxy</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab387085f6044f3a0b1631d119d22a942">PPB_TextInputController</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga307f562a9e41991de7c80b75cd7f379c">PPB_URLLoader</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad60387934d9e235d3d145ee5a1fb4e74">PPB_URLRequestInfo</a></td></tr> @@ -181,7 +181,7 @@ <a class="el" href="struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab26d5bb032f5438d02faf5bdf7b208cb">PPB_VarArrayBuffer</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga69826004b5c32232c9639090f3e1db2e">PPB_VarDictionary</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaa76d004c840f6c4f64a0694e7c844ae9">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga116e11e23c92c99094c9704d97636a67">PPB_View</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad0e152d14cefb0b480228f3fc7070faf">PPB_WebSocket</a></td></tr> @@ -530,12 +530,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="ga0f72e14a6cf9631bd733ded1f8ba4d9f"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSocket" ref="ga0f72e14a6cf9631bd733ded1f8ba4d9f" args="" --> +<a class="anchor" id="ga68e25baffc8cfc72d6c636a3a6217aa0"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSocket" ref="ga68e25baffc8cfc72d6c636a3a6217aa0" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> <a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> <a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td> </tr> </table> </div> @@ -566,12 +566,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="gaf04d893ccf01c5d1cfcadee5fcc869d1"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSocket" ref="gaf04d893ccf01c5d1cfcadee5fcc869d1" args="" --> +<a class="anchor" id="ga03552c99ad9e2a408a988822f834f548"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSocket" ref="ga03552c99ad9e2a408a988822f834f548" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> <a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> <a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td> </tr> </table> </div> @@ -662,12 +662,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="gaaab5a6b6d09e6a2eea4e11c63c3c1b4f"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="gaaab5a6b6d09e6a2eea4e11c63c3c1b4f" args="" --> +<a class="anchor" id="ga2b4555d8bd239fa28b60c42df75f7ce5"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="ga2b4555d8bd239fa28b60c42df75f7ce5" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/group___structs.html b/native_client_sdk/doc_generated/pepper_beta/c/group___structs.html index 1a4f153..1bf6366 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/group___structs.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/group___structs.html
@@ -15,6 +15,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">A structure that defines a way for the browser to return arrays of data to the plugin. <a href="struct_p_p___array_output.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> is a common mechanism for supporting potentially asynchronous calls in browser interfaces. <a href="struct_p_p___completion_callback.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___directory_entry.html">PP_DirectoryEntry</a></td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h.html b/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h.html index 88d9df4..c9cbed88 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h.html
@@ -21,6 +21,8 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> { <br />
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h__incl.png b/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h__incl.png index fcefc9dd..e74f895 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_beta/c/pp__codecs_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/ppb__tcp__socket_8h.html b/native_client_sdk/doc_generated/pepper_beta/c/ppb__tcp__socket_8h.html index 516526e55..ea5a225 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/ppb__tcp__socket_8h.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/ppb__tcp__socket_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__2.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.1"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.2"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> { <a class="el" href="group___enums.html#gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10">PP_TCPSOCKET_OPTION_NO_DELAY</a> = 0, @@ -46,19 +46,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="a12b0fabc454cb99a6d4c8352c6f22d71"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSOCKET_INTERFACE" ref="a12b0fabc454cb99a6d4c8352c6f22d71" args="" --> +<a class="anchor" id="a2f1cedfee70f4bfe4c35849be53fd73f"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSOCKET_INTERFACE" ref="a2f1cedfee70f4bfe4c35849be53fd73f" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.1"</td> +<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.2"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/ppb__udp__socket_8h.html b/native_client_sdk/doc_generated/pepper_beta/c/ppb__udp__socket_8h.html index 7cb5823..130ae3d 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/ppb__udp__socket_8h.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/ppb__udp__socket_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__1.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.0"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.1"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> { <a class="el" href="group___enums.html#gga1a8472fa3e7150615c45c38fa8c12ce2a79568403b8927bf98bea0f2d38469984">PP_UDPSOCKET_OPTION_ADDRESS_REUSE</a> = 0, @@ -47,19 +47,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="aafc1aecb9a8f2c3f8eed80a93a77763c"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSOCKET_INTERFACE" ref="aafc1aecb9a8f2c3f8eed80a93a77763c" args="" --> +<a class="anchor" id="a756bacac14becc5cbc2efedcd3ccd509"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSOCKET_INTERFACE" ref="a756bacac14becc5cbc2efedcd3ccd509" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.0"</td> +<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.1"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h.html b/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h.html index 8248cf0..212d41ab 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__2.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.2"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>This file defines the <code>PPB_VideoDecoder</code> interface. </p> @@ -37,19 +37,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="a72520f2e97ea5a9a2225fb100c577877"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="a72520f2e97ea5a9a2225fb100c577877" args="" --> +<a class="anchor" id="af814c8f0028bce254da6fb5c3e61a4d8"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="af814c8f0028bce254da6fb5c3e61a4d8" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.2"</td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h__incl.png b/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h__incl.png index 0d6c946..6456426 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_beta/c/ppb__video__decoder_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture.html index 2bf52aca..8e19d4e3 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture.html
@@ -16,6 +16,7 @@ <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#ae1a9b538db9e422e9f4c9126e941ea25">texture_id</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a5e2d5f24f86223ad71f2efb83116f118">texture_target</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a0f3c7022b44215e06f98f771f75641cc">texture_size</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">visible_rect</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Struct describing a decoded video picture. </p> @@ -77,6 +78,20 @@ <p>The pixel format of the texture is GL_RGBA. </p> </div> </div> +<a class="anchor" id="a1068a6b0ec8376cadcc7b08e607085f2"></a><!-- doxytag: member="PP_VideoPicture::visible_rect" ref="a1068a6b0ec8376cadcc7b08e607085f2" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> <a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">PP_VideoPicture::visible_rect</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The visible subrectangle of the picture. </p> +<p>The plugin should display only this part of the picture. </p> +</div> +</div> <hr />The documentation for this struct was generated from the following file:<ul> <li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> </ul>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture__0__1.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture__0__1.html new file mode 100644 index 0000000..1710cdf --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p___video_picture__0__1.html
@@ -0,0 +1,85 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PP_VideoPicture Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PP_VideoPicture" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">decode_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">texture_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">texture_target</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">texture_size</a></td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>Struct describing a decoded video picture. </p> +<p>The decoded picture data is stored in the GL texture corresponding to |texture_id|. The plugin can determine which Decode call generated the picture using |decode_id|. </p> +</div><hr /><h2>Field Documentation</h2> +<a class="anchor" id="a5745b95f0df115201c6ac1eab564cf2e"></a><!-- doxytag: member="PP_VideoPicture::decode_id" ref="a5745b95f0df115201c6ac1eab564cf2e" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">PP_VideoPicture::decode_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>|decode_id| parameter of the Decode call which generated this picture. </p> +<p>See the PPB_VideoDecoder function Decode() for more details. </p> +</div> +</div> +<a class="anchor" id="a8ee7a6fdddbf71d429a16f7779af6f0f"></a><!-- doxytag: member="PP_VideoPicture::texture_id" ref="a8ee7a6fdddbf71d429a16f7779af6f0f" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">PP_VideoPicture::texture_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Texture ID in the plugin's GL context. </p> +<p>The plugin can use this to render the decoded picture. </p> +</div> +</div> +<a class="anchor" id="aeed32ff6cc3c52d51b0a5179904e5676"></a><!-- doxytag: member="PP_VideoPicture::texture_size" ref="aeed32ff6cc3c52d51b0a5179904e5676" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> <a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">PP_VideoPicture::texture_size</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Dimensions of the texture holding the decoded picture. </p> +</div> +</div> +<a class="anchor" id="af73723a3d48c5b8ae027826dccfdc88c"></a><!-- doxytag: member="PP_VideoPicture::texture_target" ref="af73723a3d48c5b8ae027826dccfdc88c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">PP_VideoPicture::texture_target</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The GL texture target for the decoded picture. </p> +<p>Possible values are: GL_TEXTURE_2D GL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_EXTERNAL_OES</p> +<p>The pixel format of the texture is GL_RGBA. </p> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__2.html similarity index 80% rename from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html rename to native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__2.html index d9d5a0d2..7b0a919 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__2.html
@@ -12,29 +12,29 @@ <!-- doxytag: class="PPB_TCPSocket" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">IsTCPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">Connect</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">GetLocalAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">GetRemoteAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">Read</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">Write</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">Listen</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">Accept</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a889fb7b3263304ef5057cd541a197312">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5355f00c99cd7fb9563eb9987a73a3c5">IsTCPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aeb78a27cd902e93c557a0015812237f9">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939">Connect</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5916aca75506efccaa2905bb758421a2">GetLocalAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#abb362a218eef33522ea9b508d482a015">GetRemoteAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1">Read</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ac798b76c497f00231bd592ebdb584042">Write</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d">Listen</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a">Accept</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a6ca1887389cfaf357054e016adf7fc77">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aa42176651e65cf589fc310c0b2ed5751">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>The <code>PPB_TCPSocket</code> interface provides TCP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>tcp-connect</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code>; subrule <code>tcp-listen</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> +<p>Permissions: Apps permission <code>socket</code> with subrule <code>tcp-connect</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code>; subrule <code>tcp-listen</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d" title="Starts listening.">Listen()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a444d931c7fbb40e47cca8c55d57250f7"></a><!-- doxytag: member="PPB_TCPSocket::Accept" ref="a444d931c7fbb40e47cca8c55d57250f7" args=")(PP_Resource tcp_socket, PP_Resource *accepted_tcp_socket, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad9b1525032df05cf446f7d7c27c6145a"></a><!-- doxytag: member="PPB_TCPSocket::Accept" ref="ad9b1525032df05cf446f7d7c27c6145a" args=")(PP_Resource tcp_socket, PP_Resource *accepted_tcp_socket, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">PPB_TCPSocket::Accept</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a">PPB_TCPSocket::Accept</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -55,12 +55,12 @@ </dd></dl> </div> </div> -<a class="anchor" id="aae9a2f9ced445ca28a21721a0df5c567"></a><!-- doxytag: member="PPB_TCPSocket::Bind" ref="aae9a2f9ced445ca28a21721a0df5c567" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aeb78a27cd902e93c557a0015812237f9"></a><!-- doxytag: member="PPB_TCPSocket::Bind" ref="aeb78a27cd902e93c557a0015812237f9" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">PPB_TCPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aeb78a27cd902e93c557a0015812237f9">PPB_TCPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -82,18 +82,18 @@ </dd></dl> </div> </div> -<a class="anchor" id="afc2d9d7577df96bd0ac8f3cc6f503266"></a><!-- doxytag: member="PPB_TCPSocket::Close" ref="afc2d9d7577df96bd0ac8f3cc6f503266" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="a6ca1887389cfaf357054e016adf7fc77"></a><!-- doxytag: member="PPB_TCPSocket::Close" ref="a6ca1887389cfaf357054e016adf7fc77" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">PPB_TCPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a6ca1887389cfaf357054e016adf7fc77">PPB_TCPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> <div class="memdoc"> <p>Cancels all pending operations and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output buffer pointers passed into previous <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32" title="Reads data from the socket.">Read()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7" title="Accepts a connection.">Accept()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code> again.</p> +<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output buffer pointers passed into previous <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1" title="Reads data from the socket.">Read()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a" title="Accepts a connection.">Accept()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d" title="Starts listening.">Listen()</a></code> again.</p> <p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> @@ -103,12 +103,12 @@ </dl> </div> </div> -<a class="anchor" id="a1d12313b4681e48fa6f9b789d26414cb"></a><!-- doxytag: member="PPB_TCPSocket::Connect" ref="a1d12313b4681e48fa6f9b789d26414cb" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad107b3d5541072b14e2b8acc836b3939"></a><!-- doxytag: member="PPB_TCPSocket::Connect" ref="ad107b3d5541072b14e2b8acc836b3939" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">PPB_TCPSocket::Connect</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939">PPB_TCPSocket::Connect</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -131,15 +131,15 @@ <li><code>PP_ERROR_CONNECTION_TIMEDOUT</code>: the connection attempt timed out.</li> </ul> </dd></dl> -<p>Since version 1.1, if the socket is listening/connected or has a pending listen/connect request, <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> will fail without starting a connection attempt; otherwise, any failure during the connection attempt will cause the socket to be closed. </p> +<p>Since version 1.1, if the socket is listening/connected or has a pending listen/connect request, <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code> will fail without starting a connection attempt; otherwise, any failure during the connection attempt will cause the socket to be closed. </p> </div> </div> -<a class="anchor" id="a615cb349fbe99e25ae09078091c87b43"></a><!-- doxytag: member="PPB_TCPSocket::Create" ref="a615cb349fbe99e25ae09078091c87b43" args=")(PP_Instance instance)" --> +<a class="anchor" id="a889fb7b3263304ef5057cd541a197312"></a><!-- doxytag: member="PPB_TCPSocket::Create" ref="a889fb7b3263304ef5057cd541a197312" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">PPB_TCPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a889fb7b3263304ef5057cd541a197312">PPB_TCPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -154,12 +154,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a TCP socket or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="ab64edd222b040500767f5c9182358b68"></a><!-- doxytag: member="PPB_TCPSocket::GetLocalAddress" ref="ab64edd222b040500767f5c9182358b68" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="a5916aca75506efccaa2905bb758421a2"></a><!-- doxytag: member="PPB_TCPSocket::GetLocalAddress" ref="a5916aca75506efccaa2905bb758421a2" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">PPB_TCPSocket::GetLocalAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5916aca75506efccaa2905bb758421a2">PPB_TCPSocket::GetLocalAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> @@ -174,12 +174,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="af28b600fcdf657ca31dd2e9218a774e1"></a><!-- doxytag: member="PPB_TCPSocket::GetRemoteAddress" ref="af28b600fcdf657ca31dd2e9218a774e1" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="abb362a218eef33522ea9b508d482a015"></a><!-- doxytag: member="PPB_TCPSocket::GetRemoteAddress" ref="abb362a218eef33522ea9b508d482a015" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">PPB_TCPSocket::GetRemoteAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#abb362a218eef33522ea9b508d482a015">PPB_TCPSocket::GetRemoteAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> @@ -194,12 +194,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="afe32ae060181370e12c93c206964a58f"></a><!-- doxytag: member="PPB_TCPSocket::IsTCPSocket" ref="afe32ae060181370e12c93c206964a58f" args=")(PP_Resource resource)" --> +<a class="anchor" id="a5355f00c99cd7fb9563eb9987a73a3c5"></a><!-- doxytag: member="PPB_TCPSocket::IsTCPSocket" ref="a5355f00c99cd7fb9563eb9987a73a3c5" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">PPB_TCPSocket::IsTCPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5355f00c99cd7fb9563eb9987a73a3c5">PPB_TCPSocket::IsTCPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -214,12 +214,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_TCPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> </div> </div> -<a class="anchor" id="af3b28d2bf3f44d89e434e158854bea69"></a><!-- doxytag: member="PPB_TCPSocket::Listen" ref="af3b28d2bf3f44d89e434e158854bea69" args=")(PP_Resource tcp_socket, int32_t backlog, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="acffd2f5faddf094ccd9638128167259d"></a><!-- doxytag: member="PPB_TCPSocket::Listen" ref="acffd2f5faddf094ccd9638128167259d" args=")(PP_Resource tcp_socket, int32_t backlog, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">PPB_TCPSocket::Listen</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d">PPB_TCPSocket::Listen</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -241,12 +241,12 @@ </dd></dl> </div> </div> -<a class="anchor" id="ab4bd707da2d9d2136c59a08b3de2ce32"></a><!-- doxytag: member="PPB_TCPSocket::Read" ref="ab4bd707da2d9d2136c59a08b3de2ce32" args=")(PP_Resource tcp_socket, char *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aac72febd03fe6e6e5adafcfd2b24a8b1"></a><!-- doxytag: member="PPB_TCPSocket::Read" ref="aac72febd03fe6e6e5adafcfd2b24a8b1" args=")(PP_Resource tcp_socket, char *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">PPB_TCPSocket::Read</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1">PPB_TCPSocket::Read</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -265,12 +265,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been read, 0 means that end-of-file was reached; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="ab64ed8f1f7b4c3dce8d3493fb894ea0d"></a><!-- doxytag: member="PPB_TCPSocket::SetOption" ref="ab64ed8f1f7b4c3dce8d3493fb894ea0d" args=")(PP_Resource tcp_socket, PP_TCPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aa42176651e65cf589fc310c0b2ed5751"></a><!-- doxytag: member="PPB_TCPSocket::SetOption" ref="aa42176651e65cf589fc310c0b2ed5751" args=")(PP_Resource tcp_socket, PP_TCPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">PPB_TCPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aa42176651e65cf589fc310c0b2ed5751">PPB_TCPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -289,12 +289,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="adea2cbc4e8487f2f26c2126983f9c856"></a><!-- doxytag: member="PPB_TCPSocket::Write" ref="adea2cbc4e8487f2f26c2126983f9c856" args=")(PP_Resource tcp_socket, const char *buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ac798b76c497f00231bd592ebdb584042"></a><!-- doxytag: member="PPB_TCPSocket::Write" ref="ac798b76c497f00231bd592ebdb584042" args=")(PP_Resource tcp_socket, const char *buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">PPB_TCPSocket::Write</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ac798b76c497f00231bd592ebdb584042">PPB_TCPSocket::Write</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__1.html similarity index 79% rename from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html rename to native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__1.html index 1fe7d5b..6307ad0 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__1.html
@@ -12,25 +12,25 @@ <!-- doxytag: class="PPB_UDPSocket" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">IsUDPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">GetBoundAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">RecvFrom</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">SendTo</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a687ffa461f068fae0e0cc6694b3157bd">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a122be12f51d87e13cbe33bf30b3bef86">IsUDPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a33be83f9c8d91811c9ee20fd04ae9be3">GetBoundAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913">RecvFrom</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38">SendTo</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a9c349fbeb2a9fca70b8ecf0a860d2112">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a7107524b673568e4e69c63c43ecd0eec">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>The <code>PPB_UDPSocket</code> interface provides UDP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>udp-bind</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code>; subrule <code>udp-send-to</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76" title="Sends data to a specific destination.">SendTo()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> +<p>Permissions: Apps permission <code>socket</code> with subrule <code>udp-bind</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044" title="Binds the socket to the given address.">Bind()</a></code>; subrule <code>udp-send-to</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38" title="Sends data to a specific destination.">SendTo()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a0cae18760f8e9c4f06f160edab542c46"></a><!-- doxytag: member="PPB_UDPSocket::Bind" ref="a0cae18760f8e9c4f06f160edab542c46" args=")(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ab35f5cda2711b220a2b6c090b469d044"></a><!-- doxytag: member="PPB_UDPSocket::Bind" ref="ab35f5cda2711b220a2b6c090b469d044" args=")(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">PPB_UDPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044">PPB_UDPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -47,18 +47,18 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_ADDRESS_IN_USE</code> will be returned if the address is already in use. </dd></dl> </div> </div> -<a class="anchor" id="a8b34e95d8f1ca113f2c806fb9b64d3e9"></a><!-- doxytag: member="PPB_UDPSocket::Close" ref="a8b34e95d8f1ca113f2c806fb9b64d3e9" args=")(PP_Resource udp_socket)" --> +<a class="anchor" id="a9c349fbeb2a9fca70b8ecf0a860d2112"></a><!-- doxytag: member="PPB_UDPSocket::Close" ref="a9c349fbeb2a9fca70b8ecf0a860d2112" args=")(PP_Resource udp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">PPB_UDPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a9c349fbeb2a9fca70b8ecf0a860d2112">PPB_UDPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> </tr> </table> </div> <div class="memdoc"> <p>Cancels all pending reads and writes, and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output parameters passed into previous <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2" title="Receives data from the socket and stores the source address.">RecvFrom()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code> again.</p> +<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output parameters passed into previous <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913" title="Receives data from the socket and stores the source address.">RecvFrom()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044" title="Binds the socket to the given address.">Bind()</a></code> again.</p> <p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> @@ -68,12 +68,12 @@ </dl> </div> </div> -<a class="anchor" id="a48dfac97beb8bef209ea79efaf5b0c32"></a><!-- doxytag: member="PPB_UDPSocket::Create" ref="a48dfac97beb8bef209ea79efaf5b0c32" args=")(PP_Instance instance)" --> +<a class="anchor" id="a687ffa461f068fae0e0cc6694b3157bd"></a><!-- doxytag: member="PPB_UDPSocket::Create" ref="a687ffa461f068fae0e0cc6694b3157bd" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">PPB_UDPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a687ffa461f068fae0e0cc6694b3157bd">PPB_UDPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -88,12 +88,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a UDP socket or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="aa71b3888a2edf12c7bccd69d4ddcbbb6"></a><!-- doxytag: member="PPB_UDPSocket::GetBoundAddress" ref="aa71b3888a2edf12c7bccd69d4ddcbbb6" args=")(PP_Resource udp_socket)" --> +<a class="anchor" id="a33be83f9c8d91811c9ee20fd04ae9be3"></a><!-- doxytag: member="PPB_UDPSocket::GetBoundAddress" ref="a33be83f9c8d91811c9ee20fd04ae9be3" args=")(PP_Resource udp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">PPB_UDPSocket::GetBoundAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a33be83f9c8d91811c9ee20fd04ae9be3">PPB_UDPSocket::GetBoundAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> </tr> </table> </div> @@ -109,12 +109,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="a90de8c0e342ab04bc6d2439b2e0543a5"></a><!-- doxytag: member="PPB_UDPSocket::IsUDPSocket" ref="a90de8c0e342ab04bc6d2439b2e0543a5" args=")(PP_Resource resource)" --> +<a class="anchor" id="a122be12f51d87e13cbe33bf30b3bef86"></a><!-- doxytag: member="PPB_UDPSocket::IsUDPSocket" ref="a122be12f51d87e13cbe33bf30b3bef86" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">PPB_UDPSocket::IsUDPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a122be12f51d87e13cbe33bf30b3bef86">PPB_UDPSocket::IsUDPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -129,12 +129,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_UDPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> </div> </div> -<a class="anchor" id="a6f7b8cb60ad4279ac52feba6acca9cc2"></a><!-- doxytag: member="PPB_UDPSocket::RecvFrom" ref="a6f7b8cb60ad4279ac52feba6acca9cc2" args=")(PP_Resource udp_socket, char *buffer, int32_t num_bytes, PP_Resource *addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aa15ebcb5bfc899d2d46f8f25266e4913"></a><!-- doxytag: member="PPB_UDPSocket::RecvFrom" ref="aa15ebcb5bfc899d2d46f8f25266e4913" args=")(PP_Resource udp_socket, char *buffer, int32_t num_bytes, PP_Resource *addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">PPB_UDPSocket::RecvFrom</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913">PPB_UDPSocket::RecvFrom</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -154,12 +154,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been received; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="a9b78201046b292b6292f0d5bf55d3f76"></a><!-- doxytag: member="PPB_UDPSocket::SendTo" ref="a9b78201046b292b6292f0d5bf55d3f76" args=")(PP_Resource udp_socket, const char *buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad6b1bd2a28fdc4fa58b8872353524d38"></a><!-- doxytag: member="PPB_UDPSocket::SendTo" ref="ad6b1bd2a28fdc4fa58b8872353524d38" args=")(PP_Resource udp_socket, const char *buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">PPB_UDPSocket::SendTo</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38">PPB_UDPSocket::SendTo</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -176,15 +176,15 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_INPROGRESS</code> will be returned if the socket is busy sending. The caller should wait until a pending send completes before retrying. </dd></dl> </div> </div> -<a class="anchor" id="a3def770b12177d3fa8faf36e184cc528"></a><!-- doxytag: member="PPB_UDPSocket::SetOption" ref="a3def770b12177d3fa8faf36e184cc528" args=")(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="a7107524b673568e4e69c63c43ecd0eec"></a><!-- doxytag: member="PPB_UDPSocket::SetOption" ref="a7107524b673568e4e69c63c43ecd0eec" args=")(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">PPB_UDPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a7107524b673568e4e69c63c43ecd0eec">PPB_UDPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__1__0.html similarity index 74% rename from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html rename to native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__1__0.html index 1cc6802..c8dd134 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html +++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__1__0.html
@@ -12,35 +12,35 @@ <!-- doxytag: class="PPB_VideoDecoder" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Video decoder interface. </p> <p>Typical usage:</p> <ul> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> <li>To destroy the decoder, the plugin should release all of its references to it. Any pending callbacks will abort before the decoder is destroyed.</li> </ul> <p>Available video codecs vary by platform. All: theora, vorbis, vp8. Chrome and ChromeOS: aac, h264. ChromeOS: mpeg4. </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="aaca90b3aba351b89cd777c8c563360c4"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="aaca90b3aba351b89cd777c8c563360c4" args=")(PP_Instance instance)" --> +<a class="anchor" id="a81200f606c493c49a70190ca86ac135c"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="a81200f606c493c49a70190ca86ac135c" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -55,45 +55,45 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a video decoder if successful or 0 otherwise. </dd></dl> </div> </div> -<a class="anchor" id="ad2e85b80316537e0e01724e1b1875a15"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="ad2e85b80316537e0e01724e1b1875a15" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="acc8662be4232325abc545d1ae8b79366"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="acc8662be4232325abc545d1ae8b79366" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Decodes a bitstream buffer. </p> -<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> again.</p> +<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> again.</p> <p>In general, each bitstream buffer should contain a demuxed bitstream frame for the selected video codec. For example, H264 decoders expect to receive one AnnexB NAL unit, including the 4 byte start code prefix, while VP8 decoders expect to receive a bitstream frame without the IVF frame header.</p> -<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> +<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">size</td><td>Buffer size in bytes. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>Starting address of buffer. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a1a85da162f50990f318ff8bff61ceacc"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="a1a85da162f50990f318ff8bff61ceacc" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="adf3ea0876d1ba686266589a04532e86d"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="adf3ea0876d1ba686266589a04532e86d" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Flushes the decoder. </p> -<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> +<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -104,18 +104,18 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> </div> </div> -<a class="anchor" id="a53284466cb36653f3d91a4889b292811"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a53284466cb36653f3d91a4889b292811" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="a2351fe0cf66513ee77df0c1a22306c3e"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a2351fe0cf66513ee77df0c1a22306c3e" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Gets the next picture from the decoder. </p> -<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> +<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -124,21 +124,21 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a821341ce72fe1db025913f562626b119"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="a821341ce72fe1db025913f562626b119" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad115b7705b740b771e7dd9acb2b36f16"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="ad115b7705b740b771e7dd9acb2b36f16" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Initializes a video decoder resource. </p> -<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> +<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -149,15 +149,15 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> </div> </div> -<a class="anchor" id="a3748268a6df835f3eb661b0c690c37bb"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="a3748268a6df835f3eb661b0c690c37bb" args=")(PP_Resource resource)" --> +<a class="anchor" id="ae2329143c44bd5eaae507074c1fc0ec3"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="ae2329143c44bd5eaae507074c1fc0ec3" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -172,12 +172,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the resource is a <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is invalid or some other type. </dd></dl> </div> </div> -<a class="anchor" id="a30fbc6abf22cae02032bdc713ee41d1e"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="a30fbc6abf22cae02032bdc713ee41d1e" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> +<a class="anchor" id="ac7e6b42866d42eade96519f32755509f"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="ac7e6b42866d42eade96519f32755509f" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> </tr> </table> </div> @@ -193,18 +193,18 @@ </dl> </div> </div> -<a class="anchor" id="a4697495911e69da035d786dc69ce22ca"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="a4697495911e69da035d786dc69ce22ca" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aeb4704cfd86a4ad737af19e77f3ffd5e"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="aeb4704cfd86a4ad737af19e77f3ffd5e" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Resets the decoder as quickly as possible. </p> -<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> +<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_u_d_p_socket.html b/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_u_d_p_socket.html index e864cb5..c0bf3229 100644 --- a/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_u_d_p_socket.html +++ b/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_u_d_p_socket.html
@@ -356,7 +356,7 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code>pp_errors.h</code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code>pp_errors.h</code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_INPROGRESS</code> will be returned if the socket is busy sending. The caller should wait until a pending send completes before retrying. </dd></dl> </div> </div> <a class="anchor" id="a5ff91fd2342e534b57980c0c2e414251"></a><!-- doxytag: member="pp::UDPSocket::SetOption" ref="a5ff91fd2342e534b57980c0c2e414251" args="(PP_UDPSocket_Option name, const Var &value, const CompletionCallback &callback)" -->
diff --git a/native_client_sdk/doc_generated/pepper_beta/index.html b/native_client_sdk/doc_generated/pepper_beta/index.html index 41ffd8f..882199b 100644 --- a/native_client_sdk/doc_generated/pepper_beta/index.html +++ b/native_client_sdk/doc_generated/pepper_beta/index.html
@@ -2,8 +2,8 @@ <section id="pepper-api-reference-beta"> <h1 id="pepper-api-reference-beta">Pepper API Reference (Beta)</h1> -<p>This page lists the API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher.</p> +<p>This page lists the API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher.</p> <h2 id="pepper-c-api-reference"><a class="reference internal" href="/native-client/c-api-beta.html#pepper-beta-c-index"><em>Pepper C API Reference</em></a></h2> <h2 id="id1"><a class="reference internal" href="/native-client/cpp-api-beta.html#pepper-beta-cpp-index"><em>Pepper C++ API Reference</em></a></h2> </section>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/globals_defs.html b/native_client_sdk/doc_generated/pepper_dev/c/globals_defs.html index cc82f25..ec7106fe 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/globals_defs.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/globals_defs.html
@@ -244,8 +244,8 @@ <li>PPB_TCPSOCKET_INTERFACE : <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">ppb_tcp_socket.h</a> </li> -<li>PPB_TCPSOCKET_INTERFACE_1_1 -: <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">ppb_tcp_socket.h</a> +<li>PPB_TCPSOCKET_INTERFACE_1_2 +: <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">ppb_tcp_socket.h</a> </li> <li>PPB_TEXTINPUTCONTROLLER_INTERFACE : <a class="el" href="ppb__text__input__controller_8h.html#a9a28f7fd2db84c2cd550ed272070c0ee">ppb_text_input_controller.h</a> @@ -262,8 +262,8 @@ <li>PPB_UDPSOCKET_INTERFACE : <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">ppb_udp_socket.h</a> </li> -<li>PPB_UDPSOCKET_INTERFACE_1_0 -: <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">ppb_udp_socket.h</a> +<li>PPB_UDPSOCKET_INTERFACE_1_1 +: <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">ppb_udp_socket.h</a> </li> <li>PPB_URLLOADER_INTERFACE : <a class="el" href="ppb__url__loader_8h.html#ae1fa8c5cdfccb7ea67e184b1e5e1009e">ppb_url_loader.h</a> @@ -310,8 +310,8 @@ <li>PPB_VIDEODECODER_INTERFACE : <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">ppb_video_decoder.h</a> </li> -<li>PPB_VIDEODECODER_INTERFACE_0_2 -: <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">ppb_video_decoder.h</a> +<li>PPB_VIDEODECODER_INTERFACE_1_0 +: <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">ppb_video_decoder.h</a> </li> <li>PPB_VIDEOFRAME_INTERFACE : <a class="el" href="ppb__video__frame_8h.html#ac161d8c49f583eda31622d9fc010cd0d">ppb_video_frame.h</a>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/group___enums.html b/native_client_sdk/doc_generated/pepper_dev/c/group___enums.html index 237129e..3bd2e7d 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/group___enums.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/group___enums.html
@@ -1644,16 +1644,16 @@ <dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0"> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_NO_DELAY" ref="gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10" args="" -->PP_TCPSOCKET_OPTION_NO_DELAY</em> </td><td> <p>Disables coalescing of small writes to make TCP segments, and instead delivers data immediately. </p> -<p>Value's type is <code>PP_VARTYPE_BOOL</code>. This option can only be set after a successful <code>Connect()</code> call. </p> +<p>Value's type is <code>PP_VARTYPE_BOOL</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12a61ce27ba7853d05f7af51be1bed5d1a6"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE" ref="gga1557c0bbce8739a3418e6027a9c44e12a61ce27ba7853d05f7af51be1bed5d1a6" args="" -->PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for sends. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Connect()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1557c0bbce8739a3418e6027a9c44e12aef57736e294acb30fb7b3b2f4a425f72"></a><!-- doxytag: member="PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE" ref="gga1557c0bbce8739a3418e6027a9c44e12aef57736e294acb30fb7b3b2f4a425f72" args="" -->PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for receives. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Connect()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.1 or earlier, this option can only be set after a successful <code>Connect()</code> call. On version 1.2 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> </table> @@ -1741,16 +1741,16 @@ </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2aeceda8fe978a52382b96939de7707c00"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_BROADCAST" ref="gga1a8472fa3e7150615c45c38fa8c12ce2aeceda8fe978a52382b96939de7707c00" args="" -->PP_UDPSOCKET_OPTION_BROADCAST</em> </td><td> <p>Allows sending and receiving packets to and from broadcast addresses. </p> -<p>Value's type should be <code>PP_VARTYPE_BOOL</code>. This option can only be set before calling <code>Bind()</code>. </p> +<p>Value's type should be <code>PP_VARTYPE_BOOL</code>. On version 1.0, this option can only be set before calling <code>Bind()</code>. On version 1.1 or later, there is no such limitation. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2a905f0adde2912a5db26883d45fb75d57"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE" ref="gga1a8472fa3e7150615c45c38fa8c12ce2a905f0adde2912a5db26883d45fb75d57" args="" -->PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for sends. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Bind()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.0, this option can only be set after a successful <code>Bind()</code> call. On version 1.1 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> <tr><td valign="top"><em><a class="anchor" id="gga1a8472fa3e7150615c45c38fa8c12ce2a1264eb1d6d16eb3a074ee3d21ebb3b64"></a><!-- doxytag: member="PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE" ref="gga1a8472fa3e7150615c45c38fa8c12ce2a1264eb1d6d16eb3a074ee3d21ebb3b64" args="" -->PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE</em> </td><td> <p>Specifies the total per-socket buffer space reserved for receives. </p> -<p>Value's type should be <code>PP_VARTYPE_INT32</code>. This option can only be set after a successful <code>Bind()</code> call.</p> +<p>Value's type should be <code>PP_VARTYPE_INT32</code>. On version 1.0, this option can only be set after a successful <code>Bind()</code> call. On version 1.1 or later, there is no such limitation.</p> <p>Note: This is only treated as a hint for the browser to set the buffer size. Even if <code>SetOption()</code> succeeds, the browser doesn't guarantee it will conform to the size. </p> </td></tr> </table>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/group___interfaces.html b/native_client_sdk/doc_generated/pepper_dev/c/group___interfaces.html index 14ed4c5..e4a64ed8 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/group___interfaces.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/group___interfaces.html
@@ -90,12 +90,12 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html">PPB_OpenGLES2Query</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__2.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code>PPB_TextInputController</code> provides a set of functions for giving hints to the browser about the text input status of plugins, and functions for controlling input method editors (IMEs). <a href="struct_p_p_b___text_input_controller__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <b>PPB_URLLoader</b> interface contains pointers to functions for loading URLs. <a href="struct_p_p_b___u_r_l_loader__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a></td></tr> @@ -109,8 +109,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_VarArrayBuffer</code> interface provides a way to interact with JavaScript ArrayBuffers, which represent a contiguous sequence of bytes. <a href="struct_p_p_b___var_array_buffer__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">A dictionary var contains key-value pairs with unique keys. <a href="struct_p_p_b___var_dictionary__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__2.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code>PPB_View</code> represents the state of the view of an instance. <a href="struct_p_p_b___view__1__2.html#details">More...</a><br /></td></tr> @@ -166,10 +166,10 @@ <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___network_monitor__1__0.html">PPB_NetworkMonitor</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga873d8c5cd49f7b3c8ad5b4caabd1e8e6">PPB_NetworkMonitor</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___network_proxy__1__0.html">PPB_NetworkProxy</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf8338a682417267c8525446ef1de85b1">PPB_NetworkProxy</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab387085f6044f3a0b1631d119d22a942">PPB_TextInputController</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_r_l_loader__1__0.html">PPB_URLLoader</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga307f562a9e41991de7c80b75cd7f379c">PPB_URLLoader</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___u_r_l_request_info__1__0.html">PPB_URLRequestInfo</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad60387934d9e235d3d145ee5a1fb4e74">PPB_URLRequestInfo</a></td></tr> @@ -181,7 +181,7 @@ <a class="el" href="struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab26d5bb032f5438d02faf5bdf7b208cb">PPB_VarArrayBuffer</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga69826004b5c32232c9639090f3e1db2e">PPB_VarDictionary</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaa76d004c840f6c4f64a0694e7c844ae9">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga116e11e23c92c99094c9704d97636a67">PPB_View</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad0e152d14cefb0b480228f3fc7070faf">PPB_WebSocket</a></td></tr> @@ -530,12 +530,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="ga0f72e14a6cf9631bd733ded1f8ba4d9f"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSocket" ref="ga0f72e14a6cf9631bd733ded1f8ba4d9f" args="" --> +<a class="anchor" id="ga68e25baffc8cfc72d6c636a3a6217aa0"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSocket" ref="ga68e25baffc8cfc72d6c636a3a6217aa0" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> <a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> <a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td> </tr> </table> </div> @@ -566,12 +566,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="gaf04d893ccf01c5d1cfcadee5fcc869d1"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSocket" ref="gaf04d893ccf01c5d1cfcadee5fcc869d1" args="" --> +<a class="anchor" id="ga03552c99ad9e2a408a988822f834f548"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSocket" ref="ga03552c99ad9e2a408a988822f834f548" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> <a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> <a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td> </tr> </table> </div> @@ -662,12 +662,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="gaaab5a6b6d09e6a2eea4e11c63c3c1b4f"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="gaaab5a6b6d09e6a2eea4e11c63c3c1b4f" args="" --> +<a class="anchor" id="ga2b4555d8bd239fa28b60c42df75f7ce5"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="ga2b4555d8bd239fa28b60c42df75f7ce5" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/group___structs.html b/native_client_sdk/doc_generated/pepper_dev/c/group___structs.html index 1a4f153..1bf6366 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/group___structs.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/group___structs.html
@@ -15,6 +15,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">A structure that defines a way for the browser to return arrays of data to the plugin. <a href="struct_p_p___array_output.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> is a common mechanism for supporting potentially asynchronous calls in browser interfaces. <a href="struct_p_p___completion_callback.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___directory_entry.html">PP_DirectoryEntry</a></td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h.html b/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h.html index 88d9df4..c9cbed88 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h.html
@@ -21,6 +21,8 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> { <br />
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h__incl.png b/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h__incl.png index fcefc9dd..e74f895 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_dev/c/pp__codecs_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/ppb__tcp__socket_8h.html b/native_client_sdk/doc_generated/pepper_dev/c/ppb__tcp__socket_8h.html index 516526e55..ea5a225 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/ppb__tcp__socket_8h.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/ppb__tcp__socket_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__2.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.1"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.2"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga0f72e14a6cf9631bd733ded1f8ba4d9f">PPB_TCPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html">PPB_TCPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga68e25baffc8cfc72d6c636a3a6217aa0">PPB_TCPSocket</a></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> { <a class="el" href="group___enums.html#gga1557c0bbce8739a3418e6027a9c44e12a4b17558654d1df4452aa98f7d2609a10">PP_TCPSOCKET_OPTION_NO_DELAY</a> = 0, @@ -46,19 +46,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">PPB_TCPSOCKET_INTERFACE</a>   <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="a12b0fabc454cb99a6d4c8352c6f22d71"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSOCKET_INTERFACE" ref="a12b0fabc454cb99a6d4c8352c6f22d71" args="" --> +<a class="anchor" id="a2f1cedfee70f4bfe4c35849be53fd73f"></a><!-- doxytag: member="ppb_tcp_socket.h::PPB_TCPSOCKET_INTERFACE" ref="a2f1cedfee70f4bfe4c35849be53fd73f" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a12b0fabc454cb99a6d4c8352c6f22d71">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.1"</td> +<td class="memname">#define <a class="el" href="ppb__tcp__socket_8h.html#a2f1cedfee70f4bfe4c35849be53fd73f">PPB_TCPSOCKET_INTERFACE</a>   "PPB_TCPSocket;1.2"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/ppb__udp__socket_8h.html b/native_client_sdk/doc_generated/pepper_dev/c/ppb__udp__socket_8h.html index 7cb5823..130ae3d 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/ppb__udp__socket_8h.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/ppb__udp__socket_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_UDPSocket</code> interface provides UDP socket operations. <a href="struct_p_p_b___u_d_p_socket__1__1.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.0"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.1"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaf04d893ccf01c5d1cfcadee5fcc869d1">PPB_UDPSocket</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html">PPB_UDPSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga03552c99ad9e2a408a988822f834f548">PPB_UDPSocket</a></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> { <a class="el" href="group___enums.html#gga1a8472fa3e7150615c45c38fa8c12ce2a79568403b8927bf98bea0f2d38469984">PP_UDPSOCKET_OPTION_ADDRESS_REUSE</a> = 0, @@ -47,19 +47,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a673aeb3fceb5ed977b7b8683f674cbfd">PPB_UDPSOCKET_INTERFACE</a>   <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="aafc1aecb9a8f2c3f8eed80a93a77763c"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSOCKET_INTERFACE" ref="aafc1aecb9a8f2c3f8eed80a93a77763c" args="" --> +<a class="anchor" id="a756bacac14becc5cbc2efedcd3ccd509"></a><!-- doxytag: member="ppb_udp_socket.h::PPB_UDPSOCKET_INTERFACE" ref="a756bacac14becc5cbc2efedcd3ccd509" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#aafc1aecb9a8f2c3f8eed80a93a77763c">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.0"</td> +<td class="memname">#define <a class="el" href="ppb__udp__socket_8h.html#a756bacac14becc5cbc2efedcd3ccd509">PPB_UDPSOCKET_INTERFACE</a>   "PPB_UDPSocket;1.1"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h.html b/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h.html index 8248cf0..212d41ab 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__2.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.2"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__2.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaaab5a6b6d09e6a2eea4e11c63c3c1b4f">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>This file defines the <code>PPB_VideoDecoder</code> interface. </p> @@ -37,19 +37,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="a72520f2e97ea5a9a2225fb100c577877"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="a72520f2e97ea5a9a2225fb100c577877" args="" --> +<a class="anchor" id="af814c8f0028bce254da6fb5c3e61a4d8"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="af814c8f0028bce254da6fb5c3e61a4d8" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#a72520f2e97ea5a9a2225fb100c577877">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.2"</td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h__incl.png b/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h__incl.png index 0d6c946..6456426 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_dev/c/ppb__video__decoder_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture.html index 2bf52aca..8e19d4e3 100644 --- a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture.html
@@ -16,6 +16,7 @@ <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#ae1a9b538db9e422e9f4c9126e941ea25">texture_id</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a5e2d5f24f86223ad71f2efb83116f118">texture_target</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a0f3c7022b44215e06f98f771f75641cc">texture_size</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">visible_rect</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Struct describing a decoded video picture. </p> @@ -77,6 +78,20 @@ <p>The pixel format of the texture is GL_RGBA. </p> </div> </div> +<a class="anchor" id="a1068a6b0ec8376cadcc7b08e607085f2"></a><!-- doxytag: member="PP_VideoPicture::visible_rect" ref="a1068a6b0ec8376cadcc7b08e607085f2" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> <a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">PP_VideoPicture::visible_rect</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The visible subrectangle of the picture. </p> +<p>The plugin should display only this part of the picture. </p> +</div> +</div> <hr />The documentation for this struct was generated from the following file:<ul> <li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> </ul>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture__0__1.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture__0__1.html new file mode 100644 index 0000000..1710cdf --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p___video_picture__0__1.html
@@ -0,0 +1,85 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PP_VideoPicture Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PP_VideoPicture" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">decode_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">texture_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">texture_target</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">texture_size</a></td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>Struct describing a decoded video picture. </p> +<p>The decoded picture data is stored in the GL texture corresponding to |texture_id|. The plugin can determine which Decode call generated the picture using |decode_id|. </p> +</div><hr /><h2>Field Documentation</h2> +<a class="anchor" id="a5745b95f0df115201c6ac1eab564cf2e"></a><!-- doxytag: member="PP_VideoPicture::decode_id" ref="a5745b95f0df115201c6ac1eab564cf2e" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">PP_VideoPicture::decode_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>|decode_id| parameter of the Decode call which generated this picture. </p> +<p>See the PPB_VideoDecoder function Decode() for more details. </p> +</div> +</div> +<a class="anchor" id="a8ee7a6fdddbf71d429a16f7779af6f0f"></a><!-- doxytag: member="PP_VideoPicture::texture_id" ref="a8ee7a6fdddbf71d429a16f7779af6f0f" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">PP_VideoPicture::texture_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Texture ID in the plugin's GL context. </p> +<p>The plugin can use this to render the decoded picture. </p> +</div> +</div> +<a class="anchor" id="aeed32ff6cc3c52d51b0a5179904e5676"></a><!-- doxytag: member="PP_VideoPicture::texture_size" ref="aeed32ff6cc3c52d51b0a5179904e5676" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> <a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">PP_VideoPicture::texture_size</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Dimensions of the texture holding the decoded picture. </p> +</div> +</div> +<a class="anchor" id="af73723a3d48c5b8ae027826dccfdc88c"></a><!-- doxytag: member="PP_VideoPicture::texture_target" ref="af73723a3d48c5b8ae027826dccfdc88c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">PP_VideoPicture::texture_target</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The GL texture target for the decoded picture. </p> +<p>Possible values are: GL_TEXTURE_2D GL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_EXTERNAL_OES</p> +<p>The pixel format of the texture is GL_RGBA. </p> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__1.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__1.html deleted file mode 100644 index d9d5a0d2..0000000 --- a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__1.html +++ /dev/null
@@ -1,321 +0,0 @@ -{{+bindTo:partials.standard_nacl_api}} -<h1>PPB_TCPSocket Struct Reference</h1> -<div id="doxygen-ref"> -{{- dummy div to appease doxygen -}} - <div> -<!-- Generated by Doxygen 1.7.6.1 --> - - -</div> -<!--header--> -<div class="contents"> -<!-- doxytag: class="PPB_TCPSocket" --><h2> -Data Fields</h2><table class="memberdecls"> - -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">IsTCPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">Connect</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">GetLocalAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">GetRemoteAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">Read</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">Write</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">Listen</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">Accept</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -</table> -<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>The <code>PPB_TCPSocket</code> interface provides TCP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>tcp-connect</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code>; subrule <code>tcp-listen</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> -</div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a444d931c7fbb40e47cca8c55d57250f7"></a><!-- doxytag: member="PPB_TCPSocket::Accept" ref="a444d931c7fbb40e47cca8c55d57250f7" args=")(PP_Resource tcp_socket, PP_Resource *accepted_tcp_socket, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">PPB_TCPSocket::Accept</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Accepts a connection. </p> -<p>The socket must be listening.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">accepted_tcp_socket</td><td>Stores the accepted TCP socket on success. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>, including (but not limited to):<ul> -<li><code>PP_ERROR_CONNECTION_ABORTED</code>: A connection has been aborted. </li> -</ul> -</dd></dl> -</div> -</div> -<a class="anchor" id="aae9a2f9ced445ca28a21721a0df5c567"></a><!-- doxytag: member="PPB_TCPSocket::Bind" ref="aae9a2f9ced445ca28a21721a0df5c567" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">PPB_TCPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Binds the socket to the given address. </p> -<p>The socket must not be bound.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">addr</td><td>A <code>PPB_NetAddress</code> resource. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>, including (but not limited to):<ul> -<li><code>PP_ERROR_ADDRESS_IN_USE</code>: the address is already in use.</li> -<li><code>PP_ERROR_ADDRESS_INVALID</code>: the address is invalid. </li> -</ul> -</dd></dl> -</div> -</div> -<a class="anchor" id="afc2d9d7577df96bd0ac8f3cc6f503266"></a><!-- doxytag: member="PPB_TCPSocket::Close" ref="afc2d9d7577df96bd0ac8f3cc6f503266" args=")(PP_Resource tcp_socket)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">PPB_TCPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Cancels all pending operations and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output buffer pointers passed into previous <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32" title="Reads data from the socket.">Read()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7" title="Accepts a connection.">Accept()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code> again.</p> -<p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -</table> -</dd> -</dl> -</div> -</div> -<a class="anchor" id="a1d12313b4681e48fa6f9b789d26414cb"></a><!-- doxytag: member="PPB_TCPSocket::Connect" ref="a1d12313b4681e48fa6f9b789d26414cb" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">PPB_TCPSocket::Connect</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Connects the socket to the given address. </p> -<p>The socket must not be listening. Binding the socket beforehand is optional.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">addr</td><td>A <code>PPB_NetAddress</code> resource. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>, including (but not limited to):<ul> -<li><code>PP_ERROR_NOACCESS</code>: the caller doesn't have required permissions.</li> -<li><code>PP_ERROR_ADDRESS_UNREACHABLE</code>: <code>addr</code> is unreachable.</li> -<li><code>PP_ERROR_CONNECTION_REFUSED</code>: the connection attempt was refused.</li> -<li><code>PP_ERROR_CONNECTION_FAILED</code>: the connection attempt failed.</li> -<li><code>PP_ERROR_CONNECTION_TIMEDOUT</code>: the connection attempt timed out.</li> -</ul> -</dd></dl> -<p>Since version 1.1, if the socket is listening/connected or has a pending listen/connect request, <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> will fail without starting a connection attempt; otherwise, any failure during the connection attempt will cause the socket to be closed. </p> -</div> -</div> -<a class="anchor" id="a615cb349fbe99e25ae09078091c87b43"></a><!-- doxytag: member="PPB_TCPSocket::Create" ref="a615cb349fbe99e25ae09078091c87b43" args=")(PP_Instance instance)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">PPB_TCPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Creates a TCP socket resource. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a TCP socket or 0 on failure. </dd></dl> -</div> -</div> -<a class="anchor" id="ab64edd222b040500767f5c9182358b68"></a><!-- doxytag: member="PPB_TCPSocket::GetLocalAddress" ref="ab64edd222b040500767f5c9182358b68" args=")(PP_Resource tcp_socket)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">PPB_TCPSocket::GetLocalAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Gets the local address of the socket, if it is bound. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> -</div> -</div> -<a class="anchor" id="af28b600fcdf657ca31dd2e9218a774e1"></a><!-- doxytag: member="PPB_TCPSocket::GetRemoteAddress" ref="af28b600fcdf657ca31dd2e9218a774e1" args=")(PP_Resource tcp_socket)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">PPB_TCPSocket::GetRemoteAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Gets the remote address of the socket, if it is connected. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> -</div> -</div> -<a class="anchor" id="afe32ae060181370e12c93c206964a58f"></a><!-- doxytag: member="PPB_TCPSocket::IsTCPSocket" ref="afe32ae060181370e12c93c206964a58f" args=")(PP_Resource resource)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">PPB_TCPSocket::IsTCPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Determines if a given resource is a TCP socket. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">resource</td><td>A <code>PP_Resource</code> to check.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_TCPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> -</div> -</div> -<a class="anchor" id="af3b28d2bf3f44d89e434e158854bea69"></a><!-- doxytag: member="PPB_TCPSocket::Listen" ref="af3b28d2bf3f44d89e434e158854bea69" args=")(PP_Resource tcp_socket, int32_t backlog, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">PPB_TCPSocket::Listen</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Starts listening. </p> -<p>The socket must be bound and not connected.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">backlog</td><td>A hint to determine the maximum length to which the queue of pending connections may grow. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>, including (but not limited to):<ul> -<li><code>PP_ERROR_NOACCESS</code>: the caller doesn't have required permissions.</li> -<li><code>PP_ERROR_ADDRESS_IN_USE</code>: Another socket is already listening on the same port. </li> -</ul> -</dd></dl> -</div> -</div> -<a class="anchor" id="ab4bd707da2d9d2136c59a08b3de2ce32"></a><!-- doxytag: member="PPB_TCPSocket::Read" ref="ab4bd707da2d9d2136c59a08b3de2ce32" args=")(PP_Resource tcp_socket, char *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">PPB_TCPSocket::Read</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Reads data from the socket. </p> -<p>The socket must be connected. It may perform a partial read.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">buffer</td><td>The buffer to store the received data on success. It must be at least as large as <code>bytes_to_read</code>. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">bytes_to_read</td><td>The number of bytes to read. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been read, 0 means that end-of-file was reached; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> -</div> -</div> -<a class="anchor" id="ab64ed8f1f7b4c3dce8d3493fb894ea0d"></a><!-- doxytag: member="PPB_TCPSocket::SetOption" ref="ab64ed8f1f7b4c3dce8d3493fb894ea0d" args=")(PP_Resource tcp_socket, PP_TCPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">PPB_TCPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Sets a socket option on the TCP socket. </p> -<p>Please see the <code>PP_TCPSocket_Option</code> description for option names, value types and allowed values.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">name</td><td>The option to set. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">value</td><td>The option value to set. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> -</div> -</div> -<a class="anchor" id="adea2cbc4e8487f2f26c2126983f9c856"></a><!-- doxytag: member="PPB_TCPSocket::Write" ref="adea2cbc4e8487f2f26c2126983f9c856" args=")(PP_Resource tcp_socket, const char *buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">PPB_TCPSocket::Write</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Writes data to the socket. </p> -<p>The socket must be connected. It may perform a partial write.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">tcp_socket</td><td>A <code>PP_Resource</code> corresponding to a TCP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>The buffer containing the data to write. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">bytes_to_write</td><td>The number of bytes to write. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been written; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> -</div> -</div> -<hr />The documentation for this struct was generated from the following file:<ul> -<li><a class="el" href="ppb__tcp__socket_8h.html">ppb_tcp_socket.h</a></li> -</ul> -</div><!-- contents --> -</div> -{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__2.html similarity index 80% copy from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html copy to native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__2.html index d9d5a0d2..7b0a919 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___t_c_p_socket__1__2.html
@@ -12,29 +12,29 @@ <!-- doxytag: class="PPB_TCPSocket" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">IsTCPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">Connect</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">GetLocalAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">GetRemoteAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">Read</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">Write</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">Listen</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">Accept</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a889fb7b3263304ef5057cd541a197312">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5355f00c99cd7fb9563eb9987a73a3c5">IsTCPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aeb78a27cd902e93c557a0015812237f9">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939">Connect</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5916aca75506efccaa2905bb758421a2">GetLocalAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#abb362a218eef33522ea9b508d482a015">GetRemoteAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1">Read</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ac798b76c497f00231bd592ebdb584042">Write</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d">Listen</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a">Accept</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a6ca1887389cfaf357054e016adf7fc77">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aa42176651e65cf589fc310c0b2ed5751">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>The <code>PPB_TCPSocket</code> interface provides TCP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>tcp-connect</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code>; subrule <code>tcp-listen</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> +<p>Permissions: Apps permission <code>socket</code> with subrule <code>tcp-connect</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code>; subrule <code>tcp-listen</code> is required for <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d" title="Starts listening.">Listen()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a444d931c7fbb40e47cca8c55d57250f7"></a><!-- doxytag: member="PPB_TCPSocket::Accept" ref="a444d931c7fbb40e47cca8c55d57250f7" args=")(PP_Resource tcp_socket, PP_Resource *accepted_tcp_socket, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad9b1525032df05cf446f7d7c27c6145a"></a><!-- doxytag: member="PPB_TCPSocket::Accept" ref="ad9b1525032df05cf446f7d7c27c6145a" args=")(PP_Resource tcp_socket, PP_Resource *accepted_tcp_socket, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7">PPB_TCPSocket::Accept</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a">PPB_TCPSocket::Accept</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *accepted_tcp_socket, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -55,12 +55,12 @@ </dd></dl> </div> </div> -<a class="anchor" id="aae9a2f9ced445ca28a21721a0df5c567"></a><!-- doxytag: member="PPB_TCPSocket::Bind" ref="aae9a2f9ced445ca28a21721a0df5c567" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aeb78a27cd902e93c557a0015812237f9"></a><!-- doxytag: member="PPB_TCPSocket::Bind" ref="aeb78a27cd902e93c557a0015812237f9" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#aae9a2f9ced445ca28a21721a0df5c567">PPB_TCPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aeb78a27cd902e93c557a0015812237f9">PPB_TCPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -82,18 +82,18 @@ </dd></dl> </div> </div> -<a class="anchor" id="afc2d9d7577df96bd0ac8f3cc6f503266"></a><!-- doxytag: member="PPB_TCPSocket::Close" ref="afc2d9d7577df96bd0ac8f3cc6f503266" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="a6ca1887389cfaf357054e016adf7fc77"></a><!-- doxytag: member="PPB_TCPSocket::Close" ref="a6ca1887389cfaf357054e016adf7fc77" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afc2d9d7577df96bd0ac8f3cc6f503266">PPB_TCPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a6ca1887389cfaf357054e016adf7fc77">PPB_TCPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> <div class="memdoc"> <p>Cancels all pending operations and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output buffer pointers passed into previous <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32" title="Reads data from the socket.">Read()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a444d931c7fbb40e47cca8c55d57250f7" title="Accepts a connection.">Accept()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69" title="Starts listening.">Listen()</a></code> again.</p> +<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output buffer pointers passed into previous <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1" title="Reads data from the socket.">Read()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad9b1525032df05cf446f7d7c27c6145a" title="Accepts a connection.">Accept()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code> or <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d" title="Starts listening.">Listen()</a></code> again.</p> <p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> @@ -103,12 +103,12 @@ </dl> </div> </div> -<a class="anchor" id="a1d12313b4681e48fa6f9b789d26414cb"></a><!-- doxytag: member="PPB_TCPSocket::Connect" ref="a1d12313b4681e48fa6f9b789d26414cb" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad107b3d5541072b14e2b8acc836b3939"></a><!-- doxytag: member="PPB_TCPSocket::Connect" ref="ad107b3d5541072b14e2b8acc836b3939" args=")(PP_Resource tcp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb">PPB_TCPSocket::Connect</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939">PPB_TCPSocket::Connect</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -131,15 +131,15 @@ <li><code>PP_ERROR_CONNECTION_TIMEDOUT</code>: the connection attempt timed out.</li> </ul> </dd></dl> -<p>Since version 1.1, if the socket is listening/connected or has a pending listen/connect request, <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a1d12313b4681e48fa6f9b789d26414cb" title="Connects the socket to the given address.">Connect()</a></code> will fail without starting a connection attempt; otherwise, any failure during the connection attempt will cause the socket to be closed. </p> +<p>Since version 1.1, if the socket is listening/connected or has a pending listen/connect request, <code><a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ad107b3d5541072b14e2b8acc836b3939" title="Connects the socket to the given address.">Connect()</a></code> will fail without starting a connection attempt; otherwise, any failure during the connection attempt will cause the socket to be closed. </p> </div> </div> -<a class="anchor" id="a615cb349fbe99e25ae09078091c87b43"></a><!-- doxytag: member="PPB_TCPSocket::Create" ref="a615cb349fbe99e25ae09078091c87b43" args=")(PP_Instance instance)" --> +<a class="anchor" id="a889fb7b3263304ef5057cd541a197312"></a><!-- doxytag: member="PPB_TCPSocket::Create" ref="a889fb7b3263304ef5057cd541a197312" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#a615cb349fbe99e25ae09078091c87b43">PPB_TCPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a889fb7b3263304ef5057cd541a197312">PPB_TCPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -154,12 +154,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a TCP socket or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="ab64edd222b040500767f5c9182358b68"></a><!-- doxytag: member="PPB_TCPSocket::GetLocalAddress" ref="ab64edd222b040500767f5c9182358b68" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="a5916aca75506efccaa2905bb758421a2"></a><!-- doxytag: member="PPB_TCPSocket::GetLocalAddress" ref="a5916aca75506efccaa2905bb758421a2" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64edd222b040500767f5c9182358b68">PPB_TCPSocket::GetLocalAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5916aca75506efccaa2905bb758421a2">PPB_TCPSocket::GetLocalAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> @@ -174,12 +174,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="af28b600fcdf657ca31dd2e9218a774e1"></a><!-- doxytag: member="PPB_TCPSocket::GetRemoteAddress" ref="af28b600fcdf657ca31dd2e9218a774e1" args=")(PP_Resource tcp_socket)" --> +<a class="anchor" id="abb362a218eef33522ea9b508d482a015"></a><!-- doxytag: member="PPB_TCPSocket::GetRemoteAddress" ref="abb362a218eef33522ea9b508d482a015" args=")(PP_Resource tcp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af28b600fcdf657ca31dd2e9218a774e1">PPB_TCPSocket::GetRemoteAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#abb362a218eef33522ea9b508d482a015">PPB_TCPSocket::GetRemoteAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket)</td> </tr> </table> </div> @@ -194,12 +194,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="afe32ae060181370e12c93c206964a58f"></a><!-- doxytag: member="PPB_TCPSocket::IsTCPSocket" ref="afe32ae060181370e12c93c206964a58f" args=")(PP_Resource resource)" --> +<a class="anchor" id="a5355f00c99cd7fb9563eb9987a73a3c5"></a><!-- doxytag: member="PPB_TCPSocket::IsTCPSocket" ref="a5355f00c99cd7fb9563eb9987a73a3c5" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#afe32ae060181370e12c93c206964a58f">PPB_TCPSocket::IsTCPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#a5355f00c99cd7fb9563eb9987a73a3c5">PPB_TCPSocket::IsTCPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -214,12 +214,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_TCPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> </div> </div> -<a class="anchor" id="af3b28d2bf3f44d89e434e158854bea69"></a><!-- doxytag: member="PPB_TCPSocket::Listen" ref="af3b28d2bf3f44d89e434e158854bea69" args=")(PP_Resource tcp_socket, int32_t backlog, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="acffd2f5faddf094ccd9638128167259d"></a><!-- doxytag: member="PPB_TCPSocket::Listen" ref="acffd2f5faddf094ccd9638128167259d" args=")(PP_Resource tcp_socket, int32_t backlog, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#af3b28d2bf3f44d89e434e158854bea69">PPB_TCPSocket::Listen</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#acffd2f5faddf094ccd9638128167259d">PPB_TCPSocket::Listen</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, int32_t backlog, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -241,12 +241,12 @@ </dd></dl> </div> </div> -<a class="anchor" id="ab4bd707da2d9d2136c59a08b3de2ce32"></a><!-- doxytag: member="PPB_TCPSocket::Read" ref="ab4bd707da2d9d2136c59a08b3de2ce32" args=")(PP_Resource tcp_socket, char *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aac72febd03fe6e6e5adafcfd2b24a8b1"></a><!-- doxytag: member="PPB_TCPSocket::Read" ref="aac72febd03fe6e6e5adafcfd2b24a8b1" args=")(PP_Resource tcp_socket, char *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab4bd707da2d9d2136c59a08b3de2ce32">PPB_TCPSocket::Read</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aac72febd03fe6e6e5adafcfd2b24a8b1">PPB_TCPSocket::Read</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, char *buffer, int32_t bytes_to_read, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -265,12 +265,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been read, 0 means that end-of-file was reached; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="ab64ed8f1f7b4c3dce8d3493fb894ea0d"></a><!-- doxytag: member="PPB_TCPSocket::SetOption" ref="ab64ed8f1f7b4c3dce8d3493fb894ea0d" args=")(PP_Resource tcp_socket, PP_TCPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aa42176651e65cf589fc310c0b2ed5751"></a><!-- doxytag: member="PPB_TCPSocket::SetOption" ref="aa42176651e65cf589fc310c0b2ed5751" args=")(PP_Resource tcp_socket, PP_TCPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#ab64ed8f1f7b4c3dce8d3493fb894ea0d">PPB_TCPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#aa42176651e65cf589fc310c0b2ed5751">PPB_TCPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, <a class="el" href="group___enums.html#ga1557c0bbce8739a3418e6027a9c44e12">PP_TCPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -289,12 +289,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="adea2cbc4e8487f2f26c2126983f9c856"></a><!-- doxytag: member="PPB_TCPSocket::Write" ref="adea2cbc4e8487f2f26c2126983f9c856" args=")(PP_Resource tcp_socket, const char *buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ac798b76c497f00231bd592ebdb584042"></a><!-- doxytag: member="PPB_TCPSocket::Write" ref="ac798b76c497f00231bd592ebdb584042" args=")(PP_Resource tcp_socket, const char *buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html#adea2cbc4e8487f2f26c2126983f9c856">PPB_TCPSocket::Write</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___t_c_p_socket__1__2.html#ac798b76c497f00231bd592ebdb584042">PPB_TCPSocket::Write</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> tcp_socket, const char *buffer, int32_t bytes_to_write, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__0.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__0.html deleted file mode 100644 index 1fe7d5b..0000000 --- a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__0.html +++ /dev/null
@@ -1,211 +0,0 @@ -{{+bindTo:partials.standard_nacl_api}} -<h1>PPB_UDPSocket Struct Reference</h1> -<div id="doxygen-ref"> -{{- dummy div to appease doxygen -}} - <div> -<!-- Generated by Doxygen 1.7.6.1 --> - - -</div> -<!--header--> -<div class="contents"> -<!-- doxytag: class="PPB_UDPSocket" --><h2> -Data Fields</h2><table class="memberdecls"> - -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">IsUDPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">GetBoundAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">RecvFrom</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">SendTo</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -</table> -<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>The <code>PPB_UDPSocket</code> interface provides UDP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>udp-bind</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code>; subrule <code>udp-send-to</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76" title="Sends data to a specific destination.">SendTo()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> -</div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a0cae18760f8e9c4f06f160edab542c46"></a><!-- doxytag: member="PPB_UDPSocket::Bind" ref="a0cae18760f8e9c4f06f160edab542c46" args=")(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">PPB_UDPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Binds the socket to the given address. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">addr</td><td>A <code>PPB_NetAddress</code> resource. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_ADDRESS_IN_USE</code> will be returned if the address is already in use. </dd></dl> -</div> -</div> -<a class="anchor" id="a8b34e95d8f1ca113f2c806fb9b64d3e9"></a><!-- doxytag: member="PPB_UDPSocket::Close" ref="a8b34e95d8f1ca113f2c806fb9b64d3e9" args=")(PP_Resource udp_socket)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">PPB_UDPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Cancels all pending reads and writes, and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output parameters passed into previous <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2" title="Receives data from the socket and stores the source address.">RecvFrom()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code> again.</p> -<p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket. </td></tr> -</table> -</dd> -</dl> -</div> -</div> -<a class="anchor" id="a48dfac97beb8bef209ea79efaf5b0c32"></a><!-- doxytag: member="PPB_UDPSocket::Create" ref="a48dfac97beb8bef209ea79efaf5b0c32" args=")(PP_Instance instance)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">PPB_UDPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Creates a UDP socket resource. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a UDP socket or 0 on failure. </dd></dl> -</div> -</div> -<a class="anchor" id="aa71b3888a2edf12c7bccd69d4ddcbbb6"></a><!-- doxytag: member="PPB_UDPSocket::GetBoundAddress" ref="aa71b3888a2edf12c7bccd69d4ddcbbb6" args=")(PP_Resource udp_socket)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">PPB_UDPSocket::GetBoundAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Gets the address that the socket is bound to. </p> -<p>The socket must be bound.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> -</div> -</div> -<a class="anchor" id="a90de8c0e342ab04bc6d2439b2e0543a5"></a><!-- doxytag: member="PPB_UDPSocket::IsUDPSocket" ref="a90de8c0e342ab04bc6d2439b2e0543a5" args=")(PP_Resource resource)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">PPB_UDPSocket::IsUDPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Determines if a given resource is a UDP socket. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">resource</td><td>A <code>PP_Resource</code> to check.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_UDPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> -</div> -</div> -<a class="anchor" id="a6f7b8cb60ad4279ac52feba6acca9cc2"></a><!-- doxytag: member="PPB_UDPSocket::RecvFrom" ref="a6f7b8cb60ad4279ac52feba6acca9cc2" args=")(PP_Resource udp_socket, char *buffer, int32_t num_bytes, PP_Resource *addr, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">PPB_UDPSocket::RecvFrom</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Receives data from the socket and stores the source address. </p> -<p>The socket must be bound.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">buffer</td><td>The buffer to store the received data on success. It must be at least as large as <code>num_bytes</code>. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">num_bytes</td><td>The number of bytes to receive. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">addr</td><td>A <code>PPB_NetAddress</code> resource to store the source address on success. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been received; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> -</div> -</div> -<a class="anchor" id="a9b78201046b292b6292f0d5bf55d3f76"></a><!-- doxytag: member="PPB_UDPSocket::SendTo" ref="a9b78201046b292b6292f0d5bf55d3f76" args=")(PP_Resource udp_socket, const char *buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">PPB_UDPSocket::SendTo</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Sends data to a specific destination. </p> -<p>The socket must be bound.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>The buffer containing the data to send. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">num_bytes</td><td>The number of bytes to send. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">addr</td><td>A <code>PPB_NetAddress</code> resource holding the destination address. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. </dd></dl> -</div> -</div> -<a class="anchor" id="a3def770b12177d3fa8faf36e184cc528"></a><!-- doxytag: member="PPB_UDPSocket::SetOption" ref="a3def770b12177d3fa8faf36e184cc528" args=")(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">PPB_UDPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Sets a socket option on the UDP socket. </p> -<p>Please see the <code>PP_UDPSocket_Option</code> description for option names, value types and allowed values.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">udp_socket</td><td>A <code>PP_Resource</code> corresponding to a UDP socket. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">name</td><td>The option to set. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">value</td><td>The option value to set. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> -</div> -</div> -<hr />The documentation for this struct was generated from the following file:<ul> -<li><a class="el" href="ppb__udp__socket_8h.html">ppb_udp_socket.h</a></li> -</ul> -</div><!-- contents --> -</div> -{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__1.html similarity index 79% copy from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html copy to native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__1.html index 1fe7d5b..6307ad0 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___u_d_p_socket__1__1.html
@@ -12,25 +12,25 @@ <!-- doxytag: class="PPB_UDPSocket" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">IsUDPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">GetBoundAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">RecvFrom</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">SendTo</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a687ffa461f068fae0e0cc6694b3157bd">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a122be12f51d87e13cbe33bf30b3bef86">IsUDPSocket</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044">Bind</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a33be83f9c8d91811c9ee20fd04ae9be3">GetBoundAddress</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913">RecvFrom</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38">SendTo</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a9c349fbeb2a9fca70b8ecf0a860d2112">Close</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a7107524b673568e4e69c63c43ecd0eec">SetOption</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>The <code>PPB_UDPSocket</code> interface provides UDP socket operations. </p> -<p>Permissions: Apps permission <code>socket</code> with subrule <code>udp-bind</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code>; subrule <code>udp-send-to</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76" title="Sends data to a specific destination.">SendTo()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> +<p>Permissions: Apps permission <code>socket</code> with subrule <code>udp-bind</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044" title="Binds the socket to the given address.">Bind()</a></code>; subrule <code>udp-send-to</code> is required for <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38" title="Sends data to a specific destination.">SendTo()</a></code>. For more details about network communication permissions, please see: <a href="http://developer.chrome.com/apps/app_network.html">http://developer.chrome.com/apps/app_network.html</a> </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a0cae18760f8e9c4f06f160edab542c46"></a><!-- doxytag: member="PPB_UDPSocket::Bind" ref="a0cae18760f8e9c4f06f160edab542c46" args=")(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ab35f5cda2711b220a2b6c090b469d044"></a><!-- doxytag: member="PPB_UDPSocket::Bind" ref="ab35f5cda2711b220a2b6c090b469d044" args=")(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46">PPB_UDPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044">PPB_UDPSocket::Bind</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -47,18 +47,18 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_ADDRESS_IN_USE</code> will be returned if the address is already in use. </dd></dl> </div> </div> -<a class="anchor" id="a8b34e95d8f1ca113f2c806fb9b64d3e9"></a><!-- doxytag: member="PPB_UDPSocket::Close" ref="a8b34e95d8f1ca113f2c806fb9b64d3e9" args=")(PP_Resource udp_socket)" --> +<a class="anchor" id="a9c349fbeb2a9fca70b8ecf0a860d2112"></a><!-- doxytag: member="PPB_UDPSocket::Close" ref="a9c349fbeb2a9fca70b8ecf0a860d2112" args=")(PP_Resource udp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a8b34e95d8f1ca113f2c806fb9b64d3e9">PPB_UDPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a9c349fbeb2a9fca70b8ecf0a860d2112">PPB_UDPSocket::Close</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> </tr> </table> </div> <div class="memdoc"> <p>Cancels all pending reads and writes, and closes the socket. </p> -<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output parameters passed into previous <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2" title="Receives data from the socket and stores the source address.">RecvFrom()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a0cae18760f8e9c4f06f160edab542c46" title="Binds the socket to the given address.">Bind()</a></code> again.</p> +<p>Any pending callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. After a call to this method, no output parameters passed into previous <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913" title="Receives data from the socket and stores the source address.">RecvFrom()</a></code> calls will be accessed. It is not valid to call <code><a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ab35f5cda2711b220a2b6c090b469d044" title="Binds the socket to the given address.">Bind()</a></code> again.</p> <p>The socket is implicitly closed if it is destroyed, so you are not required to call this method.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> @@ -68,12 +68,12 @@ </dl> </div> </div> -<a class="anchor" id="a48dfac97beb8bef209ea79efaf5b0c32"></a><!-- doxytag: member="PPB_UDPSocket::Create" ref="a48dfac97beb8bef209ea79efaf5b0c32" args=")(PP_Instance instance)" --> +<a class="anchor" id="a687ffa461f068fae0e0cc6694b3157bd"></a><!-- doxytag: member="PPB_UDPSocket::Create" ref="a687ffa461f068fae0e0cc6694b3157bd" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a48dfac97beb8bef209ea79efaf5b0c32">PPB_UDPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a687ffa461f068fae0e0cc6694b3157bd">PPB_UDPSocket::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -88,12 +88,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a UDP socket or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="aa71b3888a2edf12c7bccd69d4ddcbbb6"></a><!-- doxytag: member="PPB_UDPSocket::GetBoundAddress" ref="aa71b3888a2edf12c7bccd69d4ddcbbb6" args=")(PP_Resource udp_socket)" --> +<a class="anchor" id="a33be83f9c8d91811c9ee20fd04ae9be3"></a><!-- doxytag: member="PPB_UDPSocket::GetBoundAddress" ref="a33be83f9c8d91811c9ee20fd04ae9be3" args=")(PP_Resource udp_socket)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#aa71b3888a2edf12c7bccd69d4ddcbbb6">PPB_UDPSocket::GetBoundAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a33be83f9c8d91811c9ee20fd04ae9be3">PPB_UDPSocket::GetBoundAddress</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket)</td> </tr> </table> </div> @@ -109,12 +109,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PPB_NetAddress</code> resource on success or 0 on failure. </dd></dl> </div> </div> -<a class="anchor" id="a90de8c0e342ab04bc6d2439b2e0543a5"></a><!-- doxytag: member="PPB_UDPSocket::IsUDPSocket" ref="a90de8c0e342ab04bc6d2439b2e0543a5" args=")(PP_Resource resource)" --> +<a class="anchor" id="a122be12f51d87e13cbe33bf30b3bef86"></a><!-- doxytag: member="PPB_UDPSocket::IsUDPSocket" ref="a122be12f51d87e13cbe33bf30b3bef86" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a90de8c0e342ab04bc6d2439b2e0543a5">PPB_UDPSocket::IsUDPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a122be12f51d87e13cbe33bf30b3bef86">PPB_UDPSocket::IsUDPSocket</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -129,12 +129,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the input is a <code>PPB_UDPSocket</code> resource; <code>PP_FALSE</code> otherwise. </dd></dl> </div> </div> -<a class="anchor" id="a6f7b8cb60ad4279ac52feba6acca9cc2"></a><!-- doxytag: member="PPB_UDPSocket::RecvFrom" ref="a6f7b8cb60ad4279ac52feba6acca9cc2" args=")(PP_Resource udp_socket, char *buffer, int32_t num_bytes, PP_Resource *addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aa15ebcb5bfc899d2d46f8f25266e4913"></a><!-- doxytag: member="PPB_UDPSocket::RecvFrom" ref="aa15ebcb5bfc899d2d46f8f25266e4913" args=")(PP_Resource udp_socket, char *buffer, int32_t num_bytes, PP_Resource *addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a6f7b8cb60ad4279ac52feba6acca9cc2">PPB_UDPSocket::RecvFrom</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#aa15ebcb5bfc899d2d46f8f25266e4913">PPB_UDPSocket::RecvFrom</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> *addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -154,12 +154,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been received; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. </dd></dl> </div> </div> -<a class="anchor" id="a9b78201046b292b6292f0d5bf55d3f76"></a><!-- doxytag: member="PPB_UDPSocket::SendTo" ref="a9b78201046b292b6292f0d5bf55d3f76" args=")(PP_Resource udp_socket, const char *buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad6b1bd2a28fdc4fa58b8872353524d38"></a><!-- doxytag: member="PPB_UDPSocket::SendTo" ref="ad6b1bd2a28fdc4fa58b8872353524d38" args=")(PP_Resource udp_socket, const char *buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a9b78201046b292b6292f0d5bf55d3f76">PPB_UDPSocket::SendTo</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#ad6b1bd2a28fdc4fa58b8872353524d38">PPB_UDPSocket::SendTo</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, const char *buffer, int32_t num_bytes, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> addr, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> @@ -176,15 +176,15 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_INPROGRESS</code> will be returned if the socket is busy sending. The caller should wait until a pending send completes before retrying. </dd></dl> </div> </div> -<a class="anchor" id="a3def770b12177d3fa8faf36e184cc528"></a><!-- doxytag: member="PPB_UDPSocket::SetOption" ref="a3def770b12177d3fa8faf36e184cc528" args=")(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="a7107524b673568e4e69c63c43ecd0eec"></a><!-- doxytag: member="PPB_UDPSocket::SetOption" ref="a7107524b673568e4e69c63c43ecd0eec" args=")(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__0.html#a3def770b12177d3fa8faf36e184cc528">PPB_UDPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___u_d_p_socket__1__1.html#a7107524b673568e4e69c63c43ecd0eec">PPB_UDPSocket::SetOption</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> udp_socket, <a class="el" href="group___enums.html#ga1a8472fa3e7150615c45c38fa8c12ce2">PP_UDPSocket_Option</a> name, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> value, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__0__2.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__0__2.html deleted file mode 100644 index 1cc6802..0000000 --- a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__0__2.html +++ /dev/null
@@ -1,223 +0,0 @@ -{{+bindTo:partials.standard_nacl_api}} -<h1>PPB_VideoDecoder Struct Reference</h1> -<div id="doxygen-ref"> -{{- dummy div to appease doxygen -}} - <div> -<!-- Generated by Doxygen 1.7.6.1 --> - - -</div> -<!--header--> -<div class="contents"> -<!-- doxytag: class="PPB_VideoDecoder" --><h2> -Data Fields</h2><table class="memberdecls"> - -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -</table> -<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>Video decoder interface. </p> -<p>Typical usage:</p> -<ul> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> -<li>To destroy the decoder, the plugin should release all of its references to it. Any pending callbacks will abort before the decoder is destroyed.</li> -</ul> -<p>Available video codecs vary by platform. All: theora, vorbis, vp8. Chrome and ChromeOS: aac, h264. ChromeOS: mpeg4. </p> -</div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="aaca90b3aba351b89cd777c8c563360c4"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="aaca90b3aba351b89cd777c8c563360c4" args=")(PP_Instance instance)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Creates a new video decoder resource. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying the instance with the video decoder.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a video decoder if successful or 0 otherwise. </dd></dl> -</div> -</div> -<a class="anchor" id="ad2e85b80316537e0e01724e1b1875a15"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="ad2e85b80316537e0e01724e1b1875a15" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Decodes a bitstream buffer. </p> -<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> again.</p> -<p>In general, each bitstream buffer should contain a demuxed bitstream frame for the selected video codec. For example, H264 decoders expect to receive one AnnexB NAL unit, including the 4 byte start code prefix, while VP8 decoders expect to receive a bitstream frame without the IVF frame header.</p> -<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">size</td><td>Buffer size in bytes. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>Starting address of buffer. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> -</div> -</div> -<a class="anchor" id="a1a85da162f50990f318ff8bff61ceacc"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="a1a85da162f50990f318ff8bff61ceacc" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Flushes the decoder. </p> -<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> -</div> -</div> -<a class="anchor" id="a53284466cb36653f3d91a4889b292811"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a53284466cb36653f3d91a4889b292811" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Gets the next picture from the decoder. </p> -<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">picture</td><td>A <code><a class="el" href="struct_p_p___video_picture.html" title="Struct describing a decoded video picture.">PP_VideoPicture</a></code> to hold the decoded picture. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> -</div> -</div> -<a class="anchor" id="a821341ce72fe1db025913f562626b119"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="a821341ce72fe1db025913f562626b119" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Initializes a video decoder resource. </p> -<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">graphics3d_context</td><td>A <code>PPB_Graphics3D</code> resource to use during decoding. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">profile</td><td>A <code>PP_VideoProfile</code> specifying the video codec profile. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">acceleration</td><td>A <code>PP_HardwareAcceleration</code> specifying whether to use a hardware accelerated or a software implementation. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> -</div> -</div> -<a class="anchor" id="a3748268a6df835f3eb661b0c690c37bb"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="a3748268a6df835f3eb661b0c690c37bb" args=")(PP_Resource resource)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Determines if the given resource is a video decoder. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">resource</td><td>A <code>PP_Resource</code> identifying a resource.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the resource is a <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is invalid or some other type. </dd></dl> -</div> -</div> -<a class="anchor" id="a30fbc6abf22cae02032bdc713ee41d1e"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="a30fbc6abf22cae02032bdc713ee41d1e" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Recycles a picture that the plugin has received from the decoder. </p> -<p>The plugin should call this as soon as it has finished using the texture so the decoder can decode more pictures.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">picture</td><td>A <code><a class="el" href="struct_p_p___video_picture.html" title="Struct describing a decoded video picture.">PP_VideoPicture</a></code> to return to the decoder. </td></tr> -</table> -</dd> -</dl> -</div> -</div> -<a class="anchor" id="a4697495911e69da035d786dc69ce22ca"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="a4697495911e69da035d786dc69ce22ca" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Resets the decoder as quickly as possible. </p> -<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> -</div> -</div> -<hr />The documentation for this struct was generated from the following file:<ul> -<li><a class="el" href="ppb__video__decoder_8h.html">ppb_video_decoder.h</a></li> -</ul> -</div><!-- contents --> -</div> -{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__1__0.html similarity index 74% copy from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html copy to native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__1__0.html index 1cc6802..c8dd134 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html +++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___video_decoder__1__0.html
@@ -12,35 +12,35 @@ <!-- doxytag: class="PPB_VideoDecoder" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Video decoder interface. </p> <p>Typical usage:</p> <ul> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> <li>To destroy the decoder, the plugin should release all of its references to it. Any pending callbacks will abort before the decoder is destroyed.</li> </ul> <p>Available video codecs vary by platform. All: theora, vorbis, vp8. Chrome and ChromeOS: aac, h264. ChromeOS: mpeg4. </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="aaca90b3aba351b89cd777c8c563360c4"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="aaca90b3aba351b89cd777c8c563360c4" args=")(PP_Instance instance)" --> +<a class="anchor" id="a81200f606c493c49a70190ca86ac135c"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="a81200f606c493c49a70190ca86ac135c" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -55,45 +55,45 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a video decoder if successful or 0 otherwise. </dd></dl> </div> </div> -<a class="anchor" id="ad2e85b80316537e0e01724e1b1875a15"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="ad2e85b80316537e0e01724e1b1875a15" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="acc8662be4232325abc545d1ae8b79366"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="acc8662be4232325abc545d1ae8b79366" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Decodes a bitstream buffer. </p> -<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> again.</p> +<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> again.</p> <p>In general, each bitstream buffer should contain a demuxed bitstream frame for the selected video codec. For example, H264 decoders expect to receive one AnnexB NAL unit, including the 4 byte start code prefix, while VP8 decoders expect to receive a bitstream frame without the IVF frame header.</p> -<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> +<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">size</td><td>Buffer size in bytes. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>Starting address of buffer. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a1a85da162f50990f318ff8bff61ceacc"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="a1a85da162f50990f318ff8bff61ceacc" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="adf3ea0876d1ba686266589a04532e86d"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="adf3ea0876d1ba686266589a04532e86d" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Flushes the decoder. </p> -<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> +<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -104,18 +104,18 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> </div> </div> -<a class="anchor" id="a53284466cb36653f3d91a4889b292811"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a53284466cb36653f3d91a4889b292811" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="a2351fe0cf66513ee77df0c1a22306c3e"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a2351fe0cf66513ee77df0c1a22306c3e" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Gets the next picture from the decoder. </p> -<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> +<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -124,21 +124,21 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a821341ce72fe1db025913f562626b119"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="a821341ce72fe1db025913f562626b119" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad115b7705b740b771e7dd9acb2b36f16"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="ad115b7705b740b771e7dd9acb2b36f16" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Initializes a video decoder resource. </p> -<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> +<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -149,15 +149,15 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> </div> </div> -<a class="anchor" id="a3748268a6df835f3eb661b0c690c37bb"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="a3748268a6df835f3eb661b0c690c37bb" args=")(PP_Resource resource)" --> +<a class="anchor" id="ae2329143c44bd5eaae507074c1fc0ec3"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="ae2329143c44bd5eaae507074c1fc0ec3" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -172,12 +172,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the resource is a <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is invalid or some other type. </dd></dl> </div> </div> -<a class="anchor" id="a30fbc6abf22cae02032bdc713ee41d1e"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="a30fbc6abf22cae02032bdc713ee41d1e" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> +<a class="anchor" id="ac7e6b42866d42eade96519f32755509f"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="ac7e6b42866d42eade96519f32755509f" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> </tr> </table> </div> @@ -193,18 +193,18 @@ </dl> </div> </div> -<a class="anchor" id="a4697495911e69da035d786dc69ce22ca"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="a4697495911e69da035d786dc69ce22ca" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aeb4704cfd86a4ad737af19e77f3ffd5e"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="aeb4704cfd86a4ad737af19e77f3ffd5e" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Resets the decoder as quickly as possible. </p> -<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> +<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_u_d_p_socket.html b/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_u_d_p_socket.html index e864cb5..c0bf3229 100644 --- a/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_u_d_p_socket.html +++ b/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_u_d_p_socket.html
@@ -356,7 +356,7 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code>pp_errors.h</code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>A non-negative number on success to indicate how many bytes have been sent; otherwise, an error code from <code>pp_errors.h</code>. <code>PP_ERROR_NOACCESS</code> will be returned if the caller doesn't have required permissions. <code>PP_ERROR_INPROGRESS</code> will be returned if the socket is busy sending. The caller should wait until a pending send completes before retrying. </dd></dl> </div> </div> <a class="anchor" id="a5ff91fd2342e534b57980c0c2e414251"></a><!-- doxytag: member="pp::UDPSocket::SetOption" ref="a5ff91fd2342e534b57980c0c2e414251" args="(PP_UDPSocket_Option name, const Var &value, const CompletionCallback &callback)" -->
diff --git a/native_client_sdk/doc_generated/pepper_dev/index.html b/native_client_sdk/doc_generated/pepper_dev/index.html index 31724fdf1..f71a18b3 100644 --- a/native_client_sdk/doc_generated/pepper_dev/index.html +++ b/native_client_sdk/doc_generated/pepper_dev/index.html
@@ -2,8 +2,8 @@ <section id="pepper-api-reference-dev"> <h1 id="pepper-api-reference-dev">Pepper API Reference (Dev)</h1> -<p>This page lists the API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher.</p> +<p>This page lists the API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher.</p> <h2 id="pepper-c-api-reference"><a class="reference internal" href="/native-client/c-api-dev.html#pepper-dev-c-index"><em>Pepper C API Reference</em></a></h2> <h2 id="id1"><a class="reference internal" href="/native-client/cpp-api-dev.html#pepper-dev-cpp-index"><em>Pepper C++ API Reference</em></a></h2> </section>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/globals_defs.html b/native_client_sdk/doc_generated/pepper_stable/c/globals_defs.html index aa9a0801..a088a1b 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/globals_defs.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/globals_defs.html
@@ -148,8 +148,8 @@ <li>PPB_MESSAGING_INTERFACE : <a class="el" href="ppb__messaging_8h.html#a558ca32dad39a710cd217aaa09921d92">ppb_messaging.h</a> </li> -<li>PPB_MESSAGING_INTERFACE_1_0 -: <a class="el" href="ppb__messaging_8h.html#afc64e56f770d45a4556b32cd6568cc77">ppb_messaging.h</a> +<li>PPB_MESSAGING_INTERFACE_1_2 +: <a class="el" href="ppb__messaging_8h.html#a233f5c34216429569a62f30b7210e816">ppb_messaging.h</a> </li> <li>PPB_MOUSE_INPUT_EVENT_INTERFACE : <a class="el" href="ppb__input__event_8h.html#a761fcf6df555946b6c2e1a0b6cd01c5e">ppb_input_event.h</a> @@ -193,6 +193,54 @@ <li>PPB_NETWORKPROXY_INTERFACE_1_0 : <a class="el" href="ppb__network__proxy_8h.html#a51bdbe7e4706cc8c5e455ceb47a34472">ppb_network_proxy.h</a> </li> +<li>PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#af73caac234005d5680c4212ee0414acf">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#ad776fe5d283c4097adc3054cf950f294">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#a0d5f52bc61032e26152508badb6293c6">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#a76831e822b9bd007659a516630b1b81b">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#a2f416acbeae9d68c9c2207683b556da1">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#ad035ea2ecebeb7dcdb46e69404149b0a">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#a8842ed3cc24ad8e5c3e1c63a30479e81">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#a7eaf092d0b7bf7f3da2b3b5bbb44175c">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#ade96920455b0451b4a84dedde8706f0c">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#a63baff589b60f79fac2b62ffe476fe52">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#ab9f1a398bb5caf6e6ac2044c181e4cb4">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#ad557f98c8d78c0704377488bb9878b6a">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_QUERY_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#a5966bff19c1b85d79bfaa773ff919798">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_QUERY_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#af9179ad2e31022ca51f19b7f3fd17f39">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE +: <a class="el" href="ppb__opengles2_8h.html#a2df0836cfb081e5cca1b639f7983b9a6">ppb_opengles2.h</a> +</li> +<li>PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE_1_0 +: <a class="el" href="ppb__opengles2_8h.html#abbc21d78bab2083560b49175e50394de">ppb_opengles2.h</a> +</li> <li>PPB_TCPSOCKET_INTERFACE : <a class="el" href="ppb__tcp__socket_8h.html#a29ecaef1552f19b223e6c93475d8788c">ppb_tcp_socket.h</a> </li> @@ -262,8 +310,8 @@ <li>PPB_VIDEODECODER_INTERFACE : <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">ppb_video_decoder.h</a> </li> -<li>PPB_VIDEODECODER_INTERFACE_0_1 -: <a class="el" href="ppb__video__decoder_8h.html#aa2111c736f441e1443e035d97fec6e60">ppb_video_decoder.h</a> +<li>PPB_VIDEODECODER_INTERFACE_1_0 +: <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">ppb_video_decoder.h</a> </li> <li>PPB_VIDEOFRAME_INTERFACE : <a class="el" href="ppb__video__frame_8h.html#ac161d8c49f583eda31622d9fc010cd0d">ppb_video_frame.h</a>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/group___interfaces.html b/native_client_sdk/doc_generated/pepper_stable/c/group___interfaces.html index 5911ec5..1b8ec48 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/group___interfaces.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/group___interfaces.html
@@ -60,8 +60,8 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___media_stream_video_track__1__0.html">PPB_MediaStreamVideoTrack</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html">PPB_MessageLoop</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">A message loop allows PPAPI calls to be issued on a thread. <a href="struct_p_p_b___message_loop__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__0.html">PPB_Messaging</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. <a href="struct_p_p_b___messaging__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__2.html">PPB_Messaging</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. <a href="struct_p_p_b___messaging__1__2.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___mouse_cursor__1__0.html">PPB_MouseCursor</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_MouseCursor</code> allows setting the mouse cursor. <a href="struct_p_p_b___mouse_cursor__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___mouse_lock__1__0.html">PPB_MouseLock</a></td></tr> @@ -74,6 +74,22 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_NetworkMonitor</code> allows to get network interfaces configuration and monitor network configuration changes. <a href="struct_p_p_b___network_monitor__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___network_proxy__1__0.html">PPB_NetworkProxy</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">This interface provides a way to determine the appropriate proxy settings for a given URL. <a href="struct_p_p_b___network_proxy__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html">PPB_OpenGLES2</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html">PPB_OpenGLES2</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html">PPB_OpenGLES2InstancedArrays</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html">PPB_OpenGLES2InstancedArrays</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html">PPB_OpenGLES2FramebufferBlit</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html">PPB_OpenGLES2FramebufferBlit</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html">PPB_OpenGLES2FramebufferMultisample</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html">PPB_OpenGLES2FramebufferMultisample</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html">PPB_OpenGLES2ChromiumEnableFeature</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html">PPB_OpenGLES2ChromiumEnableFeature</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html">PPB_OpenGLES2ChromiumMapSub</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html">PPB_OpenGLES2ChromiumMapSub</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html">PPB_OpenGLES2Query</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html">PPB_OpenGLES2Query</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___t_c_p_socket__1__1.html">PPB_TCPSocket</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_TCPSocket</code> interface provides TCP socket operations. <a href="struct_p_p_b___t_c_p_socket__1__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___text_input_controller__1__0.html">PPB_TextInputController</a></td></tr> @@ -93,8 +109,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_VarArrayBuffer</code> interface provides a way to interact with JavaScript ArrayBuffers, which represent a contiguous sequence of bytes. <a href="struct_p_p_b___var_array_buffer__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">A dictionary var contains key-value pairs with unique keys. <a href="struct_p_p_b___var_dictionary__1__0.html#details">More...</a><br /></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code>PPB_View</code> represents the state of the view of an instance. <a href="struct_p_p_b___view__1__2.html#details">More...</a><br /></td></tr> @@ -105,6 +121,8 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___input_event__0__1.html">PPP_InputEvent</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___instance__1__1.html">PPP_Instance</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPP_Instance</code> interface contains pointers to a series of functions that you must implement in your module. <a href="struct_p_p_p___instance__1__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPP_MessageHandler</code> interface is implemented by the plugin if the plugin wants to receive messages from a thread other than the main Pepper thread, or if the plugin wants to handle blocking messages which JavaScript may send via postMessageAndAwaitResponse(). <a href="struct_p_p_p___message_handler__0__2.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___messaging__1__0.html">PPP_Messaging</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPP_Messaging</code> interface contains pointers to functions that you must implement to handle postMessage events on the associated DOM element. <a href="struct_p_p_p___messaging__1__0.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___mouse_lock__1__0.html">PPP_MouseLock</a></td></tr> @@ -140,7 +158,7 @@ <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___media_stream_audio_track__0__1.html">PPB_MediaStreamAudioTrack</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga7eb38be0c7c0450e02840804b0b8b9d3">PPB_MediaStreamAudioTrack</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___message_loop__1__0.html">PPB_MessageLoop</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gae3eb3482b0fb57fb6a4eb05c07908788">PPB_MessageLoop</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___messaging__1__0.html">PPB_Messaging</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gac53fe3a3b5941f8b3608349f58ee24f0">PPB_Messaging</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___messaging__1__2.html">PPB_Messaging</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga7c131b984dbee94c139087fd526ab384">PPB_Messaging</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___mouse_cursor__1__0.html">PPB_MouseCursor</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gae583d9ea6381e1e4cb7b462c35c5d1de">PPB_MouseCursor</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___mouse_lock__1__0.html">PPB_MouseLock</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga9d5fa32b9c90b100400161025fda2617">PPB_MouseLock</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___net_address__1__0.html">PPB_NetAddress</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad6c325ff5a0a74f318a680971d0a7c52">PPB_NetAddress</a></td></tr> @@ -163,13 +181,15 @@ <a class="el" href="struct_p_p_b___var_array_buffer__1__0.html">PPB_VarArrayBuffer</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab26d5bb032f5438d02faf5bdf7b208cb">PPB_VarArrayBuffer</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> <a class="el" href="struct_p_p_b___var_dictionary__1__0.html">PPB_VarDictionary</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga69826004b5c32232c9639090f3e1db2e">PPB_VarDictionary</a></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga51985201c71f67da635ad7aa04d1aeff">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_frame__0__1.html">PPB_VideoFrame</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gaa76d004c840f6c4f64a0694e7c844ae9">PPB_VideoFrame</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___view__1__2.html">PPB_View</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga116e11e23c92c99094c9704d97636a67">PPB_View</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___web_socket__1__0.html">PPB_WebSocket</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gad0e152d14cefb0b480228f3fc7070faf">PPB_WebSocket</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_p___graphics3_d__1__0.html">PPP_Graphics3D</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gab9b763d2ae6ef08a8f18069728f418eb">PPP_Graphics3D</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_p___input_event__0__1.html">PPP_InputEvent</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga9c2577b1c089f77e1e467d74bd97a940">PPP_InputEvent</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_p___instance__1__1.html">PPP_Instance</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga3397638d116e4171368bf18fcb91ef11">PPP_Instance</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> +<a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gac581e9ff6162ebea9f26153854e7d6f2">PPP_MessageHandler</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_p___messaging__1__0.html">PPP_Messaging</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga1b4374f30360ab34679a159083db7e4d">PPP_Messaging</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_p___mouse_lock__1__0.html">PPP_MouseLock</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gae600e8f5b6005b02378e6eb9f51b11cb">PPP_MouseLock</a></td></tr> </table> @@ -414,12 +434,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="gac53fe3a3b5941f8b3608349f58ee24f0"></a><!-- doxytag: member="ppb_messaging.h::PPB_Messaging" ref="gac53fe3a3b5941f8b3608349f58ee24f0" args="" --> +<a class="anchor" id="ga7c131b984dbee94c139087fd526ab384"></a><!-- doxytag: member="ppb_messaging.h::PPB_Messaging" ref="ga7c131b984dbee94c139087fd526ab384" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___messaging__1__0.html">PPB_Messaging</a> <a class="el" href="group___interfaces.html#gac53fe3a3b5941f8b3608349f58ee24f0">PPB_Messaging</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___messaging__1__2.html">PPB_Messaging</a> <a class="el" href="group___interfaces.html#ga7c131b984dbee94c139087fd526ab384">PPB_Messaging</a></td> </tr> </table> </div> @@ -642,12 +662,12 @@ <div class="memdoc"> </div> </div> -<a class="anchor" id="ga51985201c71f67da635ad7aa04d1aeff"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="ga51985201c71f67da635ad7aa04d1aeff" args="" --> +<a class="anchor" id="ga2b4555d8bd239fa28b60c42df75f7ce5"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VideoDecoder" ref="ga2b4555d8bd239fa28b60c42df75f7ce5" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#ga51985201c71f67da635ad7aa04d1aeff">PPB_VideoDecoder</a></td> +<td class="memname">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> <a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td> </tr> </table> </div> @@ -738,6 +758,18 @@ <div class="memdoc"> </div> </div> +<a class="anchor" id="gac581e9ff6162ebea9f26153854e7d6f2"></a><!-- doxytag: member="ppp_message_handler.h::PPP_MessageHandler" ref="gac581e9ff6162ebea9f26153854e7d6f2" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef struct <a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a> <a class="el" href="group___interfaces.html#gac581e9ff6162ebea9f26153854e7d6f2">PPP_MessageHandler</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> <a class="anchor" id="ga1b4374f30360ab34679a159083db7e4d"></a><!-- doxytag: member="ppp_messaging.h::PPP_Messaging" ref="ga1b4374f30360ab34679a159083db7e4d" args="" --> <div class="memitem"> <div class="memproto">
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/group___structs.html b/native_client_sdk/doc_generated/pepper_stable/c/group___structs.html index 1a4f153..1bf6366 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/group___structs.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/group___structs.html
@@ -15,6 +15,8 @@ <tr><td class="mdescLeft"> </td><td class="mdescRight">A structure that defines a way for the browser to return arrays of data to the plugin. <a href="struct_p_p___array_output.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight"><code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> is a common mechanism for supporting potentially asynchronous calls in browser interfaces. <a href="struct_p_p___completion_callback.html#details">More...</a><br /></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___directory_entry.html">PP_DirectoryEntry</a></td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h.html b/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h.html index 88d9df4..c9cbed88 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h.html
@@ -21,6 +21,8 @@ <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html">PP_VideoPicture</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Struct describing a decoded video picture. <a href="struct_p_p___video_picture__0__1.html#details">More...</a><br /></td></tr> </table><h2> Enumerations</h2><table class="memberdecls"> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> { <br />
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h__incl.png b/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h__incl.png index fcefc9dd..e74f895 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_stable/c/pp__codecs_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h.html b/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h.html index 9b767c1..fed514a2 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__0.html">PPB_Messaging</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. <a href="struct_p_p_b___messaging__1__0.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__2.html">PPB_Messaging</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. <a href="struct_p_p_b___messaging__1__2.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__messaging_8h.html#afc64e56f770d45a4556b32cd6568cc77">PPB_MESSAGING_INTERFACE</a>   "PPB_Messaging;1.0"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__messaging_8h.html#a558ca32dad39a710cd217aaa09921d92">PPB_MESSAGING_INTERFACE</a>   <a class="el" href="ppb__messaging_8h.html#afc64e56f770d45a4556b32cd6568cc77">PPB_MESSAGING_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__messaging_8h.html#a233f5c34216429569a62f30b7210e816">PPB_MESSAGING_INTERFACE</a>   "PPB_Messaging;1.2"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__messaging_8h.html#a558ca32dad39a710cd217aaa09921d92">PPB_MESSAGING_INTERFACE</a>   <a class="el" href="ppb__messaging_8h.html#a233f5c34216429569a62f30b7210e816">PPB_MESSAGING_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___messaging__1__0.html">PPB_Messaging</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gac53fe3a3b5941f8b3608349f58ee24f0">PPB_Messaging</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___messaging__1__2.html">PPB_Messaging</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga7c131b984dbee94c139087fd526ab384">PPB_Messaging</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>This file defines the <code>PPB_Messaging</code> interface implemented by the browser for sending messages to DOM elements associated with a specific module instance. </p> @@ -37,19 +37,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__messaging_8h.html#a558ca32dad39a710cd217aaa09921d92">PPB_MESSAGING_INTERFACE</a>   <a class="el" href="ppb__messaging_8h.html#afc64e56f770d45a4556b32cd6568cc77">PPB_MESSAGING_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__messaging_8h.html#a558ca32dad39a710cd217aaa09921d92">PPB_MESSAGING_INTERFACE</a>   <a class="el" href="ppb__messaging_8h.html#a233f5c34216429569a62f30b7210e816">PPB_MESSAGING_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="afc64e56f770d45a4556b32cd6568cc77"></a><!-- doxytag: member="ppb_messaging.h::PPB_MESSAGING_INTERFACE" ref="afc64e56f770d45a4556b32cd6568cc77" args="" --> +<a class="anchor" id="a233f5c34216429569a62f30b7210e816"></a><!-- doxytag: member="ppb_messaging.h::PPB_MESSAGING_INTERFACE" ref="a233f5c34216429569a62f30b7210e816" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__messaging_8h.html#afc64e56f770d45a4556b32cd6568cc77">PPB_MESSAGING_INTERFACE</a>   "PPB_Messaging;1.0"</td> +<td class="memname">#define <a class="el" href="ppb__messaging_8h.html#a233f5c34216429569a62f30b7210e816">PPB_MESSAGING_INTERFACE</a>   "PPB_Messaging;1.2"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h__incl.png b/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h__incl.png index 565a4e8..0158103a 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__messaging_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h.html b/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h.html new file mode 100644 index 0000000..6c1524f --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h.html
@@ -0,0 +1,478 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>ppb_opengles2.h File Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<div class="textblock"><div class="dynheader"> +Include dependency graph for ppb_opengles2.h:</div> +<div class="dyncontent"> +<div class="center"><img src="ppb__opengles2_8h__incl.png" border="0" usemap="#ppb__opengles2_8h" alt="" /></div> +<map name="ppb__opengles2_8h" id="ppb__opengles2_8h"> +</map> +</div> +</div><h2> +Data Structures</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html">PPB_OpenGLES2</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html">PPB_OpenGLES2</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html">PPB_OpenGLES2InstancedArrays</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html">PPB_OpenGLES2InstancedArrays</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html">PPB_OpenGLES2FramebufferBlit</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html">PPB_OpenGLES2FramebufferBlit</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html">PPB_OpenGLES2FramebufferMultisample</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html">PPB_OpenGLES2FramebufferMultisample</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html">PPB_OpenGLES2ChromiumEnableFeature</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html">PPB_OpenGLES2ChromiumEnableFeature</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html">PPB_OpenGLES2ChromiumMapSub</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html">PPB_OpenGLES2ChromiumMapSub</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html">PPB_OpenGLES2Query</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html">PPB_OpenGLES2Query</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html">PPB_OpenGLES2VertexArrayObject</a></td></tr> +</table><h2> +Defines</h2><table class="memberdecls"> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ad557f98c8d78c0704377488bb9878b6a">PPB_OPENGLES2_INTERFACE</a>   "PPB_OpenGLES2;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ab9f1a398bb5caf6e6ac2044c181e4cb4">PPB_OPENGLES2_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad557f98c8d78c0704377488bb9878b6a">PPB_OPENGLES2_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a63baff589b60f79fac2b62ffe476fe52">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a>   "PPB_OpenGLES2InstancedArrays;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ade96920455b0451b4a84dedde8706f0c">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a63baff589b60f79fac2b62ffe476fe52">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ad035ea2ecebeb7dcdb46e69404149b0a">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a>   "PPB_OpenGLES2FramebufferBlit;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a2f416acbeae9d68c9c2207683b556da1">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad035ea2ecebeb7dcdb46e69404149b0a">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a7eaf092d0b7bf7f3da2b3b5bbb44175c">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a>   "PPB_OpenGLES2FramebufferMultisample;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a8842ed3cc24ad8e5c3e1c63a30479e81">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a7eaf092d0b7bf7f3da2b3b5bbb44175c">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ad776fe5d283c4097adc3054cf950f294">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a>   "PPB_OpenGLES2ChromiumEnableFeature;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#af73caac234005d5680c4212ee0414acf">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad776fe5d283c4097adc3054cf950f294">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a76831e822b9bd007659a516630b1b81b">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a>   "PPB_OpenGLES2ChromiumMapSub;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a0d5f52bc61032e26152508badb6293c6">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a76831e822b9bd007659a516630b1b81b">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#af9179ad2e31022ca51f19b7f3fd17f39">PPB_OPENGLES2_QUERY_INTERFACE</a>   "PPB_OpenGLES2Query;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a5966bff19c1b85d79bfaa773ff919798">PPB_OPENGLES2_QUERY_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#af9179ad2e31022ca51f19b7f3fd17f39">PPB_OPENGLES2_QUERY_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#abbc21d78bab2083560b49175e50394de">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a>   "PPB_OpenGLES2VertexArrayObject;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a2df0836cfb081e5cca1b639f7983b9a6">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#abbc21d78bab2083560b49175e50394de">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a></td></tr> +</table><h2> +Typedefs</h2><table class="memberdecls"> +<tr><td class="memItemLeft" align="right" valign="top">typedef void </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a1e5eb1ac5e47603cc80ab58338b92393">GLvoid</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned short </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ac995a558f6571eb5f98b7a6d2b2a4468">GLushort</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef short </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a2dfad4d45d694268922f502efa9c1cc0">GLshort</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned char </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned char </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef float </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef float </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef signed char </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#a0a9e8b1f1d9c4bcf1c0bc5d5d4e3608a">GLbyte</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#ad6d3fa892df40dedf48ee6d84529ae5e">GLfixed</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#aac646db97e8fa0aa9c61138e828743a0">GLclampx</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef long int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef long int </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a></td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>This file is auto-generated from gpu/command_buffer/build_gles2_cmd_buffer.py It's formatted by clang-format using chromium coding style: clang-format -i -style=chromium filename DO NOT EDIT! </p> +</div><hr /><h2>Define Documentation</h2> +<a class="anchor" id="af73caac234005d5680c4212ee0414acf"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE" ref="af73caac234005d5680c4212ee0414acf" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#af73caac234005d5680c4212ee0414acf">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad776fe5d283c4097adc3054cf950f294">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad776fe5d283c4097adc3054cf950f294"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE" ref="ad776fe5d283c4097adc3054cf950f294" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#ad776fe5d283c4097adc3054cf950f294">PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE</a>   "PPB_OpenGLES2ChromiumEnableFeature;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0d5f52bc61032e26152508badb6293c6"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE" ref="a0d5f52bc61032e26152508badb6293c6" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a0d5f52bc61032e26152508badb6293c6">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a76831e822b9bd007659a516630b1b81b">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a76831e822b9bd007659a516630b1b81b"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE" ref="a76831e822b9bd007659a516630b1b81b" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a76831e822b9bd007659a516630b1b81b">PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE</a>   "PPB_OpenGLES2ChromiumMapSub;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2f416acbeae9d68c9c2207683b556da1"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE" ref="a2f416acbeae9d68c9c2207683b556da1" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a2f416acbeae9d68c9c2207683b556da1">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad035ea2ecebeb7dcdb46e69404149b0a">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad035ea2ecebeb7dcdb46e69404149b0a"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE" ref="ad035ea2ecebeb7dcdb46e69404149b0a" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#ad035ea2ecebeb7dcdb46e69404149b0a">PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE</a>   "PPB_OpenGLES2FramebufferBlit;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8842ed3cc24ad8e5c3e1c63a30479e81"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE" ref="a8842ed3cc24ad8e5c3e1c63a30479e81" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a8842ed3cc24ad8e5c3e1c63a30479e81">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a7eaf092d0b7bf7f3da2b3b5bbb44175c">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7eaf092d0b7bf7f3da2b3b5bbb44175c"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE" ref="a7eaf092d0b7bf7f3da2b3b5bbb44175c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a7eaf092d0b7bf7f3da2b3b5bbb44175c">PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE</a>   "PPB_OpenGLES2FramebufferMultisample;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ade96920455b0451b4a84dedde8706f0c"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE" ref="ade96920455b0451b4a84dedde8706f0c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#ade96920455b0451b4a84dedde8706f0c">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#a63baff589b60f79fac2b62ffe476fe52">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a63baff589b60f79fac2b62ffe476fe52"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE" ref="a63baff589b60f79fac2b62ffe476fe52" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a63baff589b60f79fac2b62ffe476fe52">PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE</a>   "PPB_OpenGLES2InstancedArrays;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab9f1a398bb5caf6e6ac2044c181e4cb4"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_INTERFACE" ref="ab9f1a398bb5caf6e6ac2044c181e4cb4" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#ab9f1a398bb5caf6e6ac2044c181e4cb4">PPB_OPENGLES2_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#ad557f98c8d78c0704377488bb9878b6a">PPB_OPENGLES2_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad557f98c8d78c0704377488bb9878b6a"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_INTERFACE" ref="ad557f98c8d78c0704377488bb9878b6a" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#ad557f98c8d78c0704377488bb9878b6a">PPB_OPENGLES2_INTERFACE</a>   "PPB_OpenGLES2;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5966bff19c1b85d79bfaa773ff919798"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_QUERY_INTERFACE" ref="a5966bff19c1b85d79bfaa773ff919798" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a5966bff19c1b85d79bfaa773ff919798">PPB_OPENGLES2_QUERY_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#af9179ad2e31022ca51f19b7f3fd17f39">PPB_OPENGLES2_QUERY_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af9179ad2e31022ca51f19b7f3fd17f39"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_QUERY_INTERFACE" ref="af9179ad2e31022ca51f19b7f3fd17f39" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#af9179ad2e31022ca51f19b7f3fd17f39">PPB_OPENGLES2_QUERY_INTERFACE</a>   "PPB_OpenGLES2Query;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2df0836cfb081e5cca1b639f7983b9a6"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE" ref="a2df0836cfb081e5cca1b639f7983b9a6" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#a2df0836cfb081e5cca1b639f7983b9a6">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a>   <a class="el" href="ppb__opengles2_8h.html#abbc21d78bab2083560b49175e50394de">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abbc21d78bab2083560b49175e50394de"></a><!-- doxytag: member="ppb_opengles2.h::PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE" ref="abbc21d78bab2083560b49175e50394de" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">#define <a class="el" href="ppb__opengles2_8h.html#abbc21d78bab2083560b49175e50394de">PPB_OPENGLES2_VERTEXARRAYOBJECT_INTERFACE</a>   "PPB_OpenGLES2VertexArrayObject;1.0"</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr /><h2>Typedef Documentation</h2> +<a class="anchor" id="a0fb936f29008789fb46b434319f68cc9"></a><!-- doxytag: member="ppb_opengles2.h::GLbitfield" ref="a0fb936f29008789fb46b434319f68cc9" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned int <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa010a67382116caf29c29318251ccb6c"></a><!-- doxytag: member="ppb_opengles2.h::GLboolean" ref="aa010a67382116caf29c29318251ccb6c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned char <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0a9e8b1f1d9c4bcf1c0bc5d5d4e3608a"></a><!-- doxytag: member="ppb_opengles2.h::GLbyte" ref="a0a9e8b1f1d9c4bcf1c0bc5d5d4e3608a" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef signed char <a class="el" href="ppb__opengles2_8h.html#a0a9e8b1f1d9c4bcf1c0bc5d5d4e3608a">GLbyte</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aded4e0631b68d219180490a73d8424c0"></a><!-- doxytag: member="ppb_opengles2.h::GLclampf" ref="aded4e0631b68d219180490a73d8424c0" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef float <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aac646db97e8fa0aa9c61138e828743a0"></a><!-- doxytag: member="ppb_opengles2.h::GLclampx" ref="aac646db97e8fa0aa9c61138e828743a0" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef int <a class="el" href="ppb__opengles2_8h.html#aac646db97e8fa0aa9c61138e828743a0">GLclampx</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7efd7809e1632cdae75603fd1fee61c0"></a><!-- doxytag: member="ppb_opengles2.h::GLenum" ref="a7efd7809e1632cdae75603fd1fee61c0" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned int <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad6d3fa892df40dedf48ee6d84529ae5e"></a><!-- doxytag: member="ppb_opengles2.h::GLfixed" ref="ad6d3fa892df40dedf48ee6d84529ae5e" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef int <a class="el" href="ppb__opengles2_8h.html#ad6d3fa892df40dedf48ee6d84529ae5e">GLfixed</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a31aeedaeef29442c9c015ab355c8f5ab"></a><!-- doxytag: member="ppb_opengles2.h::GLfloat" ref="a31aeedaeef29442c9c015ab355c8f5ab" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef float <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5ac0f3c4d7fafd42b284b5487a791017"></a><!-- doxytag: member="ppb_opengles2.h::GLint" ref="a5ac0f3c4d7fafd42b284b5487a791017" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef int <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af7b978d38577bc5026a5f5fea9dddd1b"></a><!-- doxytag: member="ppb_opengles2.h::GLintptr" ref="af7b978d38577bc5026a5f5fea9dddd1b" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef long int <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2dfad4d45d694268922f502efa9c1cc0"></a><!-- doxytag: member="ppb_opengles2.h::GLshort" ref="a2dfad4d45d694268922f502efa9c1cc0" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef short <a class="el" href="ppb__opengles2_8h.html#a2dfad4d45d694268922f502efa9c1cc0">GLshort</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9289d5b99dc1f27f01480360f2e18ae0"></a><!-- doxytag: member="ppb_opengles2.h::GLsizei" ref="a9289d5b99dc1f27f01480360f2e18ae0" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef int <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aaccb4d7c4f31e730b377b4c44d68bc31"></a><!-- doxytag: member="ppb_opengles2.h::GLsizeiptr" ref="aaccb4d7c4f31e730b377b4c44d68bc31" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef long int <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0595908be03a8cff881a23cdc9170e7c"></a><!-- doxytag: member="ppb_opengles2.h::GLubyte" ref="a0595908be03a8cff881a23cdc9170e7c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned char <a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa311c7f0d6ec4f1a33f9235c3651b86b"></a><!-- doxytag: member="ppb_opengles2.h::GLuint" ref="aa311c7f0d6ec4f1a33f9235c3651b86b" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned int <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac995a558f6571eb5f98b7a6d2b2a4468"></a><!-- doxytag: member="ppb_opengles2.h::GLushort" ref="ac995a558f6571eb5f98b7a6d2b2a4468" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef unsigned short <a class="el" href="ppb__opengles2_8h.html#ac995a558f6571eb5f98b7a6d2b2a4468">GLushort</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1e5eb1ac5e47603cc80ab58338b92393"></a><!-- doxytag: member="ppb_opengles2.h::GLvoid" ref="a1e5eb1ac5e47603cc80ab58338b92393" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">typedef void <a class="el" href="ppb__opengles2_8h.html#a1e5eb1ac5e47603cc80ab58338b92393">GLvoid</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h__incl.png b/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h__incl.png new file mode 100644 index 0000000..511eff20 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__opengles2_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h.html b/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h.html index f888e87..212d41ab 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h.html
@@ -19,15 +19,15 @@ </div><h2> Data Structures</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a></td></tr> -<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__0__1.html#details">More...</a><br /></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">Video decoder interface. <a href="struct_p_p_b___video_decoder__1__0.html#details">More...</a><br /></td></tr> </table><h2> Defines</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#aa2111c736f441e1443e035d97fec6e60">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.1"</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#aa2111c736f441e1443e035d97fec6e60">PPB_VIDEODECODER_INTERFACE</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td></tr> </table><h2> Typedefs</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__0__1.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga51985201c71f67da635ad7aa04d1aeff">PPB_VideoDecoder</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_p_p_b___video_decoder__1__0.html">PPB_VideoDecoder</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#ga2b4555d8bd239fa28b60c42df75f7ce5">PPB_VideoDecoder</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>This file defines the <code>PPB_VideoDecoder</code> interface. </p> @@ -37,19 +37,19 @@ <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#aa2111c736f441e1443e035d97fec6e60">PPB_VIDEODECODER_INTERFACE</a></td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#ae369609aebfa745c1836ef92e9b76aa2">PPB_VIDEODECODER_INTERFACE</a>   <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a></td> </tr> </table> </div> <div class="memdoc"> </div> </div> -<a class="anchor" id="aa2111c736f441e1443e035d97fec6e60"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="aa2111c736f441e1443e035d97fec6e60" args="" --> +<a class="anchor" id="af814c8f0028bce254da6fb5c3e61a4d8"></a><!-- doxytag: member="ppb_video_decoder.h::PPB_VIDEODECODER_INTERFACE" ref="af814c8f0028bce254da6fb5c3e61a4d8" args="" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#aa2111c736f441e1443e035d97fec6e60">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;0.1"</td> +<td class="memname">#define <a class="el" href="ppb__video__decoder_8h.html#af814c8f0028bce254da6fb5c3e61a4d8">PPB_VIDEODECODER_INTERFACE</a>   "PPB_VideoDecoder;1.0"</td> </tr> </table> </div>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h__incl.png b/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h__incl.png index 0d6c946..6456426 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h__incl.png +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppb__video__decoder_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h.html b/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h.html new file mode 100644 index 0000000..d198e65 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h.html
@@ -0,0 +1,33 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>ppp_message_handler.h File Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<div class="textblock"><div class="dynheader"> +Include dependency graph for ppp_message_handler.h:</div> +<div class="dyncontent"> +<div class="center"><img src="ppp__message__handler_8h__incl.png" border="0" usemap="#ppp__message__handler_8h" alt="" /></div> +<map name="ppp__message__handler_8h" id="ppp__message__handler_8h"> +</map> +</div> +</div><h2> +Data Structures</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a></td></tr> +<tr><td class="mdescLeft"> </td><td class="mdescRight">The <code>PPP_MessageHandler</code> interface is implemented by the plugin if the plugin wants to receive messages from a thread other than the main Pepper thread, or if the plugin wants to handle blocking messages which JavaScript may send via postMessageAndAwaitResponse(). <a href="struct_p_p_p___message_handler__0__2.html#details">More...</a><br /></td></tr> +</table><h2> +Typedefs</h2><table class="memberdecls"> +<tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak" /> +<a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group___interfaces.html#gac581e9ff6162ebea9f26153854e7d6f2">PPP_MessageHandler</a></td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>This file defines the <code>PPP_MessageHandler</code> interface that plugins can implement and register using <a class="el" href="struct_p_p_b___messaging__1__2.html#ae5abee73dc21a290514f7f3554a7e895" title="Registers a handler for receiving messages from JavaScript.">PPB_Messaging::RegisterMessageHandler</a> in order to handle messages sent from JavaScript via postMessage() or postMessageAndAwaitResponse(). </p> +</div></div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h__incl.png b/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h__incl.png new file mode 100644 index 0000000..04512975 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/ppp__message__handler_8h__incl.png Binary files differ
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture.html index 2bf52aca..8e19d4e3 100644 --- a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture.html
@@ -16,6 +16,7 @@ <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#ae1a9b538db9e422e9f4c9126e941ea25">texture_id</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a5e2d5f24f86223ad71f2efb83116f118">texture_target</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a0f3c7022b44215e06f98f771f75641cc">texture_size</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">visible_rect</a></td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Struct describing a decoded video picture. </p> @@ -77,6 +78,20 @@ <p>The pixel format of the texture is GL_RGBA. </p> </div> </div> +<a class="anchor" id="a1068a6b0ec8376cadcc7b08e607085f2"></a><!-- doxytag: member="PP_VideoPicture::visible_rect" ref="a1068a6b0ec8376cadcc7b08e607085f2" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___rect.html">PP_Rect</a> <a class="el" href="struct_p_p___video_picture.html#a1068a6b0ec8376cadcc7b08e607085f2">PP_VideoPicture::visible_rect</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The visible subrectangle of the picture. </p> +<p>The plugin should display only this part of the picture. </p> +</div> +</div> <hr />The documentation for this struct was generated from the following file:<ul> <li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> </ul>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture__0__1.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture__0__1.html new file mode 100644 index 0000000..1710cdf --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p___video_picture__0__1.html
@@ -0,0 +1,85 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PP_VideoPicture Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PP_VideoPicture" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">decode_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">texture_id</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">texture_target</a></td></tr> +<tr><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">texture_size</a></td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>Struct describing a decoded video picture. </p> +<p>The decoded picture data is stored in the GL texture corresponding to |texture_id|. The plugin can determine which Decode call generated the picture using |decode_id|. </p> +</div><hr /><h2>Field Documentation</h2> +<a class="anchor" id="a5745b95f0df115201c6ac1eab564cf2e"></a><!-- doxytag: member="PP_VideoPicture::decode_id" ref="a5745b95f0df115201c6ac1eab564cf2e" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a5745b95f0df115201c6ac1eab564cf2e">PP_VideoPicture::decode_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>|decode_id| parameter of the Decode call which generated this picture. </p> +<p>See the PPB_VideoDecoder function Decode() for more details. </p> +</div> +</div> +<a class="anchor" id="a8ee7a6fdddbf71d429a16f7779af6f0f"></a><!-- doxytag: member="PP_VideoPicture::texture_id" ref="a8ee7a6fdddbf71d429a16f7779af6f0f" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#a8ee7a6fdddbf71d429a16f7779af6f0f">PP_VideoPicture::texture_id</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Texture ID in the plugin's GL context. </p> +<p>The plugin can use this to render the decoded picture. </p> +</div> +</div> +<a class="anchor" id="aeed32ff6cc3c52d51b0a5179904e5676"></a><!-- doxytag: member="PP_VideoPicture::texture_size" ref="aeed32ff6cc3c52d51b0a5179904e5676" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">struct <a class="el" href="struct_p_p___size.html">PP_Size</a> <a class="el" href="struct_p_p___video_picture__0__1.html#aeed32ff6cc3c52d51b0a5179904e5676">PP_VideoPicture::texture_size</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Dimensions of the texture holding the decoded picture. </p> +</div> +</div> +<a class="anchor" id="af73723a3d48c5b8ae027826dccfdc88c"></a><!-- doxytag: member="PP_VideoPicture::texture_target" ref="af73723a3d48c5b8ae027826dccfdc88c" args="" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">uint32_t <a class="el" href="struct_p_p___video_picture__0__1.html#af73723a3d48c5b8ae027826dccfdc88c">PP_VideoPicture::texture_target</a></td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>The GL texture target for the decoded picture. </p> +<p>Possible values are: GL_TEXTURE_2D GL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_EXTERNAL_OES</p> +<p>The pixel format of the texture is GL_RGBA. </p> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="pp__codecs_8h.html">pp_codecs.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__0.html deleted file mode 100644 index a13d4fa..0000000 --- a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__0.html +++ /dev/null
@@ -1,68 +0,0 @@ -{{+bindTo:partials.standard_nacl_api}} -<h1>PPB_Messaging Struct Reference</h1> -<div id="doxygen-ref"> -{{- dummy div to appease doxygen -}} - <div> -<!-- Generated by Doxygen 1.7.6.1 --> - - -</div> -<!--header--> -<div class="contents"> -<!-- doxytag: class="PPB_Messaging" --><h2> -Data Fields</h2><table class="memberdecls"> - -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__0.html#a7f0412c47b340d21c9c98be2e83dcc53">PostMessage</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> message)</td></tr> -</table> -<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. </p> -</div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="a7f0412c47b340d21c9c98be2e83dcc53"></a><!-- doxytag: member="PPB_Messaging::PostMessage" ref="a7f0412c47b340d21c9c98be2e83dcc53" args=")(PP_Instance instance, struct PP_Var message)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___messaging__1__0.html#a7f0412c47b340d21c9c98be2e83dcc53">PPB_Messaging::PostMessage</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> message)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p><a class="el" href="struct_p_p_b___messaging__1__0.html#a7f0412c47b340d21c9c98be2e83dcc53" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> asynchronously invokes any listeners for message events on the DOM element for the given module instance. </p> -<p>A call to <a class="el" href="struct_p_p_b___messaging__1__0.html#a7f0412c47b340d21c9c98be2e83dcc53" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> will not block while the message is processed.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">message</td><td>A <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code> containing the data to be sent to JavaScript. <code>message</code> can be any <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code> type except <code>PP_VARTYPE_OBJECT</code>. Array/Dictionary types are supported from Chrome M29 onward. All var types are copied when passing them to JavaScript.</td></tr> -</table> -</dd> -</dl> -<p>When passing array or dictionary <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code>s, the entire reference graph will be converted and transferred. If the reference graph has cycles, the message will not be sent and an error will be logged to the console.</p> -<p>Listeners for message events in JavaScript code will receive an object conforming to the HTML 5 <code>MessageEvent</code> interface. Specifically, the value of message will be contained as a property called data in the received <code>MessageEvent</code>.</p> -<p>This messaging system is similar to the system used for listening for messages from Web Workers. Refer to <code><a href="http://www.whatwg.org/specs/web-workers/current-work/">http://www.whatwg.org/specs/web-workers/current-work/</a></code> for further information.</p> -<p><b>Example:</b></p> -<div class="fragment"><pre class="fragment"> <body> - <<span class="keywordtype">object</span> <span class="keywordtype">id</span>=<span class="stringliteral">"plugin"</span> - type=<span class="stringliteral">"application/x-ppapi-postMessage-example"</span>/> - <script type=<span class="stringliteral">"text/javascript"</span>> - var plugin = document.getElementById(<span class="stringliteral">'plugin'</span>); - plugin.addEventListener(<span class="stringliteral">"message"</span>, - <span class="keyword">function</span>(message) { alert(message.data); }, - <span class="keyword">false</span>); - </script> - </body> -</pre></div><p>The module instance then invokes <a class="el" href="struct_p_p_b___messaging__1__0.html#a7f0412c47b340d21c9c98be2e83dcc53" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> as follows:</p> -<div class="fragment"><pre class="fragment"> <span class="keywordtype">char</span> hello_world[] = <span class="stringliteral">"Hello world!"</span>; - <a class="code" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a> hello_var = ppb_var_interface->VarFromUtf8(instance, - hello_world, - <span class="keyword">sizeof</span>(hello_world)); - ppb_messaging_interface->PostMessage(instance, hello_var); <span class="comment">// Copies var.</span> - ppb_var_interface->Release(hello_var); -</pre></div><p>The browser will pop-up an alert saying "Hello world!" </p> -</div> -</div> -<hr />The documentation for this struct was generated from the following file:<ul> -<li><a class="el" href="ppb__messaging_8h.html">ppb_messaging.h</a></li> -</ul> -</div><!-- contents --> -</div> -{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__2.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__2.html new file mode 100644 index 0000000..c711c156 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___messaging__1__2.html
@@ -0,0 +1,117 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_Messaging Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_Messaging" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__2.html#a3ad76397ae4e47e768a6b12d8dc0ea11">PostMessage</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> message)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__2.html#ae5abee73dc21a290514f7f3554a7e895">RegisterMessageHandler</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a> *handler, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___messaging__1__2.html#a898754602cac55875f298938e18bf017">UnregisterMessageHandler</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>The <code>PPB_Messaging</code> interface is implemented by the browser and is related to sending messages to JavaScript message event listeners on the DOM element associated with specific module instance. </p> +</div><hr /><h2>Field Documentation</h2> +<a class="anchor" id="a3ad76397ae4e47e768a6b12d8dc0ea11"></a><!-- doxytag: member="PPB_Messaging::PostMessage" ref="a3ad76397ae4e47e768a6b12d8dc0ea11" args=")(PP_Instance instance, struct PP_Var message)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___messaging__1__2.html#a3ad76397ae4e47e768a6b12d8dc0ea11">PPB_Messaging::PostMessage</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> message)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p><a class="el" href="struct_p_p_b___messaging__1__2.html#a3ad76397ae4e47e768a6b12d8dc0ea11" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> asynchronously invokes any listeners for message events on the DOM element for the given module instance. </p> +<p>A call to <a class="el" href="struct_p_p_b___messaging__1__2.html#a3ad76397ae4e47e768a6b12d8dc0ea11" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> will not block while the message is processed.</p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">message</td><td>A <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code> containing the data to be sent to JavaScript. <code>message</code> can be any <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code> type except <code>PP_VARTYPE_OBJECT</code>. Array/Dictionary types are supported from Chrome M29 onward. All var types are copied when passing them to JavaScript.</td></tr> +</table> +</dd> +</dl> +<p>When passing array or dictionary <code><a class="el" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a></code>s, the entire reference graph will be converted and transferred. If the reference graph has cycles, the message will not be sent and an error will be logged to the console.</p> +<p>Listeners for message events in JavaScript code will receive an object conforming to the HTML 5 <code>MessageEvent</code> interface. Specifically, the value of message will be contained as a property called data in the received <code>MessageEvent</code>.</p> +<p>This messaging system is similar to the system used for listening for messages from Web Workers. Refer to <code><a href="http://www.whatwg.org/specs/web-workers/current-work/">http://www.whatwg.org/specs/web-workers/current-work/</a></code> for further information.</p> +<p><b>Example:</b></p> +<div class="fragment"><pre class="fragment"> <body> + <<span class="keywordtype">object</span> <span class="keywordtype">id</span>=<span class="stringliteral">"plugin"</span> + type=<span class="stringliteral">"application/x-ppapi-postMessage-example"</span>/> + <script type=<span class="stringliteral">"text/javascript"</span>> + var plugin = document.getElementById(<span class="stringliteral">'plugin'</span>); + plugin.addEventListener(<span class="stringliteral">"message"</span>, + <span class="keyword">function</span>(message) { alert(message.data); }, + <span class="keyword">false</span>); + </script> + </body> +</pre></div><p>The module instance then invokes <a class="el" href="struct_p_p_b___messaging__1__2.html#a3ad76397ae4e47e768a6b12d8dc0ea11" title="PostMessage() asynchronously invokes any listeners for message events on the DOM element for the give...">PostMessage()</a> as follows:</p> +<div class="fragment"><pre class="fragment"> <span class="keywordtype">char</span> hello_world[] = <span class="stringliteral">"Hello world!"</span>; + <a class="code" href="struct_p_p___var.html" title="The PP_VAR struct is a variant data type and can contain any value of one of the types named in the P...">PP_Var</a> hello_var = ppb_var_interface->VarFromUtf8(instance, + hello_world, + <span class="keyword">sizeof</span>(hello_world)); + ppb_messaging_interface->PostMessage(instance, hello_var); <span class="comment">// Copies var.</span> + ppb_var_interface->Release(hello_var); +</pre></div><p>The browser will pop-up an alert saying "Hello world!" </p> +</div> +</div> +<a class="anchor" id="ae5abee73dc21a290514f7f3554a7e895"></a><!-- doxytag: member="PPB_Messaging::RegisterMessageHandler" ref="ae5abee73dc21a290514f7f3554a7e895" args=")(PP_Instance instance, void *user_data, const struct PPP_MessageHandler *handler, PP_Resource message_loop)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___messaging__1__2.html#ae5abee73dc21a290514f7f3554a7e895">PPB_Messaging::RegisterMessageHandler</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p_p___message_handler__0__2.html">PPP_MessageHandler</a> *handler, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Registers a handler for receiving messages from JavaScript. </p> +<p>If a handler is registered this way, it will replace PPP_Messaging, and all messages sent from JavaScript via postMessage and postMessageAndAwaitResponse will be dispatched to <code>handler</code>.</p> +<p>The function calls will be dispatched via <code>message_loop</code>. This means that the functions will be invoked on the thread to which <code>message_loop</code> is attached, when <code>message_loop</code> is run. It is illegal to pass the main thread message loop; RegisterMessageHandler will return PP_ERROR_WRONG_THREAD in that case. If you quit <code>message_loop</code> before calling Unregister(), the browser will not be able to call functions in the plugin's message handler any more. That could mean missing some messages or could cause a leak if you depend on Destroy() to free hander data. So you should, whenever possible, Unregister() the handler prior to quitting its event loop.</p> +<p>Attempting to register a message handler when one is already registered will cause the current MessageHandler to be unregistered and replaced. In that case, no messages will be sent to the "default" message handler (PPP_Messaging). Messages will stop arriving at the prior message handler and will begin to be dispatched at the new message handler.</p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">user_data</td><td>A pointer the plugin may choose to use when handling calls to functions within PPP_MessageHandler. The browser will pass this same pointer when invoking functions within PPP_MessageHandler. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">handler</td><td>The plugin-provided set of functions for handling messages. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">message_loop</td><td>Represents the message loop on which PPP_MessageHandler functions should be invoked. </td></tr> +</table> +</dd> +</dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>PP_OK on success, or an error from <a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a>. </dd></dl> +</div> +</div> +<a class="anchor" id="a898754602cac55875f298938e18bf017"></a><!-- doxytag: member="PPB_Messaging::UnregisterMessageHandler" ref="a898754602cac55875f298938e18bf017" args=")(PP_Instance instance)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___messaging__1__2.html#a898754602cac55875f298938e18bf017">PPB_Messaging::UnregisterMessageHandler</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Unregisters the current message handler for <code>instance</code> if one is registered. </p> +<p>After this call, the message handler (if one was registered) will have "Destroy" called on it and will receive no further messages after that point. After that point, all messages sent from JavaScript using postMessage() will be dispatched to PPP_Messaging (if the plugin supports PPP_MESSAGING_INTERFACE). Attempts to call postMessageAndAwaitResponse() from JavaScript will fail.</p> +<p>Attempting to unregister a message handler when none is registered has no effect.</p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +</table> +</dd> +</dl> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__messaging_8h.html">ppb_messaging.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2.html new file mode 100644 index 0000000..67ba65a --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2.html
@@ -0,0 +1,1868 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2 Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae53e34af2c715db40bf6836f978ba001">ActiveTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3302eaf28a71864e0a52c1fd7a046acd">AttachShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac877609276d3ce3957b5aa5170972209">BindAttribLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a297a37236aee3add9175bc36adf44ff8">BindBuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0e198004440ea8ba7aa626d63bc9c8e1">BindFramebuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2423e8c80776a8f971e2a9d93dc84c69">BindRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8b269f95d72b4f29fed62de980ff5b80">BindTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8b22428f7a3104ba9f791eead54e34d">BlendColor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afe873782d586369d5aec83a83f26c6d4">BlendEquation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#abde0f31c5db8570f37e48a35774fb325">BlendEquationSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeAlpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a18ef5c59756ff3ab71e88e9bdb0d9bdd">BlendFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> sfactor, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dfactor)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0fbec684cfce45e7e485684786eb1b08">BlendFuncSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcAlpha, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstAlpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa824981bca0cf27ea7443042f7291fee">BufferData</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> usage)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab25fb15735015c10d4938db6ada4ec6c">BufferSubData</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adf5a6d990941c6cc6620af92a919bb99">CheckFramebufferStatus</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a23ca838cdb8d41a42b53dd2385a8c802">Clear</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae6fe1382f1b9ef68862526f454d5a3da">ClearColor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a085fddf29150fa575286a77631db5aa3">ClearDepthf</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> depth)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab41c6d646fe4a249c8e3c62ac48ae15f">ClearStencil</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> s)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ada6b9a86310964424975fe32a8e88dc1">ColorMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> red, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> green, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> blue, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa307895068405a8e6fd43647d10b2240">CompileShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a709df82e66e04d67bad003e1e0432b5a">CompressedTexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a85a4542cd8def2be666c209e9c29d658">CompressedTexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acf78e2322947ad0b62d263f13a03ee4d">CopyTexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad1ebbf7b46fdc610cf7399a1dbaa65ca">CopyTexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9aeaed06acf5ea610b6eca14cd86b065">CreateProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa21109df3da84b9daff8fd755b96e9cd">CreateShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab7a3b515cca3b090cf3e53bf503a715c">CullFace</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae918075c7de431c32aa97e26c9591a7f">DeleteBuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7f23a4d62b5b6db480fa0e3ba2d64a6c">DeleteFramebuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2d67942171a98c6151432996f44edbfe">DeleteProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af9210afd908695511757500a3c368fb6">DeleteRenderbuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae387aff5d9d0a755ee91f615419781e8">DeleteShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af417c42c55cccfbb53d66bb7ee3f7630">DeleteTextures</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a986605dda31b45565234d66a0a7b91fd">DepthFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acc373d6ee5e6c03b04adb0dd57f72e7e">DepthMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> flag)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a97a9c5c3d0cfba11b92e0be2544387b3">DepthRangef</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zNear, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zFar)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acdae43713f391b50f0d9dc3538872e98">DetachShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a761da4c86a553666677e91b0af52ef3f">Disable</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6db7cbbe276ec1b207bf07c004bc8cce">DisableVertexAttribArray</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adeaf1eb89288064288f1be4f97d1e8e8">DrawArrays</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aebe63866d604b1a7ad0f04b6c10c7404">DrawElements</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0c69b4f342992dc423de86baf57d1553">Enable</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa2c0b80eba15506af0f1ac28f778342a">EnableVertexAttribArray</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a81ec538158ea1d6a92fa3682e8baf9cb">Finish</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac511f0c2abf05cb898202a025e7a4c2f">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a92b35ec6669001aa38c53a75ca597166">FramebufferRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> renderbuffertarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae0871e157118a4f56b66482bede75af0">FramebufferTexture2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> textarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a35f542c3f15f0e028f01eacfd57cd290">FrontFace</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3021ad890d7faf61f1656caff69e2936">GenBuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa5219fe93e4fe1566f058730237511a3">GenerateMipmap</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac046a9b0e3bbe97336df2f1ed4f363aa">GenFramebuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a95064b43b8b85251f25d4a99a212ffa2">GenRenderbuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a88871423b8bd9fb8b5224679cae7319d">GenTextures</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a01c888fbe0b5e4b7253ada24c2822c1a">GetActiveAttrib</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adb76d45821a6a01bd2e9cf290ade6393">GetActiveUniform</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8bcc540aaa53ed190984ff476f022dbc">GetAttachedShaders</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> maxcount, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *count, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5e10f14b16bedf58f4a4d82faae92fce">GetAttribLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a469a602f25f7a960828a33c039221b05">GetBooleanv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a274a18138ca82e21087a3bc09e0c5d6e">GetBufferParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad7a51a4767acf70e3c691f5715da66b2">GetError</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2b162ab5408f1862ede23100c1a98ed4">GetFloatv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af044cc978a541ff66d6bfcb81d0c9797">GetFramebufferAttachmentParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6cbe6db1beec8544f5d766b347c1b774">GetIntegerv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afaddb913ffc38cc8075adf7b63c1cacb">GetProgramiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a899415b7473fc77870102dc1e0eedfa6">GetProgramInfoLog</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af16e81d3abb5c7b12b9ef94351a8582a">GetRenderbufferParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab497e96f8254d499e09f37f34c4fa20f">GetShaderiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0c7aeac48bb1b7cd9ecf8ebb6e160b21">GetShaderInfoLog</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a07b780398cd5f0cbe4b66d47f6bc7432">GetShaderPrecisionFormat</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> shadertype, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> precisiontype, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *range, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *precision)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a999a0c63cd2695c4f97d267412804470">GetShaderSource</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *source)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">const <a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a> *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a51fe0f4d9dc7efb5bb5185ea23ed7854">GetString</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8ed1ea3e802fd72c1abca830757c4760">GetTexParameterfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a394d2e8e9382cc526856e760c7a99ab4">GetTexParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a68d5adab1ca625fe4c08e11cf8ff5a76">GetUniformfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0ccf7b97de2a07a2885c9c1f01dbc423">GetUniformiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae2c5c0efd5ee3ea2106c20bdad49cd25">GetUniformLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aca40defa62c9536428a64d59ab07c83e">GetVertexAttribfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a632b9ffc9fbf4f3332bd39e3e67221a2">GetVertexAttribiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5a0bf76ee7e291db46a2358fbeaf6fa8">GetVertexAttribPointerv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, void **pointer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af443ce0d45468872824a3312eb538fd6">Hint</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a22a9ee9465ede518ff017177605569c8">IsBuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1b94166b764d69207e61055ae7cebe9c">IsEnabled</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a243afc655b0c8d331656957f4878bd38">IsFramebuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab15ed85d340670c3f629e33cdaf11ff4">IsProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#abfdc2a929818dce1c2bbcfb24cd00fd2">IsRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a51bb4c4cb9a4ad680a3b69e5d94284d9">IsShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8ff9c47061f6b1e604d5d6bd1a93e2d">IsTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a33169bd4752db53cf6e25ef78db83a6d">LineWidth</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> width)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8969408a22f4abe20575497e587fae6">LinkProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0690e80898a4ce4421512f5da9614cca">PixelStorei</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79d1b98f9b4586b4ed6b2a89f6de98be">PolygonOffset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> factor, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> units)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ca1f371a2933be66db0340a3361753c">ReadPixels</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3b70d85227ab102e942371c099d1af0d">ReleaseShaderCompiler</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ace64a122c95174d26f22cd2f8bb82cd0">RenderbufferStorage</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad80041090ea0856551a5aa7683f9a754">SampleCoverage</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> value, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> invert)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a76bd885cc06b8f993a9dd4b4beba8507">Scissor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#add8cdccd7afe3115c0db6488244710f1">ShaderBinary</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> binaryformat, const void *binary, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> length)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a54563f901d3d4b68059f72f689367d04">ShaderSource</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const char **str, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *length)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab09dfe9c3aa76b033a7a899ef83881ec">StencilFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a13947e07ef135ccfb3664d7481d88f52">StencilFuncSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a582bf1efee1ce4ed489d2a2bd051ba70">StencilMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ecc42baba61b5f0ffb2acc7a846add4">StencilMaskSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2ec4b7407b261ab83dac6617024968d1">StencilOp</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a832bb94b26d3f3ef9c25e260e51c682a">StencilOpSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af5e5e8ac2991acc411bc8e7349a4528c">TexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1e247c4eba9d9b83fc3faa95ad2695b3">TexParameterf</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1fbfa876dce5f8b4a54ae357e9f94f3d">TexParameterfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a4103d52b8c7d312f623e256be6bfdc34">TexParameteri</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a760b43042385f6ea828a540c477655be">TexParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac13af0c1267510083e8b2db368f3d5f9">TexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab619fb1afcdca0291f2002a49d70263d">Uniform1f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9a114745de0223354a3f8ac0692c3d86">Uniform1fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a334011bf29706a264623c099cf3e638e">Uniform1i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad3afadbd84c98b021f4352a0ed25258e">Uniform1iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5459521734fcc78b4d541f8a443c26e5">Uniform2f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab90ca755ee6ecbe8baa31b6e7e0d94ef">Uniform2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a787d002ec3d31e7b6872e71261dade2c">Uniform2i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7ef8e80ef0bbd1d944e9165ef341bc20">Uniform2iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6512a43696bded1489f3b2d47d666d6c">Uniform3f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a4562834999794d2dfed644527f28de05">Uniform3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79dbfecdc82f934e09bb244993429478">Uniform3i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7838d459375aede455d708c5593558d7">Uniform3iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acae286535d8c99ba10459b1509aa7f33">Uniform4f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afbd5c631094027ec297959995345ae45">Uniform4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ad04ea982dcf2bd1d8ce4e205dca158">Uniform4i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a85fa410e905c328f3d0e81ee1f8a6e3b">Uniform4iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af44e9dc9f83b3b681ce478fe4051415e">UniformMatrix2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0a136244b97c8dd351e24305767f2735">UniformMatrix3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ac470e9e4a9dedf0e359001a52c42cc">UniformMatrix4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a300168f1b2fcb58a5087654224c6ab47">UseProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8119f3f8b731cce9143da0cc0c4ddd9c">ValidateProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a46f108883a33981a78b6276c7a4e1305">VertexAttrib1f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5228b6fcf8d0a65fcc8a94eb08697987">VertexAttrib1fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a96c6934bbaac1aa1625771ee27e18f29">VertexAttrib2f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79ecc589e72b0467e3e4517b414cb27a">VertexAttrib2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aecaa4d98853876c3837a0be6a1b1c665">VertexAttrib3f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a19e465e1c372bf95275feea87046ecf8">VertexAttrib3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2c55091b7ec4e7ac1df480f7401921ac">VertexAttrib4f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7a857a7cb2e0e5b79b18e94b3910e9d4">VertexAttrib4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afd77adfbe7ea0b4d85863c6cfd4e2025">VertexAttribPointer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> normalized, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> stride, const void *ptr)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af8e6a3080571bee2377c0ce1d73a4ff8">Viewport</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="ae53e34af2c715db40bf6836f978ba001"></a><!-- doxytag: member="PPB_OpenGLES2::ActiveTexture" ref="ae53e34af2c715db40bf6836f978ba001" args=")(PP_Resource context, GLenum texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae53e34af2c715db40bf6836f978ba001">PPB_OpenGLES2::ActiveTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3302eaf28a71864e0a52c1fd7a046acd"></a><!-- doxytag: member="PPB_OpenGLES2::AttachShader" ref="a3302eaf28a71864e0a52c1fd7a046acd" args=")(PP_Resource context, GLuint program, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3302eaf28a71864e0a52c1fd7a046acd">PPB_OpenGLES2::AttachShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac877609276d3ce3957b5aa5170972209"></a><!-- doxytag: member="PPB_OpenGLES2::BindAttribLocation" ref="ac877609276d3ce3957b5aa5170972209" args=")(PP_Resource context, GLuint program, GLuint index, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac877609276d3ce3957b5aa5170972209">PPB_OpenGLES2::BindAttribLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a297a37236aee3add9175bc36adf44ff8"></a><!-- doxytag: member="PPB_OpenGLES2::BindBuffer" ref="a297a37236aee3add9175bc36adf44ff8" args=")(PP_Resource context, GLenum target, GLuint buffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a297a37236aee3add9175bc36adf44ff8">PPB_OpenGLES2::BindBuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0e198004440ea8ba7aa626d63bc9c8e1"></a><!-- doxytag: member="PPB_OpenGLES2::BindFramebuffer" ref="a0e198004440ea8ba7aa626d63bc9c8e1" args=")(PP_Resource context, GLenum target, GLuint framebuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0e198004440ea8ba7aa626d63bc9c8e1">PPB_OpenGLES2::BindFramebuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2423e8c80776a8f971e2a9d93dc84c69"></a><!-- doxytag: member="PPB_OpenGLES2::BindRenderbuffer" ref="a2423e8c80776a8f971e2a9d93dc84c69" args=")(PP_Resource context, GLenum target, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2423e8c80776a8f971e2a9d93dc84c69">PPB_OpenGLES2::BindRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8b269f95d72b4f29fed62de980ff5b80"></a><!-- doxytag: member="PPB_OpenGLES2::BindTexture" ref="a8b269f95d72b4f29fed62de980ff5b80" args=")(PP_Resource context, GLenum target, GLuint texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8b269f95d72b4f29fed62de980ff5b80">PPB_OpenGLES2::BindTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae8b22428f7a3104ba9f791eead54e34d"></a><!-- doxytag: member="PPB_OpenGLES2::BlendColor" ref="ae8b22428f7a3104ba9f791eead54e34d" args=")(PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8b22428f7a3104ba9f791eead54e34d">PPB_OpenGLES2::BlendColor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="afe873782d586369d5aec83a83f26c6d4"></a><!-- doxytag: member="PPB_OpenGLES2::BlendEquation" ref="afe873782d586369d5aec83a83f26c6d4" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afe873782d586369d5aec83a83f26c6d4">PPB_OpenGLES2::BlendEquation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abde0f31c5db8570f37e48a35774fb325"></a><!-- doxytag: member="PPB_OpenGLES2::BlendEquationSeparate" ref="abde0f31c5db8570f37e48a35774fb325" args=")(PP_Resource context, GLenum modeRGB, GLenum modeAlpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#abde0f31c5db8570f37e48a35774fb325">PPB_OpenGLES2::BlendEquationSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeAlpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a18ef5c59756ff3ab71e88e9bdb0d9bdd"></a><!-- doxytag: member="PPB_OpenGLES2::BlendFunc" ref="a18ef5c59756ff3ab71e88e9bdb0d9bdd" args=")(PP_Resource context, GLenum sfactor, GLenum dfactor)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a18ef5c59756ff3ab71e88e9bdb0d9bdd">PPB_OpenGLES2::BlendFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> sfactor, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dfactor)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0fbec684cfce45e7e485684786eb1b08"></a><!-- doxytag: member="PPB_OpenGLES2::BlendFuncSeparate" ref="a0fbec684cfce45e7e485684786eb1b08" args=")(PP_Resource context, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0fbec684cfce45e7e485684786eb1b08">PPB_OpenGLES2::BlendFuncSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcAlpha, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstAlpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa824981bca0cf27ea7443042f7291fee"></a><!-- doxytag: member="PPB_OpenGLES2::BufferData" ref="aa824981bca0cf27ea7443042f7291fee" args=")(PP_Resource context, GLenum target, GLsizeiptr size, const void *data, GLenum usage)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa824981bca0cf27ea7443042f7291fee">PPB_OpenGLES2::BufferData</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> usage)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab25fb15735015c10d4938db6ada4ec6c"></a><!-- doxytag: member="PPB_OpenGLES2::BufferSubData" ref="ab25fb15735015c10d4938db6ada4ec6c" args=")(PP_Resource context, GLenum target, GLintptr offset, GLsizeiptr size, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab25fb15735015c10d4938db6ada4ec6c">PPB_OpenGLES2::BufferSubData</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adf5a6d990941c6cc6620af92a919bb99"></a><!-- doxytag: member="PPB_OpenGLES2::CheckFramebufferStatus" ref="adf5a6d990941c6cc6620af92a919bb99" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adf5a6d990941c6cc6620af92a919bb99">PPB_OpenGLES2::CheckFramebufferStatus</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a23ca838cdb8d41a42b53dd2385a8c802"></a><!-- doxytag: member="PPB_OpenGLES2::Clear" ref="a23ca838cdb8d41a42b53dd2385a8c802" args=")(PP_Resource context, GLbitfield mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a23ca838cdb8d41a42b53dd2385a8c802">PPB_OpenGLES2::Clear</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae6fe1382f1b9ef68862526f454d5a3da"></a><!-- doxytag: member="PPB_OpenGLES2::ClearColor" ref="ae6fe1382f1b9ef68862526f454d5a3da" args=")(PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae6fe1382f1b9ef68862526f454d5a3da">PPB_OpenGLES2::ClearColor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a085fddf29150fa575286a77631db5aa3"></a><!-- doxytag: member="PPB_OpenGLES2::ClearDepthf" ref="a085fddf29150fa575286a77631db5aa3" args=")(PP_Resource context, GLclampf depth)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a085fddf29150fa575286a77631db5aa3">PPB_OpenGLES2::ClearDepthf</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> depth)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab41c6d646fe4a249c8e3c62ac48ae15f"></a><!-- doxytag: member="PPB_OpenGLES2::ClearStencil" ref="ab41c6d646fe4a249c8e3c62ac48ae15f" args=")(PP_Resource context, GLint s)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab41c6d646fe4a249c8e3c62ac48ae15f">PPB_OpenGLES2::ClearStencil</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> s)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ada6b9a86310964424975fe32a8e88dc1"></a><!-- doxytag: member="PPB_OpenGLES2::ColorMask" ref="ada6b9a86310964424975fe32a8e88dc1" args=")(PP_Resource context, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ada6b9a86310964424975fe32a8e88dc1">PPB_OpenGLES2::ColorMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> red, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> green, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> blue, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa307895068405a8e6fd43647d10b2240"></a><!-- doxytag: member="PPB_OpenGLES2::CompileShader" ref="aa307895068405a8e6fd43647d10b2240" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa307895068405a8e6fd43647d10b2240">PPB_OpenGLES2::CompileShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a709df82e66e04d67bad003e1e0432b5a"></a><!-- doxytag: member="PPB_OpenGLES2::CompressedTexImage2D" ref="a709df82e66e04d67bad003e1e0432b5a" args=")(PP_Resource context, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a709df82e66e04d67bad003e1e0432b5a">PPB_OpenGLES2::CompressedTexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a85a4542cd8def2be666c209e9c29d658"></a><!-- doxytag: member="PPB_OpenGLES2::CompressedTexSubImage2D" ref="a85a4542cd8def2be666c209e9c29d658" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a85a4542cd8def2be666c209e9c29d658">PPB_OpenGLES2::CompressedTexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acf78e2322947ad0b62d263f13a03ee4d"></a><!-- doxytag: member="PPB_OpenGLES2::CopyTexImage2D" ref="acf78e2322947ad0b62d263f13a03ee4d" args=")(PP_Resource context, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acf78e2322947ad0b62d263f13a03ee4d">PPB_OpenGLES2::CopyTexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad1ebbf7b46fdc610cf7399a1dbaa65ca"></a><!-- doxytag: member="PPB_OpenGLES2::CopyTexSubImage2D" ref="ad1ebbf7b46fdc610cf7399a1dbaa65ca" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad1ebbf7b46fdc610cf7399a1dbaa65ca">PPB_OpenGLES2::CopyTexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9aeaed06acf5ea610b6eca14cd86b065"></a><!-- doxytag: member="PPB_OpenGLES2::CreateProgram" ref="a9aeaed06acf5ea610b6eca14cd86b065" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9aeaed06acf5ea610b6eca14cd86b065">PPB_OpenGLES2::CreateProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa21109df3da84b9daff8fd755b96e9cd"></a><!-- doxytag: member="PPB_OpenGLES2::CreateShader" ref="aa21109df3da84b9daff8fd755b96e9cd" args=")(PP_Resource context, GLenum type)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa21109df3da84b9daff8fd755b96e9cd">PPB_OpenGLES2::CreateShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab7a3b515cca3b090cf3e53bf503a715c"></a><!-- doxytag: member="PPB_OpenGLES2::CullFace" ref="ab7a3b515cca3b090cf3e53bf503a715c" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab7a3b515cca3b090cf3e53bf503a715c">PPB_OpenGLES2::CullFace</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae918075c7de431c32aa97e26c9591a7f"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteBuffers" ref="ae918075c7de431c32aa97e26c9591a7f" args=")(PP_Resource context, GLsizei n, const GLuint *buffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae918075c7de431c32aa97e26c9591a7f">PPB_OpenGLES2::DeleteBuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7f23a4d62b5b6db480fa0e3ba2d64a6c"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteFramebuffers" ref="a7f23a4d62b5b6db480fa0e3ba2d64a6c" args=")(PP_Resource context, GLsizei n, const GLuint *framebuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7f23a4d62b5b6db480fa0e3ba2d64a6c">PPB_OpenGLES2::DeleteFramebuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2d67942171a98c6151432996f44edbfe"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteProgram" ref="a2d67942171a98c6151432996f44edbfe" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2d67942171a98c6151432996f44edbfe">PPB_OpenGLES2::DeleteProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af9210afd908695511757500a3c368fb6"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteRenderbuffers" ref="af9210afd908695511757500a3c368fb6" args=")(PP_Resource context, GLsizei n, const GLuint *renderbuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af9210afd908695511757500a3c368fb6">PPB_OpenGLES2::DeleteRenderbuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae387aff5d9d0a755ee91f615419781e8"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteShader" ref="ae387aff5d9d0a755ee91f615419781e8" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae387aff5d9d0a755ee91f615419781e8">PPB_OpenGLES2::DeleteShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af417c42c55cccfbb53d66bb7ee3f7630"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteTextures" ref="af417c42c55cccfbb53d66bb7ee3f7630" args=")(PP_Resource context, GLsizei n, const GLuint *textures)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af417c42c55cccfbb53d66bb7ee3f7630">PPB_OpenGLES2::DeleteTextures</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a986605dda31b45565234d66a0a7b91fd"></a><!-- doxytag: member="PPB_OpenGLES2::DepthFunc" ref="a986605dda31b45565234d66a0a7b91fd" args=")(PP_Resource context, GLenum func)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a986605dda31b45565234d66a0a7b91fd">PPB_OpenGLES2::DepthFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acc373d6ee5e6c03b04adb0dd57f72e7e"></a><!-- doxytag: member="PPB_OpenGLES2::DepthMask" ref="acc373d6ee5e6c03b04adb0dd57f72e7e" args=")(PP_Resource context, GLboolean flag)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acc373d6ee5e6c03b04adb0dd57f72e7e">PPB_OpenGLES2::DepthMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> flag)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a97a9c5c3d0cfba11b92e0be2544387b3"></a><!-- doxytag: member="PPB_OpenGLES2::DepthRangef" ref="a97a9c5c3d0cfba11b92e0be2544387b3" args=")(PP_Resource context, GLclampf zNear, GLclampf zFar)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a97a9c5c3d0cfba11b92e0be2544387b3">PPB_OpenGLES2::DepthRangef</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zNear, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zFar)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acdae43713f391b50f0d9dc3538872e98"></a><!-- doxytag: member="PPB_OpenGLES2::DetachShader" ref="acdae43713f391b50f0d9dc3538872e98" args=")(PP_Resource context, GLuint program, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acdae43713f391b50f0d9dc3538872e98">PPB_OpenGLES2::DetachShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a761da4c86a553666677e91b0af52ef3f"></a><!-- doxytag: member="PPB_OpenGLES2::Disable" ref="a761da4c86a553666677e91b0af52ef3f" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a761da4c86a553666677e91b0af52ef3f">PPB_OpenGLES2::Disable</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6db7cbbe276ec1b207bf07c004bc8cce"></a><!-- doxytag: member="PPB_OpenGLES2::DisableVertexAttribArray" ref="a6db7cbbe276ec1b207bf07c004bc8cce" args=")(PP_Resource context, GLuint index)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6db7cbbe276ec1b207bf07c004bc8cce">PPB_OpenGLES2::DisableVertexAttribArray</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adeaf1eb89288064288f1be4f97d1e8e8"></a><!-- doxytag: member="PPB_OpenGLES2::DrawArrays" ref="adeaf1eb89288064288f1be4f97d1e8e8" args=")(PP_Resource context, GLenum mode, GLint first, GLsizei count)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adeaf1eb89288064288f1be4f97d1e8e8">PPB_OpenGLES2::DrawArrays</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aebe63866d604b1a7ad0f04b6c10c7404"></a><!-- doxytag: member="PPB_OpenGLES2::DrawElements" ref="aebe63866d604b1a7ad0f04b6c10c7404" args=")(PP_Resource context, GLenum mode, GLsizei count, GLenum type, const void *indices)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aebe63866d604b1a7ad0f04b6c10c7404">PPB_OpenGLES2::DrawElements</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0c69b4f342992dc423de86baf57d1553"></a><!-- doxytag: member="PPB_OpenGLES2::Enable" ref="a0c69b4f342992dc423de86baf57d1553" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0c69b4f342992dc423de86baf57d1553">PPB_OpenGLES2::Enable</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa2c0b80eba15506af0f1ac28f778342a"></a><!-- doxytag: member="PPB_OpenGLES2::EnableVertexAttribArray" ref="aa2c0b80eba15506af0f1ac28f778342a" args=")(PP_Resource context, GLuint index)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa2c0b80eba15506af0f1ac28f778342a">PPB_OpenGLES2::EnableVertexAttribArray</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a81ec538158ea1d6a92fa3682e8baf9cb"></a><!-- doxytag: member="PPB_OpenGLES2::Finish" ref="a81ec538158ea1d6a92fa3682e8baf9cb" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a81ec538158ea1d6a92fa3682e8baf9cb">PPB_OpenGLES2::Finish</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac511f0c2abf05cb898202a025e7a4c2f"></a><!-- doxytag: member="PPB_OpenGLES2::Flush" ref="ac511f0c2abf05cb898202a025e7a4c2f" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac511f0c2abf05cb898202a025e7a4c2f">PPB_OpenGLES2::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a92b35ec6669001aa38c53a75ca597166"></a><!-- doxytag: member="PPB_OpenGLES2::FramebufferRenderbuffer" ref="a92b35ec6669001aa38c53a75ca597166" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a92b35ec6669001aa38c53a75ca597166">PPB_OpenGLES2::FramebufferRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> renderbuffertarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae0871e157118a4f56b66482bede75af0"></a><!-- doxytag: member="PPB_OpenGLES2::FramebufferTexture2D" ref="ae0871e157118a4f56b66482bede75af0" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae0871e157118a4f56b66482bede75af0">PPB_OpenGLES2::FramebufferTexture2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> textarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a35f542c3f15f0e028f01eacfd57cd290"></a><!-- doxytag: member="PPB_OpenGLES2::FrontFace" ref="a35f542c3f15f0e028f01eacfd57cd290" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a35f542c3f15f0e028f01eacfd57cd290">PPB_OpenGLES2::FrontFace</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3021ad890d7faf61f1656caff69e2936"></a><!-- doxytag: member="PPB_OpenGLES2::GenBuffers" ref="a3021ad890d7faf61f1656caff69e2936" args=")(PP_Resource context, GLsizei n, GLuint *buffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3021ad890d7faf61f1656caff69e2936">PPB_OpenGLES2::GenBuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa5219fe93e4fe1566f058730237511a3"></a><!-- doxytag: member="PPB_OpenGLES2::GenerateMipmap" ref="aa5219fe93e4fe1566f058730237511a3" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aa5219fe93e4fe1566f058730237511a3">PPB_OpenGLES2::GenerateMipmap</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac046a9b0e3bbe97336df2f1ed4f363aa"></a><!-- doxytag: member="PPB_OpenGLES2::GenFramebuffers" ref="ac046a9b0e3bbe97336df2f1ed4f363aa" args=")(PP_Resource context, GLsizei n, GLuint *framebuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac046a9b0e3bbe97336df2f1ed4f363aa">PPB_OpenGLES2::GenFramebuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a95064b43b8b85251f25d4a99a212ffa2"></a><!-- doxytag: member="PPB_OpenGLES2::GenRenderbuffers" ref="a95064b43b8b85251f25d4a99a212ffa2" args=")(PP_Resource context, GLsizei n, GLuint *renderbuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a95064b43b8b85251f25d4a99a212ffa2">PPB_OpenGLES2::GenRenderbuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a88871423b8bd9fb8b5224679cae7319d"></a><!-- doxytag: member="PPB_OpenGLES2::GenTextures" ref="a88871423b8bd9fb8b5224679cae7319d" args=")(PP_Resource context, GLsizei n, GLuint *textures)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a88871423b8bd9fb8b5224679cae7319d">PPB_OpenGLES2::GenTextures</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a01c888fbe0b5e4b7253ada24c2822c1a"></a><!-- doxytag: member="PPB_OpenGLES2::GetActiveAttrib" ref="a01c888fbe0b5e4b7253ada24c2822c1a" args=")(PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a01c888fbe0b5e4b7253ada24c2822c1a">PPB_OpenGLES2::GetActiveAttrib</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adb76d45821a6a01bd2e9cf290ade6393"></a><!-- doxytag: member="PPB_OpenGLES2::GetActiveUniform" ref="adb76d45821a6a01bd2e9cf290ade6393" args=")(PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#adb76d45821a6a01bd2e9cf290ade6393">PPB_OpenGLES2::GetActiveUniform</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8bcc540aaa53ed190984ff476f022dbc"></a><!-- doxytag: member="PPB_OpenGLES2::GetAttachedShaders" ref="a8bcc540aaa53ed190984ff476f022dbc" args=")(PP_Resource context, GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8bcc540aaa53ed190984ff476f022dbc">PPB_OpenGLES2::GetAttachedShaders</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> maxcount, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *count, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5e10f14b16bedf58f4a4d82faae92fce"></a><!-- doxytag: member="PPB_OpenGLES2::GetAttribLocation" ref="a5e10f14b16bedf58f4a4d82faae92fce" args=")(PP_Resource context, GLuint program, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5e10f14b16bedf58f4a4d82faae92fce">PPB_OpenGLES2::GetAttribLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a469a602f25f7a960828a33c039221b05"></a><!-- doxytag: member="PPB_OpenGLES2::GetBooleanv" ref="a469a602f25f7a960828a33c039221b05" args=")(PP_Resource context, GLenum pname, GLboolean *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a469a602f25f7a960828a33c039221b05">PPB_OpenGLES2::GetBooleanv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a274a18138ca82e21087a3bc09e0c5d6e"></a><!-- doxytag: member="PPB_OpenGLES2::GetBufferParameteriv" ref="a274a18138ca82e21087a3bc09e0c5d6e" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a274a18138ca82e21087a3bc09e0c5d6e">PPB_OpenGLES2::GetBufferParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad7a51a4767acf70e3c691f5715da66b2"></a><!-- doxytag: member="PPB_OpenGLES2::GetError" ref="ad7a51a4767acf70e3c691f5715da66b2" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad7a51a4767acf70e3c691f5715da66b2">PPB_OpenGLES2::GetError</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2b162ab5408f1862ede23100c1a98ed4"></a><!-- doxytag: member="PPB_OpenGLES2::GetFloatv" ref="a2b162ab5408f1862ede23100c1a98ed4" args=")(PP_Resource context, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2b162ab5408f1862ede23100c1a98ed4">PPB_OpenGLES2::GetFloatv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af044cc978a541ff66d6bfcb81d0c9797"></a><!-- doxytag: member="PPB_OpenGLES2::GetFramebufferAttachmentParameteriv" ref="af044cc978a541ff66d6bfcb81d0c9797" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af044cc978a541ff66d6bfcb81d0c9797">PPB_OpenGLES2::GetFramebufferAttachmentParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6cbe6db1beec8544f5d766b347c1b774"></a><!-- doxytag: member="PPB_OpenGLES2::GetIntegerv" ref="a6cbe6db1beec8544f5d766b347c1b774" args=")(PP_Resource context, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6cbe6db1beec8544f5d766b347c1b774">PPB_OpenGLES2::GetIntegerv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a899415b7473fc77870102dc1e0eedfa6"></a><!-- doxytag: member="PPB_OpenGLES2::GetProgramInfoLog" ref="a899415b7473fc77870102dc1e0eedfa6" args=")(PP_Resource context, GLuint program, GLsizei bufsize, GLsizei *length, char *infolog)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a899415b7473fc77870102dc1e0eedfa6">PPB_OpenGLES2::GetProgramInfoLog</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="afaddb913ffc38cc8075adf7b63c1cacb"></a><!-- doxytag: member="PPB_OpenGLES2::GetProgramiv" ref="afaddb913ffc38cc8075adf7b63c1cacb" args=")(PP_Resource context, GLuint program, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afaddb913ffc38cc8075adf7b63c1cacb">PPB_OpenGLES2::GetProgramiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af16e81d3abb5c7b12b9ef94351a8582a"></a><!-- doxytag: member="PPB_OpenGLES2::GetRenderbufferParameteriv" ref="af16e81d3abb5c7b12b9ef94351a8582a" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af16e81d3abb5c7b12b9ef94351a8582a">PPB_OpenGLES2::GetRenderbufferParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0c7aeac48bb1b7cd9ecf8ebb6e160b21"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderInfoLog" ref="a0c7aeac48bb1b7cd9ecf8ebb6e160b21" args=")(PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0c7aeac48bb1b7cd9ecf8ebb6e160b21">PPB_OpenGLES2::GetShaderInfoLog</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab497e96f8254d499e09f37f34c4fa20f"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderiv" ref="ab497e96f8254d499e09f37f34c4fa20f" args=")(PP_Resource context, GLuint shader, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab497e96f8254d499e09f37f34c4fa20f">PPB_OpenGLES2::GetShaderiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a07b780398cd5f0cbe4b66d47f6bc7432"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderPrecisionFormat" ref="a07b780398cd5f0cbe4b66d47f6bc7432" args=")(PP_Resource context, GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a07b780398cd5f0cbe4b66d47f6bc7432">PPB_OpenGLES2::GetShaderPrecisionFormat</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> shadertype, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> precisiontype, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *range, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *precision)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a999a0c63cd2695c4f97d267412804470"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderSource" ref="a999a0c63cd2695c4f97d267412804470" args=")(PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei *length, char *source)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a999a0c63cd2695c4f97d267412804470">PPB_OpenGLES2::GetShaderSource</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *source)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a51fe0f4d9dc7efb5bb5185ea23ed7854"></a><!-- doxytag: member="PPB_OpenGLES2::GetString" ref="a51fe0f4d9dc7efb5bb5185ea23ed7854" args=")(PP_Resource context, GLenum name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">const <a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a>*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a51fe0f4d9dc7efb5bb5185ea23ed7854">PPB_OpenGLES2::GetString</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8ed1ea3e802fd72c1abca830757c4760"></a><!-- doxytag: member="PPB_OpenGLES2::GetTexParameterfv" ref="a8ed1ea3e802fd72c1abca830757c4760" args=")(PP_Resource context, GLenum target, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8ed1ea3e802fd72c1abca830757c4760">PPB_OpenGLES2::GetTexParameterfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a394d2e8e9382cc526856e760c7a99ab4"></a><!-- doxytag: member="PPB_OpenGLES2::GetTexParameteriv" ref="a394d2e8e9382cc526856e760c7a99ab4" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a394d2e8e9382cc526856e760c7a99ab4">PPB_OpenGLES2::GetTexParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a68d5adab1ca625fe4c08e11cf8ff5a76"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformfv" ref="a68d5adab1ca625fe4c08e11cf8ff5a76" args=")(PP_Resource context, GLuint program, GLint location, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a68d5adab1ca625fe4c08e11cf8ff5a76">PPB_OpenGLES2::GetUniformfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0ccf7b97de2a07a2885c9c1f01dbc423"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformiv" ref="a0ccf7b97de2a07a2885c9c1f01dbc423" args=")(PP_Resource context, GLuint program, GLint location, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0ccf7b97de2a07a2885c9c1f01dbc423">PPB_OpenGLES2::GetUniformiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae2c5c0efd5ee3ea2106c20bdad49cd25"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformLocation" ref="ae2c5c0efd5ee3ea2106c20bdad49cd25" args=")(PP_Resource context, GLuint program, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae2c5c0efd5ee3ea2106c20bdad49cd25">PPB_OpenGLES2::GetUniformLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aca40defa62c9536428a64d59ab07c83e"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribfv" ref="aca40defa62c9536428a64d59ab07c83e" args=")(PP_Resource context, GLuint index, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aca40defa62c9536428a64d59ab07c83e">PPB_OpenGLES2::GetVertexAttribfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a632b9ffc9fbf4f3332bd39e3e67221a2"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribiv" ref="a632b9ffc9fbf4f3332bd39e3e67221a2" args=")(PP_Resource context, GLuint index, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a632b9ffc9fbf4f3332bd39e3e67221a2">PPB_OpenGLES2::GetVertexAttribiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5a0bf76ee7e291db46a2358fbeaf6fa8"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribPointerv" ref="a5a0bf76ee7e291db46a2358fbeaf6fa8" args=")(PP_Resource context, GLuint index, GLenum pname, void **pointer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5a0bf76ee7e291db46a2358fbeaf6fa8">PPB_OpenGLES2::GetVertexAttribPointerv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, void **pointer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af443ce0d45468872824a3312eb538fd6"></a><!-- doxytag: member="PPB_OpenGLES2::Hint" ref="af443ce0d45468872824a3312eb538fd6" args=")(PP_Resource context, GLenum target, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af443ce0d45468872824a3312eb538fd6">PPB_OpenGLES2::Hint</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a22a9ee9465ede518ff017177605569c8"></a><!-- doxytag: member="PPB_OpenGLES2::IsBuffer" ref="a22a9ee9465ede518ff017177605569c8" args=")(PP_Resource context, GLuint buffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a22a9ee9465ede518ff017177605569c8">PPB_OpenGLES2::IsBuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1b94166b764d69207e61055ae7cebe9c"></a><!-- doxytag: member="PPB_OpenGLES2::IsEnabled" ref="a1b94166b764d69207e61055ae7cebe9c" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1b94166b764d69207e61055ae7cebe9c">PPB_OpenGLES2::IsEnabled</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a243afc655b0c8d331656957f4878bd38"></a><!-- doxytag: member="PPB_OpenGLES2::IsFramebuffer" ref="a243afc655b0c8d331656957f4878bd38" args=")(PP_Resource context, GLuint framebuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a243afc655b0c8d331656957f4878bd38">PPB_OpenGLES2::IsFramebuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab15ed85d340670c3f629e33cdaf11ff4"></a><!-- doxytag: member="PPB_OpenGLES2::IsProgram" ref="ab15ed85d340670c3f629e33cdaf11ff4" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab15ed85d340670c3f629e33cdaf11ff4">PPB_OpenGLES2::IsProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abfdc2a929818dce1c2bbcfb24cd00fd2"></a><!-- doxytag: member="PPB_OpenGLES2::IsRenderbuffer" ref="abfdc2a929818dce1c2bbcfb24cd00fd2" args=")(PP_Resource context, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#abfdc2a929818dce1c2bbcfb24cd00fd2">PPB_OpenGLES2::IsRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a51bb4c4cb9a4ad680a3b69e5d94284d9"></a><!-- doxytag: member="PPB_OpenGLES2::IsShader" ref="a51bb4c4cb9a4ad680a3b69e5d94284d9" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a51bb4c4cb9a4ad680a3b69e5d94284d9">PPB_OpenGLES2::IsShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae8ff9c47061f6b1e604d5d6bd1a93e2d"></a><!-- doxytag: member="PPB_OpenGLES2::IsTexture" ref="ae8ff9c47061f6b1e604d5d6bd1a93e2d" args=")(PP_Resource context, GLuint texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8ff9c47061f6b1e604d5d6bd1a93e2d">PPB_OpenGLES2::IsTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a33169bd4752db53cf6e25ef78db83a6d"></a><!-- doxytag: member="PPB_OpenGLES2::LineWidth" ref="a33169bd4752db53cf6e25ef78db83a6d" args=")(PP_Resource context, GLfloat width)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a33169bd4752db53cf6e25ef78db83a6d">PPB_OpenGLES2::LineWidth</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> width)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae8969408a22f4abe20575497e587fae6"></a><!-- doxytag: member="PPB_OpenGLES2::LinkProgram" ref="ae8969408a22f4abe20575497e587fae6" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ae8969408a22f4abe20575497e587fae6">PPB_OpenGLES2::LinkProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0690e80898a4ce4421512f5da9614cca"></a><!-- doxytag: member="PPB_OpenGLES2::PixelStorei" ref="a0690e80898a4ce4421512f5da9614cca" args=")(PP_Resource context, GLenum pname, GLint param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0690e80898a4ce4421512f5da9614cca">PPB_OpenGLES2::PixelStorei</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a79d1b98f9b4586b4ed6b2a89f6de98be"></a><!-- doxytag: member="PPB_OpenGLES2::PolygonOffset" ref="a79d1b98f9b4586b4ed6b2a89f6de98be" args=")(PP_Resource context, GLfloat factor, GLfloat units)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79d1b98f9b4586b4ed6b2a89f6de98be">PPB_OpenGLES2::PolygonOffset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> factor, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> units)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9ca1f371a2933be66db0340a3361753c"></a><!-- doxytag: member="PPB_OpenGLES2::ReadPixels" ref="a9ca1f371a2933be66db0340a3361753c" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ca1f371a2933be66db0340a3361753c">PPB_OpenGLES2::ReadPixels</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3b70d85227ab102e942371c099d1af0d"></a><!-- doxytag: member="PPB_OpenGLES2::ReleaseShaderCompiler" ref="a3b70d85227ab102e942371c099d1af0d" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a3b70d85227ab102e942371c099d1af0d">PPB_OpenGLES2::ReleaseShaderCompiler</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ace64a122c95174d26f22cd2f8bb82cd0"></a><!-- doxytag: member="PPB_OpenGLES2::RenderbufferStorage" ref="ace64a122c95174d26f22cd2f8bb82cd0" args=")(PP_Resource context, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ace64a122c95174d26f22cd2f8bb82cd0">PPB_OpenGLES2::RenderbufferStorage</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad80041090ea0856551a5aa7683f9a754"></a><!-- doxytag: member="PPB_OpenGLES2::SampleCoverage" ref="ad80041090ea0856551a5aa7683f9a754" args=")(PP_Resource context, GLclampf value, GLboolean invert)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad80041090ea0856551a5aa7683f9a754">PPB_OpenGLES2::SampleCoverage</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> value, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> invert)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a76bd885cc06b8f993a9dd4b4beba8507"></a><!-- doxytag: member="PPB_OpenGLES2::Scissor" ref="a76bd885cc06b8f993a9dd4b4beba8507" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a76bd885cc06b8f993a9dd4b4beba8507">PPB_OpenGLES2::Scissor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="add8cdccd7afe3115c0db6488244710f1"></a><!-- doxytag: member="PPB_OpenGLES2::ShaderBinary" ref="add8cdccd7afe3115c0db6488244710f1" args=")(PP_Resource context, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#add8cdccd7afe3115c0db6488244710f1">PPB_OpenGLES2::ShaderBinary</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> binaryformat, const void *binary, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> length)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a54563f901d3d4b68059f72f689367d04"></a><!-- doxytag: member="PPB_OpenGLES2::ShaderSource" ref="a54563f901d3d4b68059f72f689367d04" args=")(PP_Resource context, GLuint shader, GLsizei count, const char **str, const GLint *length)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a54563f901d3d4b68059f72f689367d04">PPB_OpenGLES2::ShaderSource</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const char **str, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *length)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab09dfe9c3aa76b033a7a899ef83881ec"></a><!-- doxytag: member="PPB_OpenGLES2::StencilFunc" ref="ab09dfe9c3aa76b033a7a899ef83881ec" args=")(PP_Resource context, GLenum func, GLint ref, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab09dfe9c3aa76b033a7a899ef83881ec">PPB_OpenGLES2::StencilFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a13947e07ef135ccfb3664d7481d88f52"></a><!-- doxytag: member="PPB_OpenGLES2::StencilFuncSeparate" ref="a13947e07ef135ccfb3664d7481d88f52" args=")(PP_Resource context, GLenum face, GLenum func, GLint ref, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a13947e07ef135ccfb3664d7481d88f52">PPB_OpenGLES2::StencilFuncSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a582bf1efee1ce4ed489d2a2bd051ba70"></a><!-- doxytag: member="PPB_OpenGLES2::StencilMask" ref="a582bf1efee1ce4ed489d2a2bd051ba70" args=")(PP_Resource context, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a582bf1efee1ce4ed489d2a2bd051ba70">PPB_OpenGLES2::StencilMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9ecc42baba61b5f0ffb2acc7a846add4"></a><!-- doxytag: member="PPB_OpenGLES2::StencilMaskSeparate" ref="a9ecc42baba61b5f0ffb2acc7a846add4" args=")(PP_Resource context, GLenum face, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ecc42baba61b5f0ffb2acc7a846add4">PPB_OpenGLES2::StencilMaskSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2ec4b7407b261ab83dac6617024968d1"></a><!-- doxytag: member="PPB_OpenGLES2::StencilOp" ref="a2ec4b7407b261ab83dac6617024968d1" args=")(PP_Resource context, GLenum fail, GLenum zfail, GLenum zpass)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2ec4b7407b261ab83dac6617024968d1">PPB_OpenGLES2::StencilOp</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a832bb94b26d3f3ef9c25e260e51c682a"></a><!-- doxytag: member="PPB_OpenGLES2::StencilOpSeparate" ref="a832bb94b26d3f3ef9c25e260e51c682a" args=")(PP_Resource context, GLenum face, GLenum fail, GLenum zfail, GLenum zpass)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a832bb94b26d3f3ef9c25e260e51c682a">PPB_OpenGLES2::StencilOpSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af5e5e8ac2991acc411bc8e7349a4528c"></a><!-- doxytag: member="PPB_OpenGLES2::TexImage2D" ref="af5e5e8ac2991acc411bc8e7349a4528c" args=")(PP_Resource context, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af5e5e8ac2991acc411bc8e7349a4528c">PPB_OpenGLES2::TexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1e247c4eba9d9b83fc3faa95ad2695b3"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameterf" ref="a1e247c4eba9d9b83fc3faa95ad2695b3" args=")(PP_Resource context, GLenum target, GLenum pname, GLfloat param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1e247c4eba9d9b83fc3faa95ad2695b3">PPB_OpenGLES2::TexParameterf</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1fbfa876dce5f8b4a54ae357e9f94f3d"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameterfv" ref="a1fbfa876dce5f8b4a54ae357e9f94f3d" args=")(PP_Resource context, GLenum target, GLenum pname, const GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a1fbfa876dce5f8b4a54ae357e9f94f3d">PPB_OpenGLES2::TexParameterfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4103d52b8c7d312f623e256be6bfdc34"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameteri" ref="a4103d52b8c7d312f623e256be6bfdc34" args=")(PP_Resource context, GLenum target, GLenum pname, GLint param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a4103d52b8c7d312f623e256be6bfdc34">PPB_OpenGLES2::TexParameteri</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a760b43042385f6ea828a540c477655be"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameteriv" ref="a760b43042385f6ea828a540c477655be" args=")(PP_Resource context, GLenum target, GLenum pname, const GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a760b43042385f6ea828a540c477655be">PPB_OpenGLES2::TexParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac13af0c1267510083e8b2db368f3d5f9"></a><!-- doxytag: member="PPB_OpenGLES2::TexSubImage2D" ref="ac13af0c1267510083e8b2db368f3d5f9" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ac13af0c1267510083e8b2db368f3d5f9">PPB_OpenGLES2::TexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab619fb1afcdca0291f2002a49d70263d"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1f" ref="ab619fb1afcdca0291f2002a49d70263d" args=")(PP_Resource context, GLint location, GLfloat x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab619fb1afcdca0291f2002a49d70263d">PPB_OpenGLES2::Uniform1f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9a114745de0223354a3f8ac0692c3d86"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1fv" ref="a9a114745de0223354a3f8ac0692c3d86" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9a114745de0223354a3f8ac0692c3d86">PPB_OpenGLES2::Uniform1fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a334011bf29706a264623c099cf3e638e"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1i" ref="a334011bf29706a264623c099cf3e638e" args=")(PP_Resource context, GLint location, GLint x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a334011bf29706a264623c099cf3e638e">PPB_OpenGLES2::Uniform1i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad3afadbd84c98b021f4352a0ed25258e"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1iv" ref="ad3afadbd84c98b021f4352a0ed25258e" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ad3afadbd84c98b021f4352a0ed25258e">PPB_OpenGLES2::Uniform1iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5459521734fcc78b4d541f8a443c26e5"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2f" ref="a5459521734fcc78b4d541f8a443c26e5" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5459521734fcc78b4d541f8a443c26e5">PPB_OpenGLES2::Uniform2f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab90ca755ee6ecbe8baa31b6e7e0d94ef"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2fv" ref="ab90ca755ee6ecbe8baa31b6e7e0d94ef" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#ab90ca755ee6ecbe8baa31b6e7e0d94ef">PPB_OpenGLES2::Uniform2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a787d002ec3d31e7b6872e71261dade2c"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2i" ref="a787d002ec3d31e7b6872e71261dade2c" args=")(PP_Resource context, GLint location, GLint x, GLint y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a787d002ec3d31e7b6872e71261dade2c">PPB_OpenGLES2::Uniform2i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7ef8e80ef0bbd1d944e9165ef341bc20"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2iv" ref="a7ef8e80ef0bbd1d944e9165ef341bc20" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7ef8e80ef0bbd1d944e9165ef341bc20">PPB_OpenGLES2::Uniform2iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6512a43696bded1489f3b2d47d666d6c"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3f" ref="a6512a43696bded1489f3b2d47d666d6c" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a6512a43696bded1489f3b2d47d666d6c">PPB_OpenGLES2::Uniform3f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4562834999794d2dfed644527f28de05"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3fv" ref="a4562834999794d2dfed644527f28de05" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a4562834999794d2dfed644527f28de05">PPB_OpenGLES2::Uniform3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a79dbfecdc82f934e09bb244993429478"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3i" ref="a79dbfecdc82f934e09bb244993429478" args=")(PP_Resource context, GLint location, GLint x, GLint y, GLint z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79dbfecdc82f934e09bb244993429478">PPB_OpenGLES2::Uniform3i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7838d459375aede455d708c5593558d7"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3iv" ref="a7838d459375aede455d708c5593558d7" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7838d459375aede455d708c5593558d7">PPB_OpenGLES2::Uniform3iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acae286535d8c99ba10459b1509aa7f33"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4f" ref="acae286535d8c99ba10459b1509aa7f33" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#acae286535d8c99ba10459b1509aa7f33">PPB_OpenGLES2::Uniform4f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="afbd5c631094027ec297959995345ae45"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4fv" ref="afbd5c631094027ec297959995345ae45" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afbd5c631094027ec297959995345ae45">PPB_OpenGLES2::Uniform4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9ad04ea982dcf2bd1d8ce4e205dca158"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4i" ref="a9ad04ea982dcf2bd1d8ce4e205dca158" args=")(PP_Resource context, GLint location, GLint x, GLint y, GLint z, GLint w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ad04ea982dcf2bd1d8ce4e205dca158">PPB_OpenGLES2::Uniform4i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a85fa410e905c328f3d0e81ee1f8a6e3b"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4iv" ref="a85fa410e905c328f3d0e81ee1f8a6e3b" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a85fa410e905c328f3d0e81ee1f8a6e3b">PPB_OpenGLES2::Uniform4iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af44e9dc9f83b3b681ce478fe4051415e"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix2fv" ref="af44e9dc9f83b3b681ce478fe4051415e" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af44e9dc9f83b3b681ce478fe4051415e">PPB_OpenGLES2::UniformMatrix2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0a136244b97c8dd351e24305767f2735"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix3fv" ref="a0a136244b97c8dd351e24305767f2735" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a0a136244b97c8dd351e24305767f2735">PPB_OpenGLES2::UniformMatrix3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9ac470e9e4a9dedf0e359001a52c42cc"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix4fv" ref="a9ac470e9e4a9dedf0e359001a52c42cc" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a9ac470e9e4a9dedf0e359001a52c42cc">PPB_OpenGLES2::UniformMatrix4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a300168f1b2fcb58a5087654224c6ab47"></a><!-- doxytag: member="PPB_OpenGLES2::UseProgram" ref="a300168f1b2fcb58a5087654224c6ab47" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a300168f1b2fcb58a5087654224c6ab47">PPB_OpenGLES2::UseProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8119f3f8b731cce9143da0cc0c4ddd9c"></a><!-- doxytag: member="PPB_OpenGLES2::ValidateProgram" ref="a8119f3f8b731cce9143da0cc0c4ddd9c" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a8119f3f8b731cce9143da0cc0c4ddd9c">PPB_OpenGLES2::ValidateProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a46f108883a33981a78b6276c7a4e1305"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib1f" ref="a46f108883a33981a78b6276c7a4e1305" args=")(PP_Resource context, GLuint indx, GLfloat x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a46f108883a33981a78b6276c7a4e1305">PPB_OpenGLES2::VertexAttrib1f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5228b6fcf8d0a65fcc8a94eb08697987"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib1fv" ref="a5228b6fcf8d0a65fcc8a94eb08697987" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a5228b6fcf8d0a65fcc8a94eb08697987">PPB_OpenGLES2::VertexAttrib1fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a96c6934bbaac1aa1625771ee27e18f29"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib2f" ref="a96c6934bbaac1aa1625771ee27e18f29" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a96c6934bbaac1aa1625771ee27e18f29">PPB_OpenGLES2::VertexAttrib2f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a79ecc589e72b0467e3e4517b414cb27a"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib2fv" ref="a79ecc589e72b0467e3e4517b414cb27a" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a79ecc589e72b0467e3e4517b414cb27a">PPB_OpenGLES2::VertexAttrib2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aecaa4d98853876c3837a0be6a1b1c665"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib3f" ref="aecaa4d98853876c3837a0be6a1b1c665" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#aecaa4d98853876c3837a0be6a1b1c665">PPB_OpenGLES2::VertexAttrib3f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a19e465e1c372bf95275feea87046ecf8"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib3fv" ref="a19e465e1c372bf95275feea87046ecf8" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a19e465e1c372bf95275feea87046ecf8">PPB_OpenGLES2::VertexAttrib3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2c55091b7ec4e7ac1df480f7401921ac"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib4f" ref="a2c55091b7ec4e7ac1df480f7401921ac" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a2c55091b7ec4e7ac1df480f7401921ac">PPB_OpenGLES2::VertexAttrib4f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7a857a7cb2e0e5b79b18e94b3910e9d4"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib4fv" ref="a7a857a7cb2e0e5b79b18e94b3910e9d4" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#a7a857a7cb2e0e5b79b18e94b3910e9d4">PPB_OpenGLES2::VertexAttrib4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="afd77adfbe7ea0b4d85863c6cfd4e2025"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttribPointer" ref="afd77adfbe7ea0b4d85863c6cfd4e2025" args=")(PP_Resource context, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#afd77adfbe7ea0b4d85863c6cfd4e2025">PPB_OpenGLES2::VertexAttribPointer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> normalized, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> stride, const void *ptr)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af8e6a3080571bee2377c0ce1d73a4ff8"></a><!-- doxytag: member="PPB_OpenGLES2::Viewport" ref="af8e6a3080571bee2377c0ce1d73a4ff8" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2.html#af8e6a3080571bee2377c0ce1d73a4ff8">PPB_OpenGLES2::Viewport</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2__1__0.html new file mode 100644 index 0000000..b557a7f --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2__1__0.html
@@ -0,0 +1,1868 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2 Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa34e464b586eaa61f67ef887a7bc2655">ActiveTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af5f501df60bb679c8ad67e342af8fdeb">AttachShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae287fae397e261b479a8228f24b69541">BindAttribLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae4779ea65ccdc556dfb47783e61fa3e9">BindBuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a70b68978c44dc2b1184cdb5ce982eac6">BindFramebuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1c2e36a931c81a274e28079e3a910390">BindRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abc8a5b7c5352bb63143480b7ba41a5f1">BindTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adbd2c2c1ffd4520992a210d0fe4f1643">BlendColor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a271602e4972c250bd48239e813fc9e89">BlendEquation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#accada00419e1c2d24f98374c202f5bdc">BlendEquationSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeAlpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a01d69f0dc88ae07cc26cf6af13ab8dd0">BlendFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> sfactor, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dfactor)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#acc46008a5377d37da1bbb922d12fd302">BlendFuncSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcAlpha, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstAlpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab8a24c0fc55782ea4a77b8a8f4c18ee9">BufferData</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> usage)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4dc9e1fbe6f424c367cff48874288d95">BufferSubData</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a68c09a107daa525accbd810af5d8b7e7">CheckFramebufferStatus</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aab191f4226b69a785ac321019ac458d4">Clear</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a59b2ed69ce80d1d2833914faa1518766">ClearColor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad5c13e5d77633c26f686b5af5cd7727d">ClearDepthf</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> depth)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac4a4c5c73753fbe0093405b3b0fd9c87">ClearStencil</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> s)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a43ba4bbe1438a6040d6df6a5fd111ea9">ColorMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> red, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> green, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> blue, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> alpha)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab22a837b8f304dde44a8337bef5dba25">CompileShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0fc10275f13764beb343cad905100fa7">CompressedTexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a488f48b4eaec02b7d0f9539d34355477">CompressedTexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af74b42925bde9e13a802e6ad2c0af02a">CopyTexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad00d27aeabf8477aeed12646d1180207">CopyTexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac2bbfa75734a508ea13eb748cc7715af">CreateProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2371aecb935d34d94af08fd197f23291">CreateShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af07caadc9a21fb31213adf41d687ff0b">CullFace</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab5ca12ee3e483450fffac2cf856f7ab5">DeleteBuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a79fa4d36bf1b5ba42402b1362220e631">DeleteFramebuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a16bf7f6e2ded12e19f34f6751969ad82">DeleteProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a17fb01cbcc24025c5ae10ae776171288">DeleteRenderbuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a5fcb36e0753e624fe181cc23639a71b2">DeleteShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3bf6533616420836fa291e8466aae8ba">DeleteTextures</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9b86654205f1d45939e9f7a007665a50">DepthFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac931d374fc3cd241539c0af6b229733f">DepthMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> flag)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6dc83777e28dd2cf3a3fbadece1637ec">DepthRangef</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zNear, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zFar)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adb09849032fbdee9b4018362d8046d8a">DetachShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adf10ac1a5115bb7cfecd820fee414543">Disable</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a023ce8e59c8c83b37f2425d4642abafa">DisableVertexAttribArray</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a00f3701866e04c87e390deeda6a3dc4e">DrawArrays</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4420853d86445b1c98ed6a51c2ee3ca4">DrawElements</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9faf8c7a761912a3e93f2f531a1a14c0">Enable</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae91777d77008df1ddfa0d7310c9858fc">EnableVertexAttribArray</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad27973d7b18a026a1019b4c94c42f017">Finish</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a40ea416a21e56c24b4bac14983b19f16">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab054ffa4f3e478a3026ab05a54f05a6a">FramebufferRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> renderbuffertarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a37f4d4823ff074ae5833d3b847953eee">FramebufferTexture2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> textarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a503ed7ba907260fd6bac5d6133da2502">FrontFace</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a22ea29492beb072b3e7f197c8243b895">GenBuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8fed425b72e4c2c5c038dc431c21c5b9">GenerateMipmap</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad14fc6bfd2571ca47f690587810e45ed">GenFramebuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a57a223eb049a5e37cd8e12258dcdf893">GenRenderbuffers</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af41e0b0c6ff3c9e95739e6585734e1c0">GenTextures</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a883e45e81157db95ff7155957a092800">GetActiveAttrib</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2a086b77b1a282c52e3c348f9c9a1080">GetActiveUniform</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aece846b6c38b17080b2593a5302536cf">GetAttachedShaders</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> maxcount, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *count, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aca2b12aa379dfc7069905c7d7acd1972">GetAttribLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a930a044665be6916f46ed51b5473fe6b">GetBooleanv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af4b62f5d61131d59c3a274b57ada67b5">GetBufferParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae25222a3a3a50368bf6ffa61fd527473">GetError</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab81d1639b6c0f0667ab344dcbc66217e">GetFloatv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac0f25a003e7077fa79954e9fe453b62c">GetFramebufferAttachmentParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a797e58efe3e7c0cfa12208bae75084f4">GetIntegerv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8045b6b71041fcee85e92e40169fc361">GetProgramiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0c45941c3c120035f0857709c65c6604">GetProgramInfoLog</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a42ffdc030fb99a76a47605e05489a182">GetRenderbufferParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af9b7ea14515e35488883481699194764">GetShaderiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a24e99f31bc2602c3d2cd4d8022fa5888">GetShaderInfoLog</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac44fd9e32e88c735ea4d01380d7c4df7">GetShaderPrecisionFormat</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> shadertype, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> precisiontype, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *range, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *precision)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af696668edf764584e867b4fa43231358">GetShaderSource</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *source)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">const <a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a> *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a41ae26ab4e202eef9201f6b199fb16ce">GetString</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae38d143eb3355edb239eea24b85fe6d3">GetTexParameterfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad52992680f6f9891c5fa625fb20c4b97">GetTexParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad70b54be2f66c6a084d1719806841469">GetUniformfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#addb8ed81d591e6812368ff9b35f9897e">GetUniformiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a32f5dcbbf803c5c84a10acf2d1292f60">GetUniformLocation</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a05684300391ac0ac5a5d8e244e065150">GetVertexAttribfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a955d0da55d8b341fb553bf8e9a62f4f4">GetVertexAttribiv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a31686faea9c09a3aea5395a160b5a703">GetVertexAttribPointerv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, void **pointer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa6bc36ca24ada1915de80fe4da2454b9">Hint</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6ada79af938927844c836a18e701ff68">IsBuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1da584120a622099284702013a8916c3">IsEnabled</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aaf2d72ba9b2620c299c433ae23f55d03">IsFramebuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3467488660ac900b116f3e0430a55946">IsProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad1ed2205b620a89b382c97c1988e7efc">IsRenderbuffer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#acd293db143a3f55832008d926d52ed75">IsShader</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0a2e1ec8346a5aa68c4728416b8d412f">IsTexture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a71db733e5030a3f755b7490693825257">LineWidth</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> width)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8665f851be1fb55d6e58db6b50ea9731">LinkProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0b6e2b1cf710df29a3df677a800e67b5">PixelStorei</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a638969596be6467368acc0f171cfdbf0">PolygonOffset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> factor, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> units)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aba8b69f84f5ef6403459ce106ebf92fe">ReadPixels</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a379ef1dfd1a84c76f66a4b8df94f5f06">ReleaseShaderCompiler</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6d4b61fc76d9d5db9ad630535ac94c97">RenderbufferStorage</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2d7905223eceebd3c5488573770a717d">SampleCoverage</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> value, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> invert)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a7acd0d4c34033c6d0fea836858cfbdd1">Scissor</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad64ba9822216952fdd6c6dea88df7ae1">ShaderBinary</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> binaryformat, const void *binary, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> length)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2a8e95c84c8bb62d52643b85ef00c07c">ShaderSource</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const char **str, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *length)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a07be2d94c3f3d20673ed2cb58aeba883">StencilFunc</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad7d3752f3b6bd299352d65f5a85aaf23">StencilFuncSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2321d2d6bd8ddff826bf571f7b69f848">StencilMask</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af4c9fa7c5ba5401a12528767e81cf1b0">StencilMaskSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a229f52383718c9df806be747b7b9dfe5">StencilOp</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2546dd17374320c8c0a3b001823673cd">StencilOpSeparate</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a81800d67bb4783190701badebfb726b9">TexImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8caf21191fa018dcf792d90647592b4b">TexParameterf</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a961a92cb2ed539ccdb9df6b940ca218b">TexParameterfv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6fac5f5df4620517abe99d2964ff28f2">TexParameteri</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a40f888933a76359c753a34cbb39da6b3">TexParameteriv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3f58d4f8da2ed2bf2e6347946080d2dc">TexSubImage2D</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a461a2f7876fd95fb2418c2bae7d3815f">Uniform1f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa32eadc3b6bf9c2ea89e7e12f10ab831">Uniform1fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1be5e32660d22531f188461129343eb3">Uniform1i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9f9e9a356348bf33d5406fd827d7c107">Uniform1iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a80cc970f928b2d72cac0dc7bf9a2ec4e">Uniform2f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a366580f180b8aaaae6b3f261efe0e109">Uniform2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abbfa04153e7a7ebf4610b23da838383d">Uniform2i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9f617af90239ef73c6ba5b2996c6fc57">Uniform2iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abd9b4bfb71307b7eb75bc525f8052c21">Uniform3f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8a9d660e9b6ed8e3a2c78872189a7626">Uniform3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3ab65dcc2c744a813fb4f00b00bc5abd">Uniform3i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac5bd453dc0d882c9a2fc3ff76f250726">Uniform3iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa0dc41f4d8434cdf18b16b978b02d7c3">Uniform4f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa6c6ba4ecbe190f6e84abb6ac2693928">Uniform4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a62f30c23c26244b2cf8aeb158bc868b0">Uniform4i</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0b239767f38e96db9c0b347d516eedce">Uniform4iv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a80efc259d84bdd9fe7ee7b2abe4e4086">UniformMatrix2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9e654ad303db1cb29ec0f68528b7f4ab">UniformMatrix3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a60dfc3e5ec260f4e662e40fe175d3906">UniformMatrix4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a72c17b1c01259c5ca6d5a675517d9d8c">UseProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac5d00690e1bd444c9cbebf3b5e80697b">ValidateProgram</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a995aba270d8989e4bb5a8aca9ac832fd">VertexAttrib1f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2c5656b5d2a849d666659233ad5e50e7">VertexAttrib1fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aad7780c9906231eb782a9af04680b711">VertexAttrib2f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4dd28d292856ba6a85857500b3566272">VertexAttrib2fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3c79e51783ccd1eac9a9bc943e23e39b">VertexAttrib3f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a666cba685fde7e2eaaddd497d4f8350e">VertexAttrib3fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac03329d95351047aecb0ab26d44ab6d2">VertexAttrib4f</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3801ec5813ab3f0a75f4f7bab4b0cd9a">VertexAttrib4fv</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2542a9f1ebae00c87c7c67b75138a33d">VertexAttribPointer</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> normalized, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> stride, const void *ptr)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac73441abfd1df4bf27725aaa38b51d8f">Viewport</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="aa34e464b586eaa61f67ef887a7bc2655"></a><!-- doxytag: member="PPB_OpenGLES2::ActiveTexture" ref="aa34e464b586eaa61f67ef887a7bc2655" args=")(PP_Resource context, GLenum texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa34e464b586eaa61f67ef887a7bc2655">PPB_OpenGLES2::ActiveTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af5f501df60bb679c8ad67e342af8fdeb"></a><!-- doxytag: member="PPB_OpenGLES2::AttachShader" ref="af5f501df60bb679c8ad67e342af8fdeb" args=")(PP_Resource context, GLuint program, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af5f501df60bb679c8ad67e342af8fdeb">PPB_OpenGLES2::AttachShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae287fae397e261b479a8228f24b69541"></a><!-- doxytag: member="PPB_OpenGLES2::BindAttribLocation" ref="ae287fae397e261b479a8228f24b69541" args=")(PP_Resource context, GLuint program, GLuint index, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae287fae397e261b479a8228f24b69541">PPB_OpenGLES2::BindAttribLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae4779ea65ccdc556dfb47783e61fa3e9"></a><!-- doxytag: member="PPB_OpenGLES2::BindBuffer" ref="ae4779ea65ccdc556dfb47783e61fa3e9" args=")(PP_Resource context, GLenum target, GLuint buffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae4779ea65ccdc556dfb47783e61fa3e9">PPB_OpenGLES2::BindBuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a70b68978c44dc2b1184cdb5ce982eac6"></a><!-- doxytag: member="PPB_OpenGLES2::BindFramebuffer" ref="a70b68978c44dc2b1184cdb5ce982eac6" args=")(PP_Resource context, GLenum target, GLuint framebuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a70b68978c44dc2b1184cdb5ce982eac6">PPB_OpenGLES2::BindFramebuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1c2e36a931c81a274e28079e3a910390"></a><!-- doxytag: member="PPB_OpenGLES2::BindRenderbuffer" ref="a1c2e36a931c81a274e28079e3a910390" args=")(PP_Resource context, GLenum target, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1c2e36a931c81a274e28079e3a910390">PPB_OpenGLES2::BindRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abc8a5b7c5352bb63143480b7ba41a5f1"></a><!-- doxytag: member="PPB_OpenGLES2::BindTexture" ref="abc8a5b7c5352bb63143480b7ba41a5f1" args=")(PP_Resource context, GLenum target, GLuint texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abc8a5b7c5352bb63143480b7ba41a5f1">PPB_OpenGLES2::BindTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adbd2c2c1ffd4520992a210d0fe4f1643"></a><!-- doxytag: member="PPB_OpenGLES2::BlendColor" ref="adbd2c2c1ffd4520992a210d0fe4f1643" args=")(PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adbd2c2c1ffd4520992a210d0fe4f1643">PPB_OpenGLES2::BlendColor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a271602e4972c250bd48239e813fc9e89"></a><!-- doxytag: member="PPB_OpenGLES2::BlendEquation" ref="a271602e4972c250bd48239e813fc9e89" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a271602e4972c250bd48239e813fc9e89">PPB_OpenGLES2::BlendEquation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="accada00419e1c2d24f98374c202f5bdc"></a><!-- doxytag: member="PPB_OpenGLES2::BlendEquationSeparate" ref="accada00419e1c2d24f98374c202f5bdc" args=")(PP_Resource context, GLenum modeRGB, GLenum modeAlpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#accada00419e1c2d24f98374c202f5bdc">PPB_OpenGLES2::BlendEquationSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> modeAlpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a01d69f0dc88ae07cc26cf6af13ab8dd0"></a><!-- doxytag: member="PPB_OpenGLES2::BlendFunc" ref="a01d69f0dc88ae07cc26cf6af13ab8dd0" args=")(PP_Resource context, GLenum sfactor, GLenum dfactor)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a01d69f0dc88ae07cc26cf6af13ab8dd0">PPB_OpenGLES2::BlendFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> sfactor, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dfactor)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acc46008a5377d37da1bbb922d12fd302"></a><!-- doxytag: member="PPB_OpenGLES2::BlendFuncSeparate" ref="acc46008a5377d37da1bbb922d12fd302" args=")(PP_Resource context, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#acc46008a5377d37da1bbb922d12fd302">PPB_OpenGLES2::BlendFuncSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstRGB, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> srcAlpha, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> dstAlpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab8a24c0fc55782ea4a77b8a8f4c18ee9"></a><!-- doxytag: member="PPB_OpenGLES2::BufferData" ref="ab8a24c0fc55782ea4a77b8a8f4c18ee9" args=")(PP_Resource context, GLenum target, GLsizeiptr size, const void *data, GLenum usage)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab8a24c0fc55782ea4a77b8a8f4c18ee9">PPB_OpenGLES2::BufferData</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> usage)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4dc9e1fbe6f424c367cff48874288d95"></a><!-- doxytag: member="PPB_OpenGLES2::BufferSubData" ref="a4dc9e1fbe6f424c367cff48874288d95" args=")(PP_Resource context, GLenum target, GLintptr offset, GLsizeiptr size, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4dc9e1fbe6f424c367cff48874288d95">PPB_OpenGLES2::BufferSubData</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a68c09a107daa525accbd810af5d8b7e7"></a><!-- doxytag: member="PPB_OpenGLES2::CheckFramebufferStatus" ref="a68c09a107daa525accbd810af5d8b7e7" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a68c09a107daa525accbd810af5d8b7e7">PPB_OpenGLES2::CheckFramebufferStatus</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aab191f4226b69a785ac321019ac458d4"></a><!-- doxytag: member="PPB_OpenGLES2::Clear" ref="aab191f4226b69a785ac321019ac458d4" args=")(PP_Resource context, GLbitfield mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aab191f4226b69a785ac321019ac458d4">PPB_OpenGLES2::Clear</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a59b2ed69ce80d1d2833914faa1518766"></a><!-- doxytag: member="PPB_OpenGLES2::ClearColor" ref="a59b2ed69ce80d1d2833914faa1518766" args=")(PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a59b2ed69ce80d1d2833914faa1518766">PPB_OpenGLES2::ClearColor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> red, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> green, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> blue, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad5c13e5d77633c26f686b5af5cd7727d"></a><!-- doxytag: member="PPB_OpenGLES2::ClearDepthf" ref="ad5c13e5d77633c26f686b5af5cd7727d" args=")(PP_Resource context, GLclampf depth)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad5c13e5d77633c26f686b5af5cd7727d">PPB_OpenGLES2::ClearDepthf</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> depth)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac4a4c5c73753fbe0093405b3b0fd9c87"></a><!-- doxytag: member="PPB_OpenGLES2::ClearStencil" ref="ac4a4c5c73753fbe0093405b3b0fd9c87" args=")(PP_Resource context, GLint s)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac4a4c5c73753fbe0093405b3b0fd9c87">PPB_OpenGLES2::ClearStencil</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> s)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a43ba4bbe1438a6040d6df6a5fd111ea9"></a><!-- doxytag: member="PPB_OpenGLES2::ColorMask" ref="a43ba4bbe1438a6040d6df6a5fd111ea9" args=")(PP_Resource context, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a43ba4bbe1438a6040d6df6a5fd111ea9">PPB_OpenGLES2::ColorMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> red, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> green, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> blue, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> alpha)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab22a837b8f304dde44a8337bef5dba25"></a><!-- doxytag: member="PPB_OpenGLES2::CompileShader" ref="ab22a837b8f304dde44a8337bef5dba25" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab22a837b8f304dde44a8337bef5dba25">PPB_OpenGLES2::CompileShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0fc10275f13764beb343cad905100fa7"></a><!-- doxytag: member="PPB_OpenGLES2::CompressedTexImage2D" ref="a0fc10275f13764beb343cad905100fa7" args=")(PP_Resource context, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0fc10275f13764beb343cad905100fa7">PPB_OpenGLES2::CompressedTexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a488f48b4eaec02b7d0f9539d34355477"></a><!-- doxytag: member="PPB_OpenGLES2::CompressedTexSubImage2D" ref="a488f48b4eaec02b7d0f9539d34355477" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a488f48b4eaec02b7d0f9539d34355477">PPB_OpenGLES2::CompressedTexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> imageSize, const void *data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af74b42925bde9e13a802e6ad2c0af02a"></a><!-- doxytag: member="PPB_OpenGLES2::CopyTexImage2D" ref="af74b42925bde9e13a802e6ad2c0af02a" args=")(PP_Resource context, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af74b42925bde9e13a802e6ad2c0af02a">PPB_OpenGLES2::CopyTexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad00d27aeabf8477aeed12646d1180207"></a><!-- doxytag: member="PPB_OpenGLES2::CopyTexSubImage2D" ref="ad00d27aeabf8477aeed12646d1180207" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad00d27aeabf8477aeed12646d1180207">PPB_OpenGLES2::CopyTexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac2bbfa75734a508ea13eb748cc7715af"></a><!-- doxytag: member="PPB_OpenGLES2::CreateProgram" ref="ac2bbfa75734a508ea13eb748cc7715af" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac2bbfa75734a508ea13eb748cc7715af">PPB_OpenGLES2::CreateProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2371aecb935d34d94af08fd197f23291"></a><!-- doxytag: member="PPB_OpenGLES2::CreateShader" ref="a2371aecb935d34d94af08fd197f23291" args=")(PP_Resource context, GLenum type)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2371aecb935d34d94af08fd197f23291">PPB_OpenGLES2::CreateShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af07caadc9a21fb31213adf41d687ff0b"></a><!-- doxytag: member="PPB_OpenGLES2::CullFace" ref="af07caadc9a21fb31213adf41d687ff0b" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af07caadc9a21fb31213adf41d687ff0b">PPB_OpenGLES2::CullFace</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab5ca12ee3e483450fffac2cf856f7ab5"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteBuffers" ref="ab5ca12ee3e483450fffac2cf856f7ab5" args=")(PP_Resource context, GLsizei n, const GLuint *buffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab5ca12ee3e483450fffac2cf856f7ab5">PPB_OpenGLES2::DeleteBuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a79fa4d36bf1b5ba42402b1362220e631"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteFramebuffers" ref="a79fa4d36bf1b5ba42402b1362220e631" args=")(PP_Resource context, GLsizei n, const GLuint *framebuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a79fa4d36bf1b5ba42402b1362220e631">PPB_OpenGLES2::DeleteFramebuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a16bf7f6e2ded12e19f34f6751969ad82"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteProgram" ref="a16bf7f6e2ded12e19f34f6751969ad82" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a16bf7f6e2ded12e19f34f6751969ad82">PPB_OpenGLES2::DeleteProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a17fb01cbcc24025c5ae10ae776171288"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteRenderbuffers" ref="a17fb01cbcc24025c5ae10ae776171288" args=")(PP_Resource context, GLsizei n, const GLuint *renderbuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a17fb01cbcc24025c5ae10ae776171288">PPB_OpenGLES2::DeleteRenderbuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a5fcb36e0753e624fe181cc23639a71b2"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteShader" ref="a5fcb36e0753e624fe181cc23639a71b2" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a5fcb36e0753e624fe181cc23639a71b2">PPB_OpenGLES2::DeleteShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3bf6533616420836fa291e8466aae8ba"></a><!-- doxytag: member="PPB_OpenGLES2::DeleteTextures" ref="a3bf6533616420836fa291e8466aae8ba" args=")(PP_Resource context, GLsizei n, const GLuint *textures)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3bf6533616420836fa291e8466aae8ba">PPB_OpenGLES2::DeleteTextures</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9b86654205f1d45939e9f7a007665a50"></a><!-- doxytag: member="PPB_OpenGLES2::DepthFunc" ref="a9b86654205f1d45939e9f7a007665a50" args=")(PP_Resource context, GLenum func)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9b86654205f1d45939e9f7a007665a50">PPB_OpenGLES2::DepthFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac931d374fc3cd241539c0af6b229733f"></a><!-- doxytag: member="PPB_OpenGLES2::DepthMask" ref="ac931d374fc3cd241539c0af6b229733f" args=")(PP_Resource context, GLboolean flag)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac931d374fc3cd241539c0af6b229733f">PPB_OpenGLES2::DepthMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> flag)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6dc83777e28dd2cf3a3fbadece1637ec"></a><!-- doxytag: member="PPB_OpenGLES2::DepthRangef" ref="a6dc83777e28dd2cf3a3fbadece1637ec" args=")(PP_Resource context, GLclampf zNear, GLclampf zFar)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6dc83777e28dd2cf3a3fbadece1637ec">PPB_OpenGLES2::DepthRangef</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zNear, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> zFar)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adb09849032fbdee9b4018362d8046d8a"></a><!-- doxytag: member="PPB_OpenGLES2::DetachShader" ref="adb09849032fbdee9b4018362d8046d8a" args=")(PP_Resource context, GLuint program, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adb09849032fbdee9b4018362d8046d8a">PPB_OpenGLES2::DetachShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="adf10ac1a5115bb7cfecd820fee414543"></a><!-- doxytag: member="PPB_OpenGLES2::Disable" ref="adf10ac1a5115bb7cfecd820fee414543" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#adf10ac1a5115bb7cfecd820fee414543">PPB_OpenGLES2::Disable</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a023ce8e59c8c83b37f2425d4642abafa"></a><!-- doxytag: member="PPB_OpenGLES2::DisableVertexAttribArray" ref="a023ce8e59c8c83b37f2425d4642abafa" args=")(PP_Resource context, GLuint index)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a023ce8e59c8c83b37f2425d4642abafa">PPB_OpenGLES2::DisableVertexAttribArray</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a00f3701866e04c87e390deeda6a3dc4e"></a><!-- doxytag: member="PPB_OpenGLES2::DrawArrays" ref="a00f3701866e04c87e390deeda6a3dc4e" args=")(PP_Resource context, GLenum mode, GLint first, GLsizei count)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a00f3701866e04c87e390deeda6a3dc4e">PPB_OpenGLES2::DrawArrays</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4420853d86445b1c98ed6a51c2ee3ca4"></a><!-- doxytag: member="PPB_OpenGLES2::DrawElements" ref="a4420853d86445b1c98ed6a51c2ee3ca4" args=")(PP_Resource context, GLenum mode, GLsizei count, GLenum type, const void *indices)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4420853d86445b1c98ed6a51c2ee3ca4">PPB_OpenGLES2::DrawElements</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9faf8c7a761912a3e93f2f531a1a14c0"></a><!-- doxytag: member="PPB_OpenGLES2::Enable" ref="a9faf8c7a761912a3e93f2f531a1a14c0" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9faf8c7a761912a3e93f2f531a1a14c0">PPB_OpenGLES2::Enable</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae91777d77008df1ddfa0d7310c9858fc"></a><!-- doxytag: member="PPB_OpenGLES2::EnableVertexAttribArray" ref="ae91777d77008df1ddfa0d7310c9858fc" args=")(PP_Resource context, GLuint index)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae91777d77008df1ddfa0d7310c9858fc">PPB_OpenGLES2::EnableVertexAttribArray</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad27973d7b18a026a1019b4c94c42f017"></a><!-- doxytag: member="PPB_OpenGLES2::Finish" ref="ad27973d7b18a026a1019b4c94c42f017" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad27973d7b18a026a1019b4c94c42f017">PPB_OpenGLES2::Finish</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a40ea416a21e56c24b4bac14983b19f16"></a><!-- doxytag: member="PPB_OpenGLES2::Flush" ref="a40ea416a21e56c24b4bac14983b19f16" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a40ea416a21e56c24b4bac14983b19f16">PPB_OpenGLES2::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab054ffa4f3e478a3026ab05a54f05a6a"></a><!-- doxytag: member="PPB_OpenGLES2::FramebufferRenderbuffer" ref="ab054ffa4f3e478a3026ab05a54f05a6a" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab054ffa4f3e478a3026ab05a54f05a6a">PPB_OpenGLES2::FramebufferRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> renderbuffertarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a37f4d4823ff074ae5833d3b847953eee"></a><!-- doxytag: member="PPB_OpenGLES2::FramebufferTexture2D" ref="a37f4d4823ff074ae5833d3b847953eee" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a37f4d4823ff074ae5833d3b847953eee">PPB_OpenGLES2::FramebufferTexture2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> textarget, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a503ed7ba907260fd6bac5d6133da2502"></a><!-- doxytag: member="PPB_OpenGLES2::FrontFace" ref="a503ed7ba907260fd6bac5d6133da2502" args=")(PP_Resource context, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a503ed7ba907260fd6bac5d6133da2502">PPB_OpenGLES2::FrontFace</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a22ea29492beb072b3e7f197c8243b895"></a><!-- doxytag: member="PPB_OpenGLES2::GenBuffers" ref="a22ea29492beb072b3e7f197c8243b895" args=")(PP_Resource context, GLsizei n, GLuint *buffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a22ea29492beb072b3e7f197c8243b895">PPB_OpenGLES2::GenBuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *buffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8fed425b72e4c2c5c038dc431c21c5b9"></a><!-- doxytag: member="PPB_OpenGLES2::GenerateMipmap" ref="a8fed425b72e4c2c5c038dc431c21c5b9" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8fed425b72e4c2c5c038dc431c21c5b9">PPB_OpenGLES2::GenerateMipmap</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad14fc6bfd2571ca47f690587810e45ed"></a><!-- doxytag: member="PPB_OpenGLES2::GenFramebuffers" ref="ad14fc6bfd2571ca47f690587810e45ed" args=")(PP_Resource context, GLsizei n, GLuint *framebuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad14fc6bfd2571ca47f690587810e45ed">PPB_OpenGLES2::GenFramebuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *framebuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a57a223eb049a5e37cd8e12258dcdf893"></a><!-- doxytag: member="PPB_OpenGLES2::GenRenderbuffers" ref="a57a223eb049a5e37cd8e12258dcdf893" args=")(PP_Resource context, GLsizei n, GLuint *renderbuffers)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a57a223eb049a5e37cd8e12258dcdf893">PPB_OpenGLES2::GenRenderbuffers</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *renderbuffers)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af41e0b0c6ff3c9e95739e6585734e1c0"></a><!-- doxytag: member="PPB_OpenGLES2::GenTextures" ref="af41e0b0c6ff3c9e95739e6585734e1c0" args=")(PP_Resource context, GLsizei n, GLuint *textures)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af41e0b0c6ff3c9e95739e6585734e1c0">PPB_OpenGLES2::GenTextures</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *textures)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a883e45e81157db95ff7155957a092800"></a><!-- doxytag: member="PPB_OpenGLES2::GetActiveAttrib" ref="a883e45e81157db95ff7155957a092800" args=")(PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a883e45e81157db95ff7155957a092800">PPB_OpenGLES2::GetActiveAttrib</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2a086b77b1a282c52e3c348f9c9a1080"></a><!-- doxytag: member="PPB_OpenGLES2::GetActiveUniform" ref="a2a086b77b1a282c52e3c348f9c9a1080" args=")(PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2a086b77b1a282c52e3c348f9c9a1080">PPB_OpenGLES2::GetActiveUniform</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> *type, char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aece846b6c38b17080b2593a5302536cf"></a><!-- doxytag: member="PPB_OpenGLES2::GetAttachedShaders" ref="aece846b6c38b17080b2593a5302536cf" args=")(PP_Resource context, GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aece846b6c38b17080b2593a5302536cf">PPB_OpenGLES2::GetAttachedShaders</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> maxcount, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *count, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aca2b12aa379dfc7069905c7d7acd1972"></a><!-- doxytag: member="PPB_OpenGLES2::GetAttribLocation" ref="aca2b12aa379dfc7069905c7d7acd1972" args=")(PP_Resource context, GLuint program, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aca2b12aa379dfc7069905c7d7acd1972">PPB_OpenGLES2::GetAttribLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a930a044665be6916f46ed51b5473fe6b"></a><!-- doxytag: member="PPB_OpenGLES2::GetBooleanv" ref="a930a044665be6916f46ed51b5473fe6b" args=")(PP_Resource context, GLenum pname, GLboolean *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a930a044665be6916f46ed51b5473fe6b">PPB_OpenGLES2::GetBooleanv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af4b62f5d61131d59c3a274b57ada67b5"></a><!-- doxytag: member="PPB_OpenGLES2::GetBufferParameteriv" ref="af4b62f5d61131d59c3a274b57ada67b5" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af4b62f5d61131d59c3a274b57ada67b5">PPB_OpenGLES2::GetBufferParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae25222a3a3a50368bf6ffa61fd527473"></a><!-- doxytag: member="PPB_OpenGLES2::GetError" ref="ae25222a3a3a50368bf6ffa61fd527473" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae25222a3a3a50368bf6ffa61fd527473">PPB_OpenGLES2::GetError</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab81d1639b6c0f0667ab344dcbc66217e"></a><!-- doxytag: member="PPB_OpenGLES2::GetFloatv" ref="ab81d1639b6c0f0667ab344dcbc66217e" args=")(PP_Resource context, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ab81d1639b6c0f0667ab344dcbc66217e">PPB_OpenGLES2::GetFloatv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac0f25a003e7077fa79954e9fe453b62c"></a><!-- doxytag: member="PPB_OpenGLES2::GetFramebufferAttachmentParameteriv" ref="ac0f25a003e7077fa79954e9fe453b62c" args=")(PP_Resource context, GLenum target, GLenum attachment, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac0f25a003e7077fa79954e9fe453b62c">PPB_OpenGLES2::GetFramebufferAttachmentParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> attachment, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a797e58efe3e7c0cfa12208bae75084f4"></a><!-- doxytag: member="PPB_OpenGLES2::GetIntegerv" ref="a797e58efe3e7c0cfa12208bae75084f4" args=")(PP_Resource context, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a797e58efe3e7c0cfa12208bae75084f4">PPB_OpenGLES2::GetIntegerv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0c45941c3c120035f0857709c65c6604"></a><!-- doxytag: member="PPB_OpenGLES2::GetProgramInfoLog" ref="a0c45941c3c120035f0857709c65c6604" args=")(PP_Resource context, GLuint program, GLsizei bufsize, GLsizei *length, char *infolog)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0c45941c3c120035f0857709c65c6604">PPB_OpenGLES2::GetProgramInfoLog</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8045b6b71041fcee85e92e40169fc361"></a><!-- doxytag: member="PPB_OpenGLES2::GetProgramiv" ref="a8045b6b71041fcee85e92e40169fc361" args=")(PP_Resource context, GLuint program, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8045b6b71041fcee85e92e40169fc361">PPB_OpenGLES2::GetProgramiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a42ffdc030fb99a76a47605e05489a182"></a><!-- doxytag: member="PPB_OpenGLES2::GetRenderbufferParameteriv" ref="a42ffdc030fb99a76a47605e05489a182" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a42ffdc030fb99a76a47605e05489a182">PPB_OpenGLES2::GetRenderbufferParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a24e99f31bc2602c3d2cd4d8022fa5888"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderInfoLog" ref="a24e99f31bc2602c3d2cd4d8022fa5888" args=")(PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a24e99f31bc2602c3d2cd4d8022fa5888">PPB_OpenGLES2::GetShaderInfoLog</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *infolog)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af9b7ea14515e35488883481699194764"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderiv" ref="af9b7ea14515e35488883481699194764" args=")(PP_Resource context, GLuint shader, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af9b7ea14515e35488883481699194764">PPB_OpenGLES2::GetShaderiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac44fd9e32e88c735ea4d01380d7c4df7"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderPrecisionFormat" ref="ac44fd9e32e88c735ea4d01380d7c4df7" args=")(PP_Resource context, GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac44fd9e32e88c735ea4d01380d7c4df7">PPB_OpenGLES2::GetShaderPrecisionFormat</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> shadertype, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> precisiontype, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *range, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *precision)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af696668edf764584e867b4fa43231358"></a><!-- doxytag: member="PPB_OpenGLES2::GetShaderSource" ref="af696668edf764584e867b4fa43231358" args=")(PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei *length, char *source)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af696668edf764584e867b4fa43231358">PPB_OpenGLES2::GetShaderSource</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> bufsize, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> *length, char *source)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a41ae26ab4e202eef9201f6b199fb16ce"></a><!-- doxytag: member="PPB_OpenGLES2::GetString" ref="a41ae26ab4e202eef9201f6b199fb16ce" args=")(PP_Resource context, GLenum name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">const <a class="el" href="ppb__opengles2_8h.html#a0595908be03a8cff881a23cdc9170e7c">GLubyte</a>*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a41ae26ab4e202eef9201f6b199fb16ce">PPB_OpenGLES2::GetString</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae38d143eb3355edb239eea24b85fe6d3"></a><!-- doxytag: member="PPB_OpenGLES2::GetTexParameterfv" ref="ae38d143eb3355edb239eea24b85fe6d3" args=")(PP_Resource context, GLenum target, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ae38d143eb3355edb239eea24b85fe6d3">PPB_OpenGLES2::GetTexParameterfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad52992680f6f9891c5fa625fb20c4b97"></a><!-- doxytag: member="PPB_OpenGLES2::GetTexParameteriv" ref="ad52992680f6f9891c5fa625fb20c4b97" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad52992680f6f9891c5fa625fb20c4b97">PPB_OpenGLES2::GetTexParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad70b54be2f66c6a084d1719806841469"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformfv" ref="ad70b54be2f66c6a084d1719806841469" args=")(PP_Resource context, GLuint program, GLint location, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad70b54be2f66c6a084d1719806841469">PPB_OpenGLES2::GetUniformfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="addb8ed81d591e6812368ff9b35f9897e"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformiv" ref="addb8ed81d591e6812368ff9b35f9897e" args=")(PP_Resource context, GLuint program, GLint location, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#addb8ed81d591e6812368ff9b35f9897e">PPB_OpenGLES2::GetUniformiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a32f5dcbbf803c5c84a10acf2d1292f60"></a><!-- doxytag: member="PPB_OpenGLES2::GetUniformLocation" ref="a32f5dcbbf803c5c84a10acf2d1292f60" args=")(PP_Resource context, GLuint program, const char *name)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a32f5dcbbf803c5c84a10acf2d1292f60">PPB_OpenGLES2::GetUniformLocation</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program, const char *name)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a05684300391ac0ac5a5d8e244e065150"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribfv" ref="a05684300391ac0ac5a5d8e244e065150" args=")(PP_Resource context, GLuint index, GLenum pname, GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a05684300391ac0ac5a5d8e244e065150">PPB_OpenGLES2::GetVertexAttribfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a955d0da55d8b341fb553bf8e9a62f4f4"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribiv" ref="a955d0da55d8b341fb553bf8e9a62f4f4" args=")(PP_Resource context, GLuint index, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a955d0da55d8b341fb553bf8e9a62f4f4">PPB_OpenGLES2::GetVertexAttribiv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a31686faea9c09a3aea5395a160b5a703"></a><!-- doxytag: member="PPB_OpenGLES2::GetVertexAttribPointerv" ref="a31686faea9c09a3aea5395a160b5a703" args=")(PP_Resource context, GLuint index, GLenum pname, void **pointer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a31686faea9c09a3aea5395a160b5a703">PPB_OpenGLES2::GetVertexAttribPointerv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, void **pointer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa6bc36ca24ada1915de80fe4da2454b9"></a><!-- doxytag: member="PPB_OpenGLES2::Hint" ref="aa6bc36ca24ada1915de80fe4da2454b9" args=")(PP_Resource context, GLenum target, GLenum mode)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa6bc36ca24ada1915de80fe4da2454b9">PPB_OpenGLES2::Hint</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6ada79af938927844c836a18e701ff68"></a><!-- doxytag: member="PPB_OpenGLES2::IsBuffer" ref="a6ada79af938927844c836a18e701ff68" args=")(PP_Resource context, GLuint buffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6ada79af938927844c836a18e701ff68">PPB_OpenGLES2::IsBuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> buffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1da584120a622099284702013a8916c3"></a><!-- doxytag: member="PPB_OpenGLES2::IsEnabled" ref="a1da584120a622099284702013a8916c3" args=")(PP_Resource context, GLenum cap)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1da584120a622099284702013a8916c3">PPB_OpenGLES2::IsEnabled</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> cap)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aaf2d72ba9b2620c299c433ae23f55d03"></a><!-- doxytag: member="PPB_OpenGLES2::IsFramebuffer" ref="aaf2d72ba9b2620c299c433ae23f55d03" args=")(PP_Resource context, GLuint framebuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aaf2d72ba9b2620c299c433ae23f55d03">PPB_OpenGLES2::IsFramebuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> framebuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3467488660ac900b116f3e0430a55946"></a><!-- doxytag: member="PPB_OpenGLES2::IsProgram" ref="a3467488660ac900b116f3e0430a55946" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3467488660ac900b116f3e0430a55946">PPB_OpenGLES2::IsProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad1ed2205b620a89b382c97c1988e7efc"></a><!-- doxytag: member="PPB_OpenGLES2::IsRenderbuffer" ref="ad1ed2205b620a89b382c97c1988e7efc" args=")(PP_Resource context, GLuint renderbuffer)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad1ed2205b620a89b382c97c1988e7efc">PPB_OpenGLES2::IsRenderbuffer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> renderbuffer)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="acd293db143a3f55832008d926d52ed75"></a><!-- doxytag: member="PPB_OpenGLES2::IsShader" ref="acd293db143a3f55832008d926d52ed75" args=")(PP_Resource context, GLuint shader)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#acd293db143a3f55832008d926d52ed75">PPB_OpenGLES2::IsShader</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0a2e1ec8346a5aa68c4728416b8d412f"></a><!-- doxytag: member="PPB_OpenGLES2::IsTexture" ref="a0a2e1ec8346a5aa68c4728416b8d412f" args=")(PP_Resource context, GLuint texture)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0a2e1ec8346a5aa68c4728416b8d412f">PPB_OpenGLES2::IsTexture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> texture)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a71db733e5030a3f755b7490693825257"></a><!-- doxytag: member="PPB_OpenGLES2::LineWidth" ref="a71db733e5030a3f755b7490693825257" args=")(PP_Resource context, GLfloat width)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a71db733e5030a3f755b7490693825257">PPB_OpenGLES2::LineWidth</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> width)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8665f851be1fb55d6e58db6b50ea9731"></a><!-- doxytag: member="PPB_OpenGLES2::LinkProgram" ref="a8665f851be1fb55d6e58db6b50ea9731" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8665f851be1fb55d6e58db6b50ea9731">PPB_OpenGLES2::LinkProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0b6e2b1cf710df29a3df677a800e67b5"></a><!-- doxytag: member="PPB_OpenGLES2::PixelStorei" ref="a0b6e2b1cf710df29a3df677a800e67b5" args=")(PP_Resource context, GLenum pname, GLint param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0b6e2b1cf710df29a3df677a800e67b5">PPB_OpenGLES2::PixelStorei</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a638969596be6467368acc0f171cfdbf0"></a><!-- doxytag: member="PPB_OpenGLES2::PolygonOffset" ref="a638969596be6467368acc0f171cfdbf0" args=")(PP_Resource context, GLfloat factor, GLfloat units)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a638969596be6467368acc0f171cfdbf0">PPB_OpenGLES2::PolygonOffset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> factor, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> units)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aba8b69f84f5ef6403459ce106ebf92fe"></a><!-- doxytag: member="PPB_OpenGLES2::ReadPixels" ref="aba8b69f84f5ef6403459ce106ebf92fe" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aba8b69f84f5ef6403459ce106ebf92fe">PPB_OpenGLES2::ReadPixels</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a379ef1dfd1a84c76f66a4b8df94f5f06"></a><!-- doxytag: member="PPB_OpenGLES2::ReleaseShaderCompiler" ref="a379ef1dfd1a84c76f66a4b8df94f5f06" args=")(PP_Resource context)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a379ef1dfd1a84c76f66a4b8df94f5f06">PPB_OpenGLES2::ReleaseShaderCompiler</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6d4b61fc76d9d5db9ad630535ac94c97"></a><!-- doxytag: member="PPB_OpenGLES2::RenderbufferStorage" ref="a6d4b61fc76d9d5db9ad630535ac94c97" args=")(PP_Resource context, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6d4b61fc76d9d5db9ad630535ac94c97">PPB_OpenGLES2::RenderbufferStorage</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2d7905223eceebd3c5488573770a717d"></a><!-- doxytag: member="PPB_OpenGLES2::SampleCoverage" ref="a2d7905223eceebd3c5488573770a717d" args=")(PP_Resource context, GLclampf value, GLboolean invert)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2d7905223eceebd3c5488573770a717d">PPB_OpenGLES2::SampleCoverage</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aded4e0631b68d219180490a73d8424c0">GLclampf</a> value, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> invert)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7acd0d4c34033c6d0fea836858cfbdd1"></a><!-- doxytag: member="PPB_OpenGLES2::Scissor" ref="a7acd0d4c34033c6d0fea836858cfbdd1" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a7acd0d4c34033c6d0fea836858cfbdd1">PPB_OpenGLES2::Scissor</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad64ba9822216952fdd6c6dea88df7ae1"></a><!-- doxytag: member="PPB_OpenGLES2::ShaderBinary" ref="ad64ba9822216952fdd6c6dea88df7ae1" args=")(PP_Resource context, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad64ba9822216952fdd6c6dea88df7ae1">PPB_OpenGLES2::ShaderBinary</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *shaders, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> binaryformat, const void *binary, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> length)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2a8e95c84c8bb62d52643b85ef00c07c"></a><!-- doxytag: member="PPB_OpenGLES2::ShaderSource" ref="a2a8e95c84c8bb62d52643b85ef00c07c" args=")(PP_Resource context, GLuint shader, GLsizei count, const char **str, const GLint *length)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2a8e95c84c8bb62d52643b85ef00c07c">PPB_OpenGLES2::ShaderSource</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> shader, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const char **str, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *length)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a07be2d94c3f3d20673ed2cb58aeba883"></a><!-- doxytag: member="PPB_OpenGLES2::StencilFunc" ref="a07be2d94c3f3d20673ed2cb58aeba883" args=")(PP_Resource context, GLenum func, GLint ref, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a07be2d94c3f3d20673ed2cb58aeba883">PPB_OpenGLES2::StencilFunc</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad7d3752f3b6bd299352d65f5a85aaf23"></a><!-- doxytag: member="PPB_OpenGLES2::StencilFuncSeparate" ref="ad7d3752f3b6bd299352d65f5a85aaf23" args=")(PP_Resource context, GLenum face, GLenum func, GLint ref, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ad7d3752f3b6bd299352d65f5a85aaf23">PPB_OpenGLES2::StencilFuncSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> func, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> ref, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2321d2d6bd8ddff826bf571f7b69f848"></a><!-- doxytag: member="PPB_OpenGLES2::StencilMask" ref="a2321d2d6bd8ddff826bf571f7b69f848" args=")(PP_Resource context, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2321d2d6bd8ddff826bf571f7b69f848">PPB_OpenGLES2::StencilMask</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af4c9fa7c5ba5401a12528767e81cf1b0"></a><!-- doxytag: member="PPB_OpenGLES2::StencilMaskSeparate" ref="af4c9fa7c5ba5401a12528767e81cf1b0" args=")(PP_Resource context, GLenum face, GLuint mask)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#af4c9fa7c5ba5401a12528767e81cf1b0">PPB_OpenGLES2::StencilMaskSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> mask)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a229f52383718c9df806be747b7b9dfe5"></a><!-- doxytag: member="PPB_OpenGLES2::StencilOp" ref="a229f52383718c9df806be747b7b9dfe5" args=")(PP_Resource context, GLenum fail, GLenum zfail, GLenum zpass)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a229f52383718c9df806be747b7b9dfe5">PPB_OpenGLES2::StencilOp</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2546dd17374320c8c0a3b001823673cd"></a><!-- doxytag: member="PPB_OpenGLES2::StencilOpSeparate" ref="a2546dd17374320c8c0a3b001823673cd" args=")(PP_Resource context, GLenum face, GLenum fail, GLenum zfail, GLenum zpass)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2546dd17374320c8c0a3b001823673cd">PPB_OpenGLES2::StencilOpSeparate</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> face, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> fail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zfail, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> zpass)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a81800d67bb4783190701badebfb726b9"></a><!-- doxytag: member="PPB_OpenGLES2::TexImage2D" ref="a81800d67bb4783190701badebfb726b9" args=")(PP_Resource context, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a81800d67bb4783190701badebfb726b9">PPB_OpenGLES2::TexImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> border, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8caf21191fa018dcf792d90647592b4b"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameterf" ref="a8caf21191fa018dcf792d90647592b4b" args=")(PP_Resource context, GLenum target, GLenum pname, GLfloat param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8caf21191fa018dcf792d90647592b4b">PPB_OpenGLES2::TexParameterf</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a961a92cb2ed539ccdb9df6b940ca218b"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameterfv" ref="a961a92cb2ed539ccdb9df6b940ca218b" args=")(PP_Resource context, GLenum target, GLenum pname, const GLfloat *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a961a92cb2ed539ccdb9df6b940ca218b">PPB_OpenGLES2::TexParameterfv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a6fac5f5df4620517abe99d2964ff28f2"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameteri" ref="a6fac5f5df4620517abe99d2964ff28f2" args=")(PP_Resource context, GLenum target, GLenum pname, GLint param)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a6fac5f5df4620517abe99d2964ff28f2">PPB_OpenGLES2::TexParameteri</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> param)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a40f888933a76359c753a34cbb39da6b3"></a><!-- doxytag: member="PPB_OpenGLES2::TexParameteriv" ref="a40f888933a76359c753a34cbb39da6b3" args=")(PP_Resource context, GLenum target, GLenum pname, const GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a40f888933a76359c753a34cbb39da6b3">PPB_OpenGLES2::TexParameteriv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3f58d4f8da2ed2bf2e6347946080d2dc"></a><!-- doxytag: member="PPB_OpenGLES2::TexSubImage2D" ref="a3f58d4f8da2ed2bf2e6347946080d2dc" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3f58d4f8da2ed2bf2e6347946080d2dc">PPB_OpenGLES2::TexSubImage2D</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *pixels)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a461a2f7876fd95fb2418c2bae7d3815f"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1f" ref="a461a2f7876fd95fb2418c2bae7d3815f" args=")(PP_Resource context, GLint location, GLfloat x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a461a2f7876fd95fb2418c2bae7d3815f">PPB_OpenGLES2::Uniform1f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa32eadc3b6bf9c2ea89e7e12f10ab831"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1fv" ref="aa32eadc3b6bf9c2ea89e7e12f10ab831" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa32eadc3b6bf9c2ea89e7e12f10ab831">PPB_OpenGLES2::Uniform1fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a1be5e32660d22531f188461129343eb3"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1i" ref="a1be5e32660d22531f188461129343eb3" args=")(PP_Resource context, GLint location, GLint x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a1be5e32660d22531f188461129343eb3">PPB_OpenGLES2::Uniform1i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9f9e9a356348bf33d5406fd827d7c107"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform1iv" ref="a9f9e9a356348bf33d5406fd827d7c107" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9f9e9a356348bf33d5406fd827d7c107">PPB_OpenGLES2::Uniform1iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a80cc970f928b2d72cac0dc7bf9a2ec4e"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2f" ref="a80cc970f928b2d72cac0dc7bf9a2ec4e" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a80cc970f928b2d72cac0dc7bf9a2ec4e">PPB_OpenGLES2::Uniform2f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a366580f180b8aaaae6b3f261efe0e109"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2fv" ref="a366580f180b8aaaae6b3f261efe0e109" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a366580f180b8aaaae6b3f261efe0e109">PPB_OpenGLES2::Uniform2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abbfa04153e7a7ebf4610b23da838383d"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2i" ref="abbfa04153e7a7ebf4610b23da838383d" args=")(PP_Resource context, GLint location, GLint x, GLint y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abbfa04153e7a7ebf4610b23da838383d">PPB_OpenGLES2::Uniform2i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9f617af90239ef73c6ba5b2996c6fc57"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform2iv" ref="a9f617af90239ef73c6ba5b2996c6fc57" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9f617af90239ef73c6ba5b2996c6fc57">PPB_OpenGLES2::Uniform2iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="abd9b4bfb71307b7eb75bc525f8052c21"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3f" ref="abd9b4bfb71307b7eb75bc525f8052c21" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#abd9b4bfb71307b7eb75bc525f8052c21">PPB_OpenGLES2::Uniform3f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8a9d660e9b6ed8e3a2c78872189a7626"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3fv" ref="a8a9d660e9b6ed8e3a2c78872189a7626" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a8a9d660e9b6ed8e3a2c78872189a7626">PPB_OpenGLES2::Uniform3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3ab65dcc2c744a813fb4f00b00bc5abd"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3i" ref="a3ab65dcc2c744a813fb4f00b00bc5abd" args=")(PP_Resource context, GLint location, GLint x, GLint y, GLint z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3ab65dcc2c744a813fb4f00b00bc5abd">PPB_OpenGLES2::Uniform3i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac5bd453dc0d882c9a2fc3ff76f250726"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform3iv" ref="ac5bd453dc0d882c9a2fc3ff76f250726" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac5bd453dc0d882c9a2fc3ff76f250726">PPB_OpenGLES2::Uniform3iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa0dc41f4d8434cdf18b16b978b02d7c3"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4f" ref="aa0dc41f4d8434cdf18b16b978b02d7c3" args=")(PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa0dc41f4d8434cdf18b16b978b02d7c3">PPB_OpenGLES2::Uniform4f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa6c6ba4ecbe190f6e84abb6ac2693928"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4fv" ref="aa6c6ba4ecbe190f6e84abb6ac2693928" args=")(PP_Resource context, GLint location, GLsizei count, const GLfloat *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aa6c6ba4ecbe190f6e84abb6ac2693928">PPB_OpenGLES2::Uniform4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a62f30c23c26244b2cf8aeb158bc868b0"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4i" ref="a62f30c23c26244b2cf8aeb158bc868b0" args=")(PP_Resource context, GLint location, GLint x, GLint y, GLint z, GLint w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a62f30c23c26244b2cf8aeb158bc868b0">PPB_OpenGLES2::Uniform4i</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> z, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a0b239767f38e96db9c0b347d516eedce"></a><!-- doxytag: member="PPB_OpenGLES2::Uniform4iv" ref="a0b239767f38e96db9c0b347d516eedce" args=")(PP_Resource context, GLint location, GLsizei count, const GLint *v)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a0b239767f38e96db9c0b347d516eedce">PPB_OpenGLES2::Uniform4iv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, const <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *v)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a80efc259d84bdd9fe7ee7b2abe4e4086"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix2fv" ref="a80efc259d84bdd9fe7ee7b2abe4e4086" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a80efc259d84bdd9fe7ee7b2abe4e4086">PPB_OpenGLES2::UniformMatrix2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9e654ad303db1cb29ec0f68528b7f4ab"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix3fv" ref="a9e654ad303db1cb29ec0f68528b7f4ab" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a9e654ad303db1cb29ec0f68528b7f4ab">PPB_OpenGLES2::UniformMatrix3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a60dfc3e5ec260f4e662e40fe175d3906"></a><!-- doxytag: member="PPB_OpenGLES2::UniformMatrix4fv" ref="a60dfc3e5ec260f4e662e40fe175d3906" args=")(PP_Resource context, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a60dfc3e5ec260f4e662e40fe175d3906">PPB_OpenGLES2::UniformMatrix4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> location, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> transpose, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *value)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a72c17b1c01259c5ca6d5a675517d9d8c"></a><!-- doxytag: member="PPB_OpenGLES2::UseProgram" ref="a72c17b1c01259c5ca6d5a675517d9d8c" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a72c17b1c01259c5ca6d5a675517d9d8c">PPB_OpenGLES2::UseProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac5d00690e1bd444c9cbebf3b5e80697b"></a><!-- doxytag: member="PPB_OpenGLES2::ValidateProgram" ref="ac5d00690e1bd444c9cbebf3b5e80697b" args=")(PP_Resource context, GLuint program)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac5d00690e1bd444c9cbebf3b5e80697b">PPB_OpenGLES2::ValidateProgram</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> program)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a995aba270d8989e4bb5a8aca9ac832fd"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib1f" ref="a995aba270d8989e4bb5a8aca9ac832fd" args=")(PP_Resource context, GLuint indx, GLfloat x)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a995aba270d8989e4bb5a8aca9ac832fd">PPB_OpenGLES2::VertexAttrib1f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2c5656b5d2a849d666659233ad5e50e7"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib1fv" ref="a2c5656b5d2a849d666659233ad5e50e7" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2c5656b5d2a849d666659233ad5e50e7">PPB_OpenGLES2::VertexAttrib1fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aad7780c9906231eb782a9af04680b711"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib2f" ref="aad7780c9906231eb782a9af04680b711" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#aad7780c9906231eb782a9af04680b711">PPB_OpenGLES2::VertexAttrib2f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4dd28d292856ba6a85857500b3566272"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib2fv" ref="a4dd28d292856ba6a85857500b3566272" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a4dd28d292856ba6a85857500b3566272">PPB_OpenGLES2::VertexAttrib2fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3c79e51783ccd1eac9a9bc943e23e39b"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib3f" ref="a3c79e51783ccd1eac9a9bc943e23e39b" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3c79e51783ccd1eac9a9bc943e23e39b">PPB_OpenGLES2::VertexAttrib3f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a666cba685fde7e2eaaddd497d4f8350e"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib3fv" ref="a666cba685fde7e2eaaddd497d4f8350e" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a666cba685fde7e2eaaddd497d4f8350e">PPB_OpenGLES2::VertexAttrib3fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac03329d95351047aecb0ab26d44ab6d2"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib4f" ref="ac03329d95351047aecb0ab26d44ab6d2" args=")(PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac03329d95351047aecb0ab26d44ab6d2">PPB_OpenGLES2::VertexAttrib4f</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> x, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> y, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> z, <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> w)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3801ec5813ab3f0a75f4f7bab4b0cd9a"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttrib4fv" ref="a3801ec5813ab3f0a75f4f7bab4b0cd9a" args=")(PP_Resource context, GLuint indx, const GLfloat *values)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a3801ec5813ab3f0a75f4f7bab4b0cd9a">PPB_OpenGLES2::VertexAttrib4fv</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, const <a class="el" href="ppb__opengles2_8h.html#a31aeedaeef29442c9c015ab355c8f5ab">GLfloat</a> *values)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2542a9f1ebae00c87c7c67b75138a33d"></a><!-- doxytag: member="PPB_OpenGLES2::VertexAttribPointer" ref="a2542a9f1ebae00c87c7c67b75138a33d" args=")(PP_Resource context, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#a2542a9f1ebae00c87c7c67b75138a33d">PPB_OpenGLES2::VertexAttribPointer</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> indx, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a> normalized, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> stride, const void *ptr)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac73441abfd1df4bf27725aaa38b51d8f"></a><!-- doxytag: member="PPB_OpenGLES2::Viewport" ref="ac73441abfd1df4bf27725aaa38b51d8f" args=")(PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2__1__0.html#ac73441abfd1df4bf27725aaa38b51d8f">PPB_OpenGLES2::Viewport</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> x, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> y, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html new file mode 100644 index 0000000..c05bb4b2 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2ChromiumEnableFeature Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2ChromiumEnableFeature" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html#a7b682945881f47e3a02032ba542c8ce0">EnableFeatureCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const char *feature)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a7b682945881f47e3a02032ba542c8ce0"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumEnableFeature::EnableFeatureCHROMIUM" ref="a7b682945881f47e3a02032ba542c8ce0" args=")(PP_Resource context, const char *feature)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html#a7b682945881f47e3a02032ba542c8ce0">PPB_OpenGLES2ChromiumEnableFeature::EnableFeatureCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const char *feature)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html new file mode 100644 index 0000000..fea7735 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2ChromiumEnableFeature Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2ChromiumEnableFeature" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html#aab7e64c543027c95e5d9d02b8d4b972f">EnableFeatureCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const char *feature)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="aab7e64c543027c95e5d9d02b8d4b972f"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumEnableFeature::EnableFeatureCHROMIUM" ref="aab7e64c543027c95e5d9d02b8d4b972f" args=")(PP_Resource context, const char *feature)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html#aab7e64c543027c95e5d9d02b8d4b972f">PPB_OpenGLES2ChromiumEnableFeature::EnableFeatureCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const char *feature)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html new file mode 100644 index 0000000..a3048c70 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html
@@ -0,0 +1,74 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2ChromiumMapSub Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2ChromiumMapSub" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#acc9e5344e37376cf9e732819876ad67f">MapBufferSubDataCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#ab86dbf8472a8ce7477027459cbc9e45a">UnmapBufferSubDataCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#ae30d0bd3191b620513b9ede9fd48d697">MapTexSubImage2DCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#a070ead3876d6c726b2d4b1a979201327">UnmapTexSubImage2DCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="acc9e5344e37376cf9e732819876ad67f"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::MapBufferSubDataCHROMIUM" ref="acc9e5344e37376cf9e732819876ad67f" args=")(PP_Resource context, GLuint target, GLintptr offset, GLsizeiptr size, GLenum access)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#acc9e5344e37376cf9e732819876ad67f">PPB_OpenGLES2ChromiumMapSub::MapBufferSubDataCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae30d0bd3191b620513b9ede9fd48d697"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::MapTexSubImage2DCHROMIUM" ref="ae30d0bd3191b620513b9ede9fd48d697" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#ae30d0bd3191b620513b9ede9fd48d697">PPB_OpenGLES2ChromiumMapSub::MapTexSubImage2DCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab86dbf8472a8ce7477027459cbc9e45a"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::UnmapBufferSubDataCHROMIUM" ref="ab86dbf8472a8ce7477027459cbc9e45a" args=")(PP_Resource context, const void *mem)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#ab86dbf8472a8ce7477027459cbc9e45a">PPB_OpenGLES2ChromiumMapSub::UnmapBufferSubDataCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a070ead3876d6c726b2d4b1a979201327"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::UnmapTexSubImage2DCHROMIUM" ref="a070ead3876d6c726b2d4b1a979201327" args=")(PP_Resource context, const void *mem)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html#a070ead3876d6c726b2d4b1a979201327">PPB_OpenGLES2ChromiumMapSub::UnmapTexSubImage2DCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html new file mode 100644 index 0000000..41a8d1d --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html
@@ -0,0 +1,74 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2ChromiumMapSub Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2ChromiumMapSub" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#a296ecc89ac044069aff8ecccd38b21c9">MapBufferSubDataCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#ab35a055a709f8147ae20c40c4a9036ae">UnmapBufferSubDataCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void *(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#a4de8dea85b886ba2d15c201f40c669b9">MapTexSubImage2DCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#aef6105aadcc25ef4daee8dc2e52e4999">UnmapTexSubImage2DCHROMIUM</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a296ecc89ac044069aff8ecccd38b21c9"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::MapBufferSubDataCHROMIUM" ref="a296ecc89ac044069aff8ecccd38b21c9" args=")(PP_Resource context, GLuint target, GLintptr offset, GLsizeiptr size, GLenum access)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#a296ecc89ac044069aff8ecccd38b21c9">PPB_OpenGLES2ChromiumMapSub::MapBufferSubDataCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> target, <a class="el" href="ppb__opengles2_8h.html#af7b978d38577bc5026a5f5fea9dddd1b">GLintptr</a> offset, <a class="el" href="ppb__opengles2_8h.html#aaccb4d7c4f31e730b377b4c44d68bc31">GLsizeiptr</a> size, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a4de8dea85b886ba2d15c201f40c669b9"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::MapTexSubImage2DCHROMIUM" ref="a4de8dea85b886ba2d15c201f40c669b9" args=")(PP_Resource context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void*(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#a4de8dea85b886ba2d15c201f40c669b9">PPB_OpenGLES2ChromiumMapSub::MapTexSubImage2DCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> level, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> xoffset, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> yoffset, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> format, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> access)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ab35a055a709f8147ae20c40c4a9036ae"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::UnmapBufferSubDataCHROMIUM" ref="ab35a055a709f8147ae20c40c4a9036ae" args=")(PP_Resource context, const void *mem)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#ab35a055a709f8147ae20c40c4a9036ae">PPB_OpenGLES2ChromiumMapSub::UnmapBufferSubDataCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aef6105aadcc25ef4daee8dc2e52e4999"></a><!-- doxytag: member="PPB_OpenGLES2ChromiumMapSub::UnmapTexSubImage2DCHROMIUM" ref="aef6105aadcc25ef4daee8dc2e52e4999" args=")(PP_Resource context, const void *mem)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html#aef6105aadcc25ef4daee8dc2e52e4999">PPB_OpenGLES2ChromiumMapSub::UnmapTexSubImage2DCHROMIUM</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, const void *mem)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html new file mode 100644 index 0000000..f0dc77f --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2FramebufferBlit Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2FramebufferBlit" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html#a33288c12dd8062bc7d1894327ebb3771">BlitFramebufferEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY1, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> filter)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a33288c12dd8062bc7d1894327ebb3771"></a><!-- doxytag: member="PPB_OpenGLES2FramebufferBlit::BlitFramebufferEXT" ref="a33288c12dd8062bc7d1894327ebb3771" args=")(PP_Resource context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html#a33288c12dd8062bc7d1894327ebb3771">PPB_OpenGLES2FramebufferBlit::BlitFramebufferEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY1, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> filter)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html new file mode 100644 index 0000000..a186c67 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2FramebufferBlit Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2FramebufferBlit" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html#a4e11818dcb9aea72b7d8925d54e9d3ff">BlitFramebufferEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY1, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> filter)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a4e11818dcb9aea72b7d8925d54e9d3ff"></a><!-- doxytag: member="PPB_OpenGLES2FramebufferBlit::BlitFramebufferEXT" ref="a4e11818dcb9aea72b7d8925d54e9d3ff" args=")(PP_Resource context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html#a4e11818dcb9aea72b7d8925d54e9d3ff">PPB_OpenGLES2FramebufferBlit::BlitFramebufferEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> srcY1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY0, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstX1, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> dstY1, <a class="el" href="ppb__opengles2_8h.html#a0fb936f29008789fb46b434319f68cc9">GLbitfield</a> mask, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> filter)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html new file mode 100644 index 0000000..d214b8f --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2FramebufferMultisample Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2FramebufferMultisample" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html#ae9a2335014f42388fe445c023309aa4f">RenderbufferStorageMultisampleEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> samples, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="ae9a2335014f42388fe445c023309aa4f"></a><!-- doxytag: member="PPB_OpenGLES2FramebufferMultisample::RenderbufferStorageMultisampleEXT" ref="ae9a2335014f42388fe445c023309aa4f" args=")(PP_Resource context, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html#ae9a2335014f42388fe445c023309aa4f">PPB_OpenGLES2FramebufferMultisample::RenderbufferStorageMultisampleEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> samples, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html new file mode 100644 index 0000000..2446b64 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html
@@ -0,0 +1,35 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2FramebufferMultisample Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2FramebufferMultisample" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html#a22cdff264a2e10fa4b3843f2be095e92">RenderbufferStorageMultisampleEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> samples, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a22cdff264a2e10fa4b3843f2be095e92"></a><!-- doxytag: member="PPB_OpenGLES2FramebufferMultisample::RenderbufferStorageMultisampleEXT" ref="a22cdff264a2e10fa4b3843f2be095e92" args=")(PP_Resource context, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html#a22cdff264a2e10fa4b3843f2be095e92">PPB_OpenGLES2FramebufferMultisample::RenderbufferStorageMultisampleEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> samples, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> internalformat, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> width, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> height)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays.html new file mode 100644 index 0000000..4937e77 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays.html
@@ -0,0 +1,61 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2InstancedArrays Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2InstancedArrays" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#aacc8c2b28773b7f0a99c39a967f2e9f1">DrawArraysInstancedANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#a40a3200a267d4df2efe3ae5adce7c21e">DrawElementsInstancedANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#aad4d8b8f799dada68d83407310f63099">VertexAttribDivisorANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> divisor)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="aacc8c2b28773b7f0a99c39a967f2e9f1"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::DrawArraysInstancedANGLE" ref="aacc8c2b28773b7f0a99c39a967f2e9f1" args=")(PP_Resource context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#aacc8c2b28773b7f0a99c39a967f2e9f1">PPB_OpenGLES2InstancedArrays::DrawArraysInstancedANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a40a3200a267d4df2efe3ae5adce7c21e"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::DrawElementsInstancedANGLE" ref="a40a3200a267d4df2efe3ae5adce7c21e" args=")(PP_Resource context, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#a40a3200a267d4df2efe3ae5adce7c21e">PPB_OpenGLES2InstancedArrays::DrawElementsInstancedANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aad4d8b8f799dada68d83407310f63099"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::VertexAttribDivisorANGLE" ref="aad4d8b8f799dada68d83407310f63099" args=")(PP_Resource context, GLuint index, GLuint divisor)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays.html#aad4d8b8f799dada68d83407310f63099">PPB_OpenGLES2InstancedArrays::VertexAttribDivisorANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> divisor)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html new file mode 100644 index 0000000..491ff9d --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html
@@ -0,0 +1,61 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2InstancedArrays Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2InstancedArrays" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#af74c0f73abc3c097d0ec72f239a0c2b0">DrawArraysInstancedANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#a929c1a6861e4167aefda1f0b4f503f61">DrawElementsInstancedANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#aa5dac4f0d129c9954646c20e238bb8e7">VertexAttribDivisorANGLE</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> divisor)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="af74c0f73abc3c097d0ec72f239a0c2b0"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::DrawArraysInstancedANGLE" ref="af74c0f73abc3c097d0ec72f239a0c2b0" args=")(PP_Resource context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#af74c0f73abc3c097d0ec72f239a0c2b0">PPB_OpenGLES2InstancedArrays::DrawArraysInstancedANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> first, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a929c1a6861e4167aefda1f0b4f503f61"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::DrawElementsInstancedANGLE" ref="a929c1a6861e4167aefda1f0b4f503f61" args=")(PP_Resource context, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#a929c1a6861e4167aefda1f0b4f503f61">PPB_OpenGLES2InstancedArrays::DrawElementsInstancedANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> mode, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> count, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> type, const void *indices, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> primcount)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa5dac4f0d129c9954646c20e238bb8e7"></a><!-- doxytag: member="PPB_OpenGLES2InstancedArrays::VertexAttribDivisorANGLE" ref="aa5dac4f0d129c9954646c20e238bb8e7" args=")(PP_Resource context, GLuint index, GLuint divisor)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html#aa5dac4f0d129c9954646c20e238bb8e7">PPB_OpenGLES2InstancedArrays::VertexAttribDivisorANGLE</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> index, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> divisor)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query.html new file mode 100644 index 0000000..c2bc008 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query.html
@@ -0,0 +1,113 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2Query Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2Query" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#ac7f972db2f16fd921113b699809423a6">GenQueriesEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a540e524a6fd88ab096a207ecca7bc14c">DeleteQueriesEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a3c41482d977160b2b5996e0ac54c2966">IsQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a1ec23a910cbd8b946ef870522f988c01">BeginQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#af025f4ae3d19616f2919df8cbfc54d57">EndQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a20022463bd047ba05e8ce0e2efdb2af6">GetQueryivEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#af2a018b4c0b8e16ec5c84b6a859f64e9">GetQueryObjectuivEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *params)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a1ec23a910cbd8b946ef870522f988c01"></a><!-- doxytag: member="PPB_OpenGLES2Query::BeginQueryEXT" ref="a1ec23a910cbd8b946ef870522f988c01" args=")(PP_Resource context, GLenum target, GLuint id)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a1ec23a910cbd8b946ef870522f988c01">PPB_OpenGLES2Query::BeginQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a540e524a6fd88ab096a207ecca7bc14c"></a><!-- doxytag: member="PPB_OpenGLES2Query::DeleteQueriesEXT" ref="a540e524a6fd88ab096a207ecca7bc14c" args=")(PP_Resource context, GLsizei n, const GLuint *queries)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a540e524a6fd88ab096a207ecca7bc14c">PPB_OpenGLES2Query::DeleteQueriesEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af025f4ae3d19616f2919df8cbfc54d57"></a><!-- doxytag: member="PPB_OpenGLES2Query::EndQueryEXT" ref="af025f4ae3d19616f2919df8cbfc54d57" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#af025f4ae3d19616f2919df8cbfc54d57">PPB_OpenGLES2Query::EndQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ac7f972db2f16fd921113b699809423a6"></a><!-- doxytag: member="PPB_OpenGLES2Query::GenQueriesEXT" ref="ac7f972db2f16fd921113b699809423a6" args=")(PP_Resource context, GLsizei n, GLuint *queries)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#ac7f972db2f16fd921113b699809423a6">PPB_OpenGLES2Query::GenQueriesEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a20022463bd047ba05e8ce0e2efdb2af6"></a><!-- doxytag: member="PPB_OpenGLES2Query::GetQueryivEXT" ref="a20022463bd047ba05e8ce0e2efdb2af6" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a20022463bd047ba05e8ce0e2efdb2af6">PPB_OpenGLES2Query::GetQueryivEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="af2a018b4c0b8e16ec5c84b6a859f64e9"></a><!-- doxytag: member="PPB_OpenGLES2Query::GetQueryObjectuivEXT" ref="af2a018b4c0b8e16ec5c84b6a859f64e9" args=")(PP_Resource context, GLuint id, GLenum pname, GLuint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#af2a018b4c0b8e16ec5c84b6a859f64e9">PPB_OpenGLES2Query::GetQueryObjectuivEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a3c41482d977160b2b5996e0ac54c2966"></a><!-- doxytag: member="PPB_OpenGLES2Query::IsQueryEXT" ref="a3c41482d977160b2b5996e0ac54c2966" args=")(PP_Resource context, GLuint id)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query.html#a3c41482d977160b2b5996e0ac54c2966">PPB_OpenGLES2Query::IsQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html new file mode 100644 index 0000000..76e008a3 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html
@@ -0,0 +1,113 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2Query Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2Query" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#ae2f6e8510804ee551ee9edee69aa2c01">GenQueriesEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#ae49c996941b28dda03b9b1b20a12221b">DeleteQueriesEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a2cac26bbb7738ced3d8e117856eeda50">IsQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a5ba50bc0dc933e9e20233656610287df">BeginQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a8eb817ad4a0aa902a18acae5891dd66c">EndQueryEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#aaf9d9f118b872b8f1905eeb09a86b6da">GetQueryivEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a25c570a8514e53f01b224731fbcd8244">GetQueryObjectuivEXT</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *params)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a5ba50bc0dc933e9e20233656610287df"></a><!-- doxytag: member="PPB_OpenGLES2Query::BeginQueryEXT" ref="a5ba50bc0dc933e9e20233656610287df" args=")(PP_Resource context, GLenum target, GLuint id)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a5ba50bc0dc933e9e20233656610287df">PPB_OpenGLES2Query::BeginQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae49c996941b28dda03b9b1b20a12221b"></a><!-- doxytag: member="PPB_OpenGLES2Query::DeleteQueriesEXT" ref="ae49c996941b28dda03b9b1b20a12221b" args=")(PP_Resource context, GLsizei n, const GLuint *queries)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#ae49c996941b28dda03b9b1b20a12221b">PPB_OpenGLES2Query::DeleteQueriesEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a8eb817ad4a0aa902a18acae5891dd66c"></a><!-- doxytag: member="PPB_OpenGLES2Query::EndQueryEXT" ref="a8eb817ad4a0aa902a18acae5891dd66c" args=")(PP_Resource context, GLenum target)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a8eb817ad4a0aa902a18acae5891dd66c">PPB_OpenGLES2Query::EndQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ae2f6e8510804ee551ee9edee69aa2c01"></a><!-- doxytag: member="PPB_OpenGLES2Query::GenQueriesEXT" ref="ae2f6e8510804ee551ee9edee69aa2c01" args=")(PP_Resource context, GLsizei n, GLuint *queries)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#ae2f6e8510804ee551ee9edee69aa2c01">PPB_OpenGLES2Query::GenQueriesEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *queries)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aaf9d9f118b872b8f1905eeb09a86b6da"></a><!-- doxytag: member="PPB_OpenGLES2Query::GetQueryivEXT" ref="aaf9d9f118b872b8f1905eeb09a86b6da" args=")(PP_Resource context, GLenum target, GLenum pname, GLint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#aaf9d9f118b872b8f1905eeb09a86b6da">PPB_OpenGLES2Query::GetQueryivEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> target, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#a5ac0f3c4d7fafd42b284b5487a791017">GLint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a25c570a8514e53f01b224731fbcd8244"></a><!-- doxytag: member="PPB_OpenGLES2Query::GetQueryObjectuivEXT" ref="a25c570a8514e53f01b224731fbcd8244" args=")(PP_Resource context, GLuint id, GLenum pname, GLuint *params)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a25c570a8514e53f01b224731fbcd8244">PPB_OpenGLES2Query::GetQueryObjectuivEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id, <a class="el" href="ppb__opengles2_8h.html#a7efd7809e1632cdae75603fd1fee61c0">GLenum</a> pname, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *params)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a2cac26bbb7738ced3d8e117856eeda50"></a><!-- doxytag: member="PPB_OpenGLES2Query::IsQueryEXT" ref="a2cac26bbb7738ced3d8e117856eeda50" args=")(PP_Resource context, GLuint id)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_query__1__0.html#a2cac26bbb7738ced3d8e117856eeda50">PPB_OpenGLES2Query::IsQueryEXT</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> id)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html new file mode 100644 index 0000000..510cc761 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html
@@ -0,0 +1,74 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2VertexArrayObject Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2VertexArrayObject" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#a7d8cd9055647469e4aa1c56142f5c548">GenVertexArraysOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#a9d9d729442e72f4a16178664de686aaf">DeleteVertexArraysOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#aeefdbc2e5307baefcf414222904911bc">IsVertexArrayOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#ae513e9ea1e10bf0617621568a008024e">BindVertexArrayOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="ae513e9ea1e10bf0617621568a008024e"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::BindVertexArrayOES" ref="ae513e9ea1e10bf0617621568a008024e" args=")(PP_Resource context, GLuint array)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#ae513e9ea1e10bf0617621568a008024e">PPB_OpenGLES2VertexArrayObject::BindVertexArrayOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a9d9d729442e72f4a16178664de686aaf"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::DeleteVertexArraysOES" ref="a9d9d729442e72f4a16178664de686aaf" args=")(PP_Resource context, GLsizei n, const GLuint *arrays)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#a9d9d729442e72f4a16178664de686aaf">PPB_OpenGLES2VertexArrayObject::DeleteVertexArraysOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="a7d8cd9055647469e4aa1c56142f5c548"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::GenVertexArraysOES" ref="a7d8cd9055647469e4aa1c56142f5c548" args=")(PP_Resource context, GLsizei n, GLuint *arrays)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#a7d8cd9055647469e4aa1c56142f5c548">PPB_OpenGLES2VertexArrayObject::GenVertexArraysOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aeefdbc2e5307baefcf414222904911bc"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::IsVertexArrayOES" ref="aeefdbc2e5307baefcf414222904911bc" args=")(PP_Resource context, GLuint array)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object.html#aeefdbc2e5307baefcf414222904911bc">PPB_OpenGLES2VertexArrayObject::IsVertexArrayOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html new file mode 100644 index 0000000..e378a4a --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html
@@ -0,0 +1,74 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPB_OpenGLES2VertexArrayObject Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPB_OpenGLES2VertexArrayObject" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#aab4479bfadfd2598ea9e15081959a714">GenVertexArraysOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#ad45235047833c00a7229b65fc3611327">DeleteVertexArraysOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#aa544d5f9795315e906bc9101e3d526b3">IsVertexArrayOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#a09998a61d1a2a9538fb4941bd69337b0">BindVertexArrayOES</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td></tr> +</table> +<hr /><h2>Field Documentation</h2> +<a class="anchor" id="a09998a61d1a2a9538fb4941bd69337b0"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::BindVertexArrayOES" ref="a09998a61d1a2a9538fb4941bd69337b0" args=")(PP_Resource context, GLuint array)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#a09998a61d1a2a9538fb4941bd69337b0">PPB_OpenGLES2VertexArrayObject::BindVertexArrayOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="ad45235047833c00a7229b65fc3611327"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::DeleteVertexArraysOES" ref="ad45235047833c00a7229b65fc3611327" args=")(PP_Resource context, GLsizei n, const GLuint *arrays)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#ad45235047833c00a7229b65fc3611327">PPB_OpenGLES2VertexArrayObject::DeleteVertexArraysOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, const <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aab4479bfadfd2598ea9e15081959a714"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::GenVertexArraysOES" ref="aab4479bfadfd2598ea9e15081959a714" args=")(PP_Resource context, GLsizei n, GLuint *arrays)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#aab4479bfadfd2598ea9e15081959a714">PPB_OpenGLES2VertexArrayObject::GenVertexArraysOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#a9289d5b99dc1f27f01480360f2e18ae0">GLsizei</a> n, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> *arrays)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<a class="anchor" id="aa544d5f9795315e906bc9101e3d526b3"></a><!-- doxytag: member="PPB_OpenGLES2VertexArrayObject::IsVertexArrayOES" ref="aa544d5f9795315e906bc9101e3d526b3" args=")(PP_Resource context, GLuint array)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname"><a class="el" href="ppb__opengles2_8h.html#aa010a67382116caf29c29318251ccb6c">GLboolean</a>(* <a class="el" href="struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html#aa544d5f9795315e906bc9101e3d526b3">PPB_OpenGLES2VertexArrayObject::IsVertexArrayOES</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> context, <a class="el" href="ppb__opengles2_8h.html#aa311c7f0d6ec4f1a33f9235c3651b86b">GLuint</a> array)</td> +</tr> +</table> +</div> +<div class="memdoc"> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppb__opengles2_8h.html">ppb_opengles2.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__0__1.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__0__1.html deleted file mode 100644 index fe6e43c..0000000 --- a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__0__1.html +++ /dev/null
@@ -1,223 +0,0 @@ -{{+bindTo:partials.standard_nacl_api}} -<h1>PPB_VideoDecoder Struct Reference</h1> -<div id="doxygen-ref"> -{{- dummy div to appease doxygen -}} - <div> -<!-- Generated by Doxygen 1.7.6.1 --> - - -</div> -<!--header--> -<div class="contents"> -<!-- doxytag: class="PPB_VideoDecoder" --><h2> -Data Fields</h2><table class="memberdecls"> - -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#aab2c846ae7cf8c15e5337f8c768e3b27">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#afe3b784d87af6e4856e8bc6c6bb6629d">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#a477ac82814cc6677b082c6044df81b18">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a> allow_software_fallback, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#ae65877f22dc977a0747271809a741297">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -</table> -<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>Video decoder interface. </p> -<p>Typical usage:</p> -<ul> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aab2c846ae7cf8c15e5337f8c768e3b27" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a477ac82814cc6677b082c6044df81b18" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> -<li>To destroy the decoder, the plugin should release all of its references to it. Any pending callbacks will abort before the decoder is destroyed.</li> -</ul> -<p>Available video codecs vary by platform. All: theora, vorbis, vp8. Chrome and ChromeOS: aac, h264. ChromeOS: mpeg4. </p> -</div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="aab2c846ae7cf8c15e5337f8c768e3b27"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="aab2c846ae7cf8c15e5337f8c768e3b27" args=")(PP_Instance instance)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aab2c846ae7cf8c15e5337f8c768e3b27">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Creates a new video decoder resource. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying the instance with the video decoder.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a video decoder if successful or 0 otherwise. </dd></dl> -</div> -</div> -<a class="anchor" id="a8e2c5a3b99eff16845b8335be36e6d4c"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="a8e2c5a3b99eff16845b8335be36e6d4c" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Decodes a bitstream buffer. </p> -<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> again.</p> -<p>In general, each bitstream buffer should contain a demuxed bitstream frame for the selected video codec. For example, H264 decoders expect to receive one AnnexB NAL unit, including the 4 byte start code prefix, while VP8 decoders expect to receive a bitstream frame without the IVF frame header.</p> -<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">size</td><td>Buffer size in bytes. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>Starting address of buffer. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> -</div> -</div> -<a class="anchor" id="a56052b4cdde98dbed1f8fdc3df379eb4"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="a56052b4cdde98dbed1f8fdc3df379eb4" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Flushes the decoder. </p> -<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__1.html#ae65877f22dc977a0747271809a741297" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> -</div> -</div> -<a class="anchor" id="aa058b25aa12485118536fb42130b367a"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="aa058b25aa12485118536fb42130b367a" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Gets the next picture from the decoder. </p> -<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__0__1.html#ae65877f22dc977a0747271809a741297" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[out]</td><td class="paramname">picture</td><td>A <code><a class="el" href="struct_p_p___video_picture.html" title="Struct describing a decoded video picture.">PP_VideoPicture</a></code> to hold the decoded picture. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a56052b4cdde98dbed1f8fdc3df379eb4" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> -</div> -</div> -<a class="anchor" id="a477ac82814cc6677b082c6044df81b18"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="a477ac82814cc6677b082c6044df81b18" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_Bool allow_software_fallback, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a477ac82814cc6677b082c6044df81b18">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a> allow_software_fallback, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Initializes a video decoder resource. </p> -<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aab2c846ae7cf8c15e5337f8c768e3b27" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">graphics3d_context</td><td>A <code>PPB_Graphics3D</code> resource to use during decoding. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">profile</td><td>A <code>PP_VideoProfile</code> specifying the video codec profile. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">allow_software_fallback</td><td>A <code>PP_Bool</code> specifying whether the decoder can fall back to software decoding if a suitable hardware decoder isn't available. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called upon completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a477ac82814cc6677b082c6044df81b18" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> -</div> -</div> -<a class="anchor" id="afe3b784d87af6e4856e8bc6c6bb6629d"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="afe3b784d87af6e4856e8bc6c6bb6629d" args=")(PP_Resource resource)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#afe3b784d87af6e4856e8bc6c6bb6629d">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Determines if the given resource is a video decoder. </p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">resource</td><td>A <code>PP_Resource</code> identifying a resource.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the resource is a <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is invalid or some other type. </dd></dl> -</div> -</div> -<a class="anchor" id="ae65877f22dc977a0747271809a741297"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="ae65877f22dc977a0747271809a741297" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#ae65877f22dc977a0747271809a741297">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Recycles a picture that the plugin has received from the decoder. </p> -<p>The plugin should call this as soon as it has finished using the texture so the decoder can decode more pictures.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">picture</td><td>A <code><a class="el" href="struct_p_p___video_picture.html" title="Struct describing a decoded video picture.">PP_VideoPicture</a></code> to return to the decoder. </td></tr> -</table> -</dd> -</dl> -</div> -</div> -<a class="anchor" id="a0ad3178247894ca37eadd796d157581a"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="a0ad3178247894ca37eadd796d157581a" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> -<div class="memitem"> -<div class="memproto"> -<table class="memname"> -<tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> -</tr> -</table> -</div> -<div class="memdoc"> -<p>Resets the decoder as quickly as possible. </p> -<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a0ad3178247894ca37eadd796d157581a" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__0__1.html#a8e2c5a3b99eff16845b8335be36e6d4c" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__1.html#aa058b25aa12485118536fb42130b367a" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__1.html#ae65877f22dc977a0747271809a741297" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> -<dl class="params"><dt><b>Parameters:</b></dt><dd> -<table class="params"> -<tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> -</table> -</dd> -</dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> -</div> -</div> -<hr />The documentation for this struct was generated from the following file:<ul> -<li><a class="el" href="ppb__video__decoder_8h.html">ppb_video_decoder.h</a></li> -</ul> -</div><!-- contents --> -</div> -{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__1__0.html similarity index 74% copy from native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html copy to native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__1__0.html index 1cc6802..c8dd134 100644 --- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___video_decoder__0__2.html +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___video_decoder__1__0.html
@@ -12,35 +12,35 @@ <!-- doxytag: class="PPB_VideoDecoder" --><h2> Data Fields</h2><table class="memberdecls"> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">IsVideoDecoder</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">Initialize</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">Decode</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">GetPicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">RecyclePicture</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">Flush</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">Reset</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td></tr> </table> <hr /><a name="details" id="details"></a><h2>Detailed Description</h2> <div class="textblock"><p>Video decoder interface. </p> <p>Typical usage:</p> <ul> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> -<li>Call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> to create a new video decoder resource.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> to initialize it with a 3d graphics context and the desired codec profile.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> continuously (waiting for each previous call to complete) to push bitstream buffers to the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> continuously (waiting for each previous call to complete) to pull decoded pictures from the decoder.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> to signal end of stream to the decoder and perform shutdown when it completes.</li> +<li>Call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to quickly stop the decoder (e.g. to implement Seek) and wait for the callback before restarting decoding at another point.</li> <li>To destroy the decoder, the plugin should release all of its references to it. Any pending callbacks will abort before the decoder is destroyed.</li> </ul> <p>Available video codecs vary by platform. All: theora, vorbis, vp8. Chrome and ChromeOS: aac, h264. ChromeOS: mpeg4. </p> </div><hr /><h2>Field Documentation</h2> -<a class="anchor" id="aaca90b3aba351b89cd777c8c563360c4"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="aaca90b3aba351b89cd777c8c563360c4" args=")(PP_Instance instance)" --> +<a class="anchor" id="a81200f606c493c49a70190ca86ac135c"></a><!-- doxytag: member="PPB_VideoDecoder::Create" ref="a81200f606c493c49a70190ca86ac135c" args=")(PP_Instance instance)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> +<td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c">PPB_VideoDecoder::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td> </tr> </table> </div> @@ -55,45 +55,45 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>A <code>PP_Resource</code> corresponding to a video decoder if successful or 0 otherwise. </dd></dl> </div> </div> -<a class="anchor" id="ad2e85b80316537e0e01724e1b1875a15"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="ad2e85b80316537e0e01724e1b1875a15" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="acc8662be4232325abc545d1ae8b79366"></a><!-- doxytag: member="PPB_VideoDecoder::Decode" ref="acc8662be4232325abc545d1ae8b79366" args=")(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366">PPB_VideoDecoder::Decode</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, uint32_t decode_id, uint32_t size, const void *buffer, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Decodes a bitstream buffer. </p> -<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> again.</p> +<p>Copies |size| bytes of data from the plugin's |buffer|. The plugin should wait until the decoder signals completion by returning PP_OK or by running |callback| before calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> again.</p> <p>In general, each bitstream buffer should contain a demuxed bitstream frame for the selected video codec. For example, H264 decoders expect to receive one AnnexB NAL unit, including the 4 byte start code prefix, while VP8 decoders expect to receive a bitstream frame without the IVF frame header.</p> -<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> +<p>If the call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> eventually results in a picture, the |decode_id| parameter is copied into the returned picture. The plugin can use this to associate decoded pictures with <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> calls (e.g. to assign timestamps or frame numbers to pictures.) This value is opaque to the API so the plugin is free to pass any value.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> -<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">decode_id</td><td>An optional value, chosen by the plugin, that can be used to associate calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> with decoded pictures returned by <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">size</td><td>Buffer size in bytes. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">buffer</td><td>Starting address of buffer. </td></tr> <tr><td class="paramdir">[in]</td><td class="paramname">callback</td><td>A <code><a class="el" href="struct_p_p___completion_callback.html" title="PP_CompletionCallback is a common mechanism for supporting potentially asynchronous calls in browser ...">PP_CompletionCallback</a></code> to be called on completion.</td></tr> </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> or <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call pending. Returns PP_ERROR_NOMEMORY if a bitstream buffer can't be created. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a1a85da162f50990f318ff8bff61ceacc"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="a1a85da162f50990f318ff8bff61ceacc" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="adf3ea0876d1ba686266589a04532e86d"></a><!-- doxytag: member="PPB_VideoDecoder::Flush" ref="adf3ea0876d1ba686266589a04532e86d" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d">PPB_VideoDecoder::Flush</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Flushes the decoder. </p> -<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> +<p>The plugin should call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> when it reaches the end of its video stream in order to stop cleanly. The decoder will run any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> call to completion. The plugin should make no further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Just before completion, any pending <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call will complete by running its callback with result PP_ERROR_ABORTED to signal that no more pictures are available. Any pictures held by the plugin remain valid during and after the flush and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -104,18 +104,18 @@ <dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized. </dd></dl> </div> </div> -<a class="anchor" id="a53284466cb36653f3d91a4889b292811"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a53284466cb36653f3d91a4889b292811" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="a2351fe0cf66513ee77df0c1a22306c3e"></a><!-- doxytag: member="PPB_VideoDecoder::GetPicture" ref="a2351fe0cf66513ee77df0c1a22306c3e" args=")(PP_Resource video_decoder, struct PP_VideoPicture *picture, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e">PPB_VideoDecoder::GetPicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Gets the next picture from the decoder. </p> -<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> +<p>The picture is valid after the decoder signals completion by returning PP_OK or running |callback|. The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> again after the decoder signals completion. When the plugin is finished using the picture, it should return it to the system by calling <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a>.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -124,21 +124,21 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a1a85da162f50990f318ff8bff61ceacc" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_FAILED if the decoder isn't initialized or if a <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> call is pending. Returns PP_ERROR_INPROGRESS if there is another <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> call pending. Returns PP_ERROR_ABORTED when <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> is called, or if a call to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#adf3ea0876d1ba686266589a04532e86d" title="Flushes the decoder.">Flush()</a> completes while <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a> is pending. </dd></dl> </div> </div> -<a class="anchor" id="a821341ce72fe1db025913f562626b119"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="a821341ce72fe1db025913f562626b119" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="ad115b7705b740b771e7dd9acb2b36f16"></a><!-- doxytag: member="PPB_VideoDecoder::Initialize" ref="ad115b7705b740b771e7dd9acb2b36f16" args=")(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16">PPB_VideoDecoder::Initialize</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, <a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> graphics3d_context, <a class="el" href="group___enums.html#ga4d50d27186f68b2de578e82162206fea">PP_VideoProfile</a> profile, <a class="el" href="group___enums.html#ga6a3fd7e22be02521243b52481afadae5">PP_HardwareAcceleration</a> acceleration, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Initializes a video decoder resource. </p> -<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__0__2.html#aaca90b3aba351b89cd777c8c563360c4" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> +<p>This should be called after <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a81200f606c493c49a70190ca86ac135c" title="Creates a new video decoder resource.">Create()</a> and before any other functions.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr> @@ -149,15 +149,15 @@ </table> </dd> </dl> -<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a821341ce72fe1db025913f562626b119" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> +<dl class="return"><dt><b>Returns:</b></dt><dd>An int32_t containing an error code from <code><a class="el" href="pp__errors_8h.html" title="This file defines an enumeration of all PPAPI error codes.">pp_errors.h</a></code>. Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the requested profile is not supported. In this case, the client may call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ad115b7705b740b771e7dd9acb2b36f16" title="Initializes a video decoder resource.">Initialize()</a> again with different parameters to find a good configuration. </dd></dl> </div> </div> -<a class="anchor" id="a3748268a6df835f3eb661b0c690c37bb"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="a3748268a6df835f3eb661b0c690c37bb" args=")(PP_Resource resource)" --> +<a class="anchor" id="ae2329143c44bd5eaae507074c1fc0ec3"></a><!-- doxytag: member="PPB_VideoDecoder::IsVideoDecoder" ref="ae2329143c44bd5eaae507074c1fc0ec3" args=")(PP_Resource resource)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a3748268a6df835f3eb661b0c690c37bb">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> +<td class="memname"><a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a>(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ae2329143c44bd5eaae507074c1fc0ec3">PPB_VideoDecoder::IsVideoDecoder</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> resource)</td> </tr> </table> </div> @@ -172,12 +172,12 @@ <dl class="return"><dt><b>Returns:</b></dt><dd><code>PP_TRUE</code> if the resource is a <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is invalid or some other type. </dd></dl> </div> </div> -<a class="anchor" id="a30fbc6abf22cae02032bdc713ee41d1e"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="a30fbc6abf22cae02032bdc713ee41d1e" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> +<a class="anchor" id="ac7e6b42866d42eade96519f32755509f"></a><!-- doxytag: member="PPB_VideoDecoder::RecyclePicture" ref="ac7e6b42866d42eade96519f32755509f" args=")(PP_Resource video_decoder, const struct PP_VideoPicture *picture)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> +<td class="memname">void(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f">PPB_VideoDecoder::RecyclePicture</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, const struct <a class="el" href="struct_p_p___video_picture.html">PP_VideoPicture</a> *picture)</td> </tr> </table> </div> @@ -193,18 +193,18 @@ </dl> </div> </div> -<a class="anchor" id="a4697495911e69da035d786dc69ce22ca"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="a4697495911e69da035d786dc69ce22ca" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> +<a class="anchor" id="aeb4704cfd86a4ad737af19e77f3ffd5e"></a><!-- doxytag: member="PPB_VideoDecoder::Reset" ref="aeb4704cfd86a4ad737af19e77f3ffd5e" args=")(PP_Resource video_decoder, struct PP_CompletionCallback callback)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> -<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> +<td class="memname">int32_t(* <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e">PPB_VideoDecoder::Reset</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> video_decoder, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback)</td> </tr> </table> </div> <div class="memdoc"> <p>Resets the decoder as quickly as possible. </p> -<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a4697495911e69da035d786dc69ce22ca" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__0__2.html#ad2e85b80316537e0e01724e1b1875a15" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a53284466cb36653f3d91a4889b292811" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__0__2.html#a30fbc6abf22cae02032bdc713ee41d1e" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> +<p>The plugin can call <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> to skip to another position in the video stream. After <a class="el" href="struct_p_p_b___video_decoder__1__0.html#aeb4704cfd86a4ad737af19e77f3ffd5e" title="Resets the decoder as quickly as possible.">Reset()</a> returns, any pending calls to <a class="el" href="struct_p_p_b___video_decoder__1__0.html#acc8662be4232325abc545d1ae8b79366" title="Decodes a bitstream buffer.">Decode()</a> and <a class="el" href="struct_p_p_b___video_decoder__1__0.html#a2351fe0cf66513ee77df0c1a22306c3e" title="Gets the next picture from the decoder.">GetPicture()</a>) abort, causing their callbacks to run with PP_ERROR_ABORTED. The plugin should not make further calls to the decoder other than <a class="el" href="struct_p_p_b___video_decoder__1__0.html#ac7e6b42866d42eade96519f32755509f" title="Recycles a picture that the plugin has received from the decoder.">RecyclePicture()</a> until the decoder signals completion by running |callback|. Any pictures held by the plugin remain valid during and after the reset and should be recycled back to the decoder.</p> <dl class="params"><dt><b>Parameters:</b></dt><dd> <table class="params"> <tr><td class="paramdir">[in]</td><td class="paramname">video_decoder</td><td>A <code>PP_Resource</code> identifying the video decoder. </td></tr>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_p___message_handler__0__2.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_p___message_handler__0__2.html new file mode 100644 index 0000000..dca3ae8 --- /dev/null +++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_p___message_handler__0__2.html
@@ -0,0 +1,93 @@ +{{+bindTo:partials.standard_nacl_api}} +<h1>PPP_MessageHandler Struct Reference</h1> +<div id="doxygen-ref"> +{{- dummy div to appease doxygen -}} + <div> +<!-- Generated by Doxygen 1.7.6.1 --> + + +</div> +<!--header--> +<div class="contents"> +<!-- doxytag: class="PPP_MessageHandler" --><h2> +Data Fields</h2><table class="memberdecls"> + +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___message_handler__0__2.html#ab8b6b045541790d1d0ca862d0a225f27">HandleMessage</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *message)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___message_handler__0__2.html#aca37a8a59cb6a0b9be2846a2ab3e2828">HandleBlockingMessage</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *message, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *response)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_p___message_handler__0__2.html#a0804b4fbaab3b6abedd888e96107fd4d">Destroy</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data)</td></tr> +</table> +<hr /><a name="details" id="details"></a><h2>Detailed Description</h2> +<div class="textblock"><p>The <code>PPP_MessageHandler</code> interface is implemented by the plugin if the plugin wants to receive messages from a thread other than the main Pepper thread, or if the plugin wants to handle blocking messages which JavaScript may send via postMessageAndAwaitResponse(). </p> +<p>This interface struct should not be returned by PPP_GetInterface; instead it must be passed as a parameter to <a class="el" href="struct_p_p_b___messaging__1__2.html#ae5abee73dc21a290514f7f3554a7e895" title="Registers a handler for receiving messages from JavaScript.">PPB_Messaging::RegisterMessageHandler</a>. </p> +</div><hr /><h2>Field Documentation</h2> +<a class="anchor" id="a0804b4fbaab3b6abedd888e96107fd4d"></a><!-- doxytag: member="PPP_MessageHandler::Destroy" ref="a0804b4fbaab3b6abedd888e96107fd4d" args=")(PP_Instance instance, void *user_data)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_p___message_handler__0__2.html#a0804b4fbaab3b6abedd888e96107fd4d">PPP_MessageHandler::Destroy</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Invoked when the handler object is no longer needed. </p> +<p>After this, no more calls will be made which pass this same value for <code>instance</code> and <code>user_data</code>.</p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">user_data</td><td>is the same pointer which was provided by a call to RegisterMessageHandler. </td></tr> +</table> +</dd> +</dl> +</div> +</div> +<a class="anchor" id="aca37a8a59cb6a0b9be2846a2ab3e2828"></a><!-- doxytag: member="PPP_MessageHandler::HandleBlockingMessage" ref="aca37a8a59cb6a0b9be2846a2ab3e2828" args=")(PP_Instance instance, void *user_data, const struct PP_Var *message, struct PP_Var *response)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_p___message_handler__0__2.html#aca37a8a59cb6a0b9be2846a2ab3e2828">PPP_MessageHandler::HandleBlockingMessage</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *message, struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *response)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Invoked as a result of JavaScript invoking postMessageAndAwaitResponse() on the plugin's DOM element. </p> +<p>NOTE: JavaScript execution is blocked during the duration of this call. Hence, the plugin should respond as quickly as possible. For this reason, blocking completion callbacks are disallowed while handling a blocking message.</p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">user_data</td><td>is the same pointer which was provided by a call to RegisterMessageHandler(). </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">message</td><td>is a copy of the parameter that JavaScript provided to postMessageAndAwaitResponse(). </td></tr> +<tr><td class="paramdir">[out]</td><td class="paramname">response</td><td>will be copied to a JavaScript object which is returned as the result of postMessageAndAwaitResponse() to the invoking </td></tr> +</table> +</dd> +</dl> +</div> +</div> +<a class="anchor" id="ab8b6b045541790d1d0ca862d0a225f27"></a><!-- doxytag: member="PPP_MessageHandler::HandleMessage" ref="ab8b6b045541790d1d0ca862d0a225f27" args=")(PP_Instance instance, void *user_data, const struct PP_Var *message)" --> +<div class="memitem"> +<div class="memproto"> +<table class="memname"> +<tr> +<td class="memname">void(* <a class="el" href="struct_p_p_p___message_handler__0__2.html#ab8b6b045541790d1d0ca862d0a225f27">PPP_MessageHandler::HandleMessage</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance, void *user_data, const struct <a class="el" href="struct_p_p___var.html">PP_Var</a> *message)</td> +</tr> +</table> +</div> +<div class="memdoc"> +<p>Invoked as a result of JavaScript invoking postMessage() on the plugin's DOM element. </p> +<dl class="params"><dt><b>Parameters:</b></dt><dd> +<table class="params"> +<tr><td class="paramdir">[in]</td><td class="paramname">instance</td><td>A <code>PP_Instance</code> identifying one instance of a module. </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">user_data</td><td>is the same pointer which was provided by a call to RegisterMessageHandler(). </td></tr> +<tr><td class="paramdir">[in]</td><td class="paramname">message</td><td>A copy of the parameter that JavaScript provided to postMessage(). </td></tr> +</table> +</dd> +</dl> +</div> +</div> +<hr />The documentation for this struct was generated from the following file:<ul> +<li><a class="el" href="ppp__message__handler_8h.html">ppp_message_handler.h</a></li> +</ul> +</div><!-- contents --> +</div> +{{/partials.standard_nacl_api}}
diff --git a/native_client_sdk/doc_generated/pepper_stable/index.html b/native_client_sdk/doc_generated/pepper_stable/index.html index 3f6f1fb4..c25f5c0b 100644 --- a/native_client_sdk/doc_generated/pepper_stable/index.html +++ b/native_client_sdk/doc_generated/pepper_stable/index.html
@@ -2,8 +2,8 @@ <section id="pepper-api-reference-stable"> <h1 id="pepper-api-reference-stable">Pepper API Reference (Stable)</h1> -<p>This page lists the API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher.</p> +<p>This page lists the API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher.</p> <h2 id="pepper-c-api-reference"><a class="reference internal" href="/native-client/c-api.html#pepper-stable-c-index"><em>Pepper C API Reference</em></a></h2> <h2 id="id1"><a class="reference internal" href="/native-client/cpp-api.html#pepper-stable-cpp-index"><em>Pepper C++ API Reference</em></a></h2> </section>
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py index 503dda1..f2c5d60c 100755 --- a/native_client_sdk/src/build_tools/build_sdk.py +++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -84,58 +84,73 @@ buildbot_common.ErrorExit('Unknown architecture: %s' % arch) -def GetGypGenDir(xarch): - if xarch == 'arm': - build_dir = GYPBUILD_DIR + '-arm' +def GetConfigDir(arch): + if arch == 'x64' and getos.GetPlatform() == 'win': + return 'Release_x64' else: - build_dir = GYPBUILD_DIR - return os.path.join(OUT_DIR, build_dir, 'Release', 'gen') + return 'Release' -def GetGypBuiltLib(tcname, xarch=None): +def GetNinjaOutDir(arch): + return os.path.join(OUT_DIR, GYPBUILD_DIR + '-' + arch, GetConfigDir(arch)) + + +def GetGypBuiltLib(tcname, arch): + if arch == 'ia32': + lib_suffix = '32' + elif arch == 'x64': + lib_suffix = '64' + elif arch == 'arm': + lib_suffix = 'arm' + else: + lib_suffix = '' + if tcname == 'pnacl': tcname = 'pnacl_newlib' - if not xarch: - xarch = '' - return os.path.join(GetGypGenDir(xarch), 'tc_' + tcname, 'lib' + xarch) + arch = 'x64' + + return os.path.join(GetNinjaOutDir(arch), + 'gen', + 'tc_' + tcname, + 'lib' + lib_suffix) -def GetToolchainNaClLib(tcname, tcpath, xarch): +def GetToolchainNaClLib(tcname, tcpath, arch): if tcname == 'pnacl': return os.path.join(tcpath, 'le32-nacl', 'lib') - elif xarch == '32': + elif arch == 'ia32': return os.path.join(tcpath, 'x86_64-nacl', 'lib32') - elif xarch == '64': + elif arch == 'x64': return os.path.join(tcpath, 'x86_64-nacl', 'lib') - elif xarch == 'arm': + elif arch == 'arm': return os.path.join(tcpath, 'arm-nacl', 'lib') -def GetToolchainDirName(tcname, xarch): +def GetToolchainDirName(tcname, arch): if tcname == 'pnacl': return '%s_%s' % (getos.GetPlatform(), tcname) - elif xarch == 'arm': + elif arch == 'arm': return '%s_arm_%s' % (getos.GetPlatform(), tcname) else: return '%s_x86_%s' % (getos.GetPlatform(), tcname) -def GetGypToolchainLib(tcname, xarch): - if xarch == 'arm': - toolchain = xarch +def GetGypToolchainLib(tcname, arch): + if arch == 'arm': + toolchain = arch else: toolchain = tcname - tcpath = os.path.join(GetGypGenDir(xarch), 'sdk', + tcpath = os.path.join(GetNinjaOutDir(arch), 'gen', 'sdk', '%s_x86' % getos.GetPlatform(), TOOLCHAIN_PACKAGE_MAP[toolchain][0]) - return GetToolchainNaClLib(tcname, tcpath, xarch) + return GetToolchainNaClLib(tcname, tcpath, arch) -def GetOutputToolchainLib(pepperdir, tcname, xarch): +def GetOutputToolchainLib(pepperdir, tcname, arch): tcpath = os.path.join(pepperdir, 'toolchain', - GetToolchainDirName(tcname, xarch)) - return GetToolchainNaClLib(tcname, tcpath, xarch) + GetToolchainDirName(tcname, arch)) + return GetToolchainNaClLib(tcname, tcpath, arch) def GetPNaClTranslatorLib(tcpath, arch): @@ -373,63 +388,64 @@ def GypNinjaInstall(pepperdir, toolchains): - build_dir = GYPBUILD_DIR - ninja_out_dir = os.path.join(OUT_DIR, build_dir, 'Release') - tools_files = [ + tools_files_32 = [ ['sel_ldr', 'sel_ldr_x86_32'], - ['ncval_new', 'ncval'], ['irt_core_newlib_x32.nexe', 'irt_core_x86_32.nexe'], ['irt_core_newlib_x64.nexe', 'irt_core_x86_64.nexe'], ] + tools_files_64 = [] + platform = getos.GetPlatform() # TODO(binji): dump_syms doesn't currently build on Windows. See # http://crbug.com/245456 if platform != 'win': - tools_files += [ + tools_files_64 += [ ['dump_syms', 'dump_syms'], ['minidump_dump', 'minidump_dump'], ['minidump_stackwalk', 'minidump_stackwalk'] ] - tools_files.append(['sel_ldr64', 'sel_ldr_x86_64']) + tools_files_64.append(['sel_ldr', 'sel_ldr_x86_64']) + tools_files_64.append(['ncval_new', 'ncval']) if platform == 'linux': - tools_files.append(['nacl_helper_bootstrap', - 'nacl_helper_bootstrap_x86_32']) - tools_files.append(['nacl_helper_bootstrap64', - 'nacl_helper_bootstrap_x86_64']) - tools_files.append(['nonsfi_loader_newlib_x32_nonsfi.nexe', - 'nonsfi_loader_x86_32']) + tools_files_32.append(['nacl_helper_bootstrap', + 'nacl_helper_bootstrap_x86_32']) + tools_files_64.append(['nacl_helper_bootstrap', + 'nacl_helper_bootstrap_x86_64']) + tools_files_32.append(['nonsfi_loader_newlib_x32_nonsfi.nexe', + 'nonsfi_loader_x86_32']) - buildbot_common.MakeDir(os.path.join(pepperdir, 'tools')) + tools_dir = os.path.join(pepperdir, 'tools') + buildbot_common.MakeDir(tools_dir) # Add .exe extensions to all windows tools - for pair in tools_files: + for pair in tools_files_32 + tools_files_64: if platform == 'win' and not pair[0].endswith('.nexe'): pair[0] += '.exe' pair[1] += '.exe' - InstallFiles(ninja_out_dir, os.path.join(pepperdir, 'tools'), tools_files) + InstallFiles(GetNinjaOutDir('x64'), tools_dir, tools_files_64) + InstallFiles(GetNinjaOutDir('ia32'), tools_dir, tools_files_32) # Add ARM binaries if platform == 'linux' and not options.no_arm_trusted: - tools_files = [ + arm_files = [ ['irt_core_newlib_arm.nexe', 'irt_core_arm.nexe'], ['irt_core_newlib_arm.nexe', 'irt_core_arm.nexe'], ['nacl_helper_bootstrap', 'nacl_helper_bootstrap_arm'], ['nonsfi_loader_newlib_arm_nonsfi.nexe', 'nonsfi_loader_arm'], ['sel_ldr', 'sel_ldr_arm'] ] - ninja_out_dir = os.path.join(OUT_DIR, build_dir + '-arm', 'Release') - InstallFiles(ninja_out_dir, os.path.join(pepperdir, 'tools'), tools_files) + InstallFiles(GetNinjaOutDir('arm'), tools_dir, arm_files) for tc in set(toolchains) & set(['newlib', 'glibc', 'pnacl']): if tc == 'pnacl': xarches = (None,) else: - xarches = ('arm', '32', '64') + xarches = ('arm', 'ia32', 'x64') for xarch in xarches: if tc == 'glibc' and xarch == 'arm': @@ -462,29 +478,13 @@ nacl_core_sdk_gyp = os.path.join(NACL_DIR, 'build', 'nacl_core_sdk.gyp') all_gyp = os.path.join(NACL_DIR, 'build', 'all.gyp') - out_dir = MakeNinjaRelPath(rel_out_dir) + out_dir_32 = MakeNinjaRelPath(rel_out_dir + '-ia32') + out_dir_64 = MakeNinjaRelPath(rel_out_dir + '-x64') out_dir_arm = MakeNinjaRelPath(rel_out_dir + '-arm') - GypNinjaBuild('ia32', gyp_py, nacl_core_sdk_gyp, 'nacl_core_sdk', out_dir) + GypNinjaBuild('ia32', gyp_py, nacl_core_sdk_gyp, 'nacl_core_sdk', out_dir_32) GypNinjaBuild('arm', gyp_py, nacl_core_sdk_gyp, 'nacl_core_sdk', out_dir_arm) - GypNinjaBuild(None, gyp_py, all_gyp, 'ncval_new', out_dir) - - platform = getos.GetPlatform() - if platform == 'win': - NinjaBuild('sel_ldr64', out_dir) - else: - out_dir_64 = MakeNinjaRelPath(rel_out_dir + '-64') - GypNinjaBuild('x64', gyp_py, nacl_core_sdk_gyp, 'sel_ldr', out_dir_64) - - # We only need sel_ldr from the 64-bit out directory. - # sel_ldr needs to be renamed, so we'll call it sel_ldr64. - files_to_copy = [('sel_ldr', 'sel_ldr64')] - if platform == 'linux': - files_to_copy.append(('nacl_helper_bootstrap', 'nacl_helper_bootstrap64')) - - for src, dst in files_to_copy: - buildbot_common.CopyFile( - os.path.join(SRC_DIR, out_dir_64, 'Release', src), - os.path.join(SRC_DIR, out_dir, 'Release', dst)) + GypNinjaBuild('x64', gyp_py, nacl_core_sdk_gyp, 'nacl_core_sdk', out_dir_64) + GypNinjaBuild('x64', gyp_py, all_gyp, 'ncval_new', out_dir_64) def GypNinjaBuild_Breakpad(rel_out_dir): @@ -497,7 +497,7 @@ out_dir = MakeNinjaRelPath(rel_out_dir) gyp_file = os.path.join(SRC_DIR, 'breakpad', 'breakpad.gyp') build_list = ['dump_syms', 'minidump_dump', 'minidump_stackwalk'] - GypNinjaBuild(None, gyp_py, gyp_file, build_list, out_dir) + GypNinjaBuild('x64', gyp_py, gyp_file, build_list, out_dir) def GypNinjaBuild_PPAPI(arch, rel_out_dir): @@ -538,39 +538,56 @@ gyp_defines.append('clang=1') gyp_env['GYP_DEFINES'] = ' '.join(gyp_defines) - for key in ['GYP_GENERATORS', 'GYP_DEFINES', 'CC']: - value = gyp_env.get(key) - if value is not None: + # We can't use windows path separators in GYP_GENERATOR_FLAGS since + # gyp uses shlex to parse them and treats '\' as an escape char. + gyp_env['GYP_GENERATOR_FLAGS'] = 'output_dir=%s' % out_dir.replace('\\', '/') + + # Print relevant environment variables + for key, value in gyp_env.iteritems(): + if key.startswith('GYP') or key in ('CC',): print '%s="%s"' % (key, value) - gyp_generator_flags = ['-G', 'output_dir=%s' % (out_dir,)] - gyp_depth = '--depth=.' + buildbot_common.Run( - [sys.executable, gyp_py_script, gyp_file, gyp_depth] + \ - gyp_generator_flags, + [sys.executable, gyp_py_script, gyp_file, '--depth=.'], cwd=SRC_DIR, env=gyp_env) - NinjaBuild(targets, out_dir) + + NinjaBuild(targets, out_dir, arch) -def NinjaBuild(targets, out_dir): +def NinjaBuild(targets, out_dir, arch): if type(targets) is not list: targets = [targets] - out_config_dir = os.path.join(out_dir, 'Release') + out_config_dir = os.path.join(out_dir, GetConfigDir(arch)) buildbot_common.Run(['ninja', '-C', out_config_dir] + targets, cwd=SRC_DIR) -def BuildStepBuildToolchains(pepperdir, toolchains): +def BuildStepBuildToolchains(pepperdir, toolchains, build, clean): buildbot_common.BuildStep('SDK Items') - # Remove all gypbuild-* dirs. - buildbot_common.RemoveDir(os.path.join(OUT_DIR, GYPBUILD_DIR)) - buildbot_common.RemoveDir(os.path.join(OUT_DIR, GYPBUILD_DIR) + '-arm') - buildbot_common.RemoveDir(os.path.join(OUT_DIR, GYPBUILD_DIR) + '-64') - buildbot_common.RemoveDir(os.path.join(OUT_DIR, GYPBUILD_DIR) + '-pnacl-ia32') - buildbot_common.RemoveDir(os.path.join(OUT_DIR, GYPBUILD_DIR) + '-pnacl-arm') + if clean: + for dirname in glob.glob(os.path.join(OUT_DIR, GYPBUILD_DIR + '*')): + buildbot_common.RemoveDir(dirname) - GypNinjaBuild_NaCl(GYPBUILD_DIR) - GypNinjaBuild_Breakpad(GYPBUILD_DIR) + if build: + GypNinjaBuild_NaCl(GYPBUILD_DIR) + GypNinjaBuild_Breakpad(GYPBUILD_DIR + '-x64') + + if set(toolchains) & set(['glibc', 'newlib']): + GypNinjaBuild_PPAPI('ia32', GYPBUILD_DIR + '-ia32') + GypNinjaBuild_PPAPI('x64', GYPBUILD_DIR + '-x64') + + if 'arm' in toolchains: + GypNinjaBuild_PPAPI('arm', GYPBUILD_DIR + '-arm') + + if 'pnacl' in toolchains: + # NOTE: For ia32, gyp builds both x86-32 and x86-64 by default. + for arch in ('ia32', 'arm'): + # Fill in the latest native pnacl shim library from the chrome build. + build_dir = GYPBUILD_DIR + '-pnacl-' + arch + GypNinjaBuild_Pnacl(build_dir, arch) + + GypNinjaInstall(pepperdir, toolchains) platform = getos.GetPlatform() newlibdir = os.path.join(pepperdir, 'toolchain', platform + '_x86_newlib') @@ -579,15 +596,6 @@ pnacldir = os.path.join(pepperdir, 'toolchain', platform + '_pnacl') bionicdir = os.path.join(pepperdir, 'toolchain', platform + '_arm_bionic') - if set(toolchains) & set(['glibc', 'newlib']): - GypNinjaBuild_PPAPI('ia32', GYPBUILD_DIR) - GypNinjaBuild_PPAPI('x64', GYPBUILD_DIR) - - if 'arm' in toolchains: - GypNinjaBuild_PPAPI('arm', GYPBUILD_DIR + '-arm') - - GypNinjaInstall(pepperdir, toolchains) - if 'newlib' in toolchains: InstallNaClHeaders(GetToolchainNaClInclude('newlib', newlibdir, 'x86'), 'newlib') @@ -609,7 +617,6 @@ for arch in ('ia32', 'arm'): # Fill in the latest native pnacl shim library from the chrome build. build_dir = GYPBUILD_DIR + '-pnacl-' + arch - GypNinjaBuild_Pnacl(build_dir, arch) if arch == 'ia32': nacl_arches = ['x86-32', 'x86-64'] elif arch == 'arm': @@ -924,6 +931,8 @@ dest='build_experimental') parser.add_argument('--skip-toolchain', help='Skip toolchain untar', action='store_true') + parser.add_argument('--no-clean', dest='clean', action='store_false', + help="Don't clean gypbuild directories") parser.add_argument('--mac-sdk', help='Set the mac-sdk (e.g. 10.6) to use when building with ninja.') parser.add_argument('--no-arm-trusted', action='store_true', @@ -1025,7 +1034,9 @@ else: BuildStepUntarToolchains(pepperdir, toolchains) - BuildStepBuildToolchains(pepperdir, toolchains) + BuildStepBuildToolchains(pepperdir, toolchains, + not options.skip_toolchain, + options.clean) BuildStepUpdateHelpers(pepperdir, True) BuildStepUpdateUserProjects(pepperdir, toolchains,
diff --git a/native_client_sdk/src/build_tools/json/naclsdk_manifest0.json b/native_client_sdk/src/build_tools/json/naclsdk_manifest0.json index e9f7101d..1a169474 100644 --- a/native_client_sdk/src/build_tools/json/naclsdk_manifest0.json +++ b/native_client_sdk/src/build_tools/json/naclsdk_manifest0.json
@@ -4,17 +4,17 @@ "archives": [ { "checksum": { - "sha1": "a4f63d8a724d472edcdc98dfab703ec7d2acd269" + "sha1": "3c63a6002dea894616292bb25d6b375dba0290f1" }, "host_os": "all", - "size": 29758, - "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/trunk.313258/sdk_tools.tgz" + "size": 30527, + "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/trunk.314836/sdk_tools.tgz" } ], - "description": "Native Client SDK Tools, revision 313258", + "description": "Native Client SDK Tools, revision 314836", "name": "sdk_tools", "recommended": "yes", - "revision": 313258, + "revision": 314836, "stability": "stable", "version": 1 }
diff --git a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json index fcb846c5..e44e11a 100644 --- a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json +++ b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
@@ -4,17 +4,17 @@ "archives": [ { "checksum": { - "sha1": "a4f63d8a724d472edcdc98dfab703ec7d2acd269" + "sha1": "3c63a6002dea894616292bb25d6b375dba0290f1" }, "host_os": "all", - "size": 29758, - "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/trunk.313258/sdk_tools.tgz" + "size": 30527, + "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/trunk.314836/sdk_tools.tgz" } ], - "description": "Native Client SDK Tools, revision 313258", + "description": "Native Client SDK Tools, revision 314836", "name": "sdk_tools", "recommended": "yes", - "revision": 313258, + "revision": 314836, "stability": "stable", "version": 1 },
diff --git a/native_client_sdk/src/build_tools/parse_dsc.py b/native_client_sdk/src/build_tools/parse_dsc.py index 5047469b..18cc722 100755 --- a/native_client_sdk/src/build_tools/parse_dsc.py +++ b/native_client_sdk/src/build_tools/parse_dsc.py
@@ -28,7 +28,7 @@ # Don't generate the additional files to allow this project to run as a # packaged app (i.e. manifest.json, background.js, etc.). 'NO_PACKAGE_FILES': (bool, [True, False], False), - 'TOOLS' : (list, VALID_TOOLCHAINS, True), + 'TOOLS' : (list, VALID_TOOLCHAINS, False), 'CONFIGS' : (list, ['Debug', 'Release'], False), 'PREREQ' : (list, '', False), 'TARGETS' : (list, { @@ -167,6 +167,7 @@ return None ValidateFormat(desc, DSC_FORMAT) desc['FILEPATH'] = os.path.abspath(filename) + desc.setdefault('TOOLS', VALID_TOOLCHAINS) return desc
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list index 9c5c75f9..7098987 100644 --- a/native_client_sdk/src/build_tools/sdk_files.list +++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -46,9 +46,9 @@ examples/tutorial/dlopen/* examples/tutorial/filesystem_passing/* examples/tutorial/load_progress/* -examples/tutorial/multi_platform/* [win]examples/tutorial/make.bat examples/tutorial/Makefile +examples/tutorial/multi_platform/* examples/tutorial/testing/* examples/tutorial/using_ppapi_simple/* [win]getting_started/make.bat @@ -204,6 +204,18 @@ lib/glibc_x86_64/Release/libppapi_simple.so lib/glibc_x86_64/Release/libsdk_util.a lib/glibc_x86_64/Release/libsdk_util.so +[mac]lib/mac_host/Debug/libgmock.a +[mac]lib/mac_host/Debug/libgtest.a +[mac]lib/mac_host/Debug/libppapi_cpp.a +[mac]lib/mac_host/Debug/libppapi_cpp_private.a +[mac]lib/mac_host/Debug/libppapi_gles2.a +[mac]lib/mac_host/Debug/libsdk_util.a +[mac]lib/mac_host/Release/libgmock.a +[mac]lib/mac_host/Release/libgtest.a +[mac]lib/mac_host/Release/libppapi_cpp.a +[mac]lib/mac_host/Release/libppapi_cpp_private.a +[mac]lib/mac_host/Release/libppapi_gles2.a +[mac]lib/mac_host/Release/libsdk_util.a lib/newlib_arm/Debug/liberror_handling.a lib/newlib_arm/Debug/libgmock.a lib/newlib_arm/Debug/libgtest.a
diff --git a/native_client_sdk/src/build_tools/sdk_tools/third_party/fancy_urllib/__init__.py b/native_client_sdk/src/build_tools/sdk_tools/third_party/fancy_urllib/__init__.py index dfbad4d..d4e7b276 100644 --- a/native_client_sdk/src/build_tools/sdk_tools/third_party/fancy_urllib/__init__.py +++ b/native_client_sdk/src/build_tools/sdk_tools/third_party/fancy_urllib/__init__.py
@@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software # Foundation; All Rights Reserved @@ -14,13 +12,12 @@ import base64 import httplib import logging -import re import socket -import urllib2 - +from urllib import splitpasswd from urllib import splittype from urllib import splituser -from urllib import splitpasswd +import urllib2 + class InvalidCertificateException(httplib.HTTPException): """Raised when a certificate is provided with an invalid hostname.""" @@ -31,6 +28,7 @@ Args: host: The hostname the connection was made to. cert: The SSL certificate (as a dictionary) the host returned. + reason: user readable error reason. """ httplib.HTTPException.__init__(self) self.host = host @@ -38,21 +36,35 @@ self.reason = reason def __str__(self): - return ('Host %s returned an invalid certificate (%s): %s\n' - 'To learn more, see ' - 'http://code.google.com/appengine/kb/general.html#rpcssl' % + return ("Host %s returned an invalid certificate (%s): %s\n" + "To learn more, see " + "http://code.google.com/appengine/kb/general.html#rpcssl" % (self.host, self.reason, self.cert)) + +try: + import ssl + _CAN_VALIDATE_CERTS = True +except ImportError: + _CAN_VALIDATE_CERTS = False + + def can_validate_certs(): """Return True if we have the SSL package and can validate certificates.""" - try: - import ssl - return True - except ImportError: - return False + return _CAN_VALIDATE_CERTS -def _create_fancy_connection(tunnel_host=None, key_file=None, - cert_file=None, ca_certs=None): + +# Reexport SSLError so clients don't have to to do their own checking for ssl's +# existence. +if can_validate_certs(): + SSLError = ssl.SSLError +else: + SSLError = None + + +def create_fancy_connection(tunnel_host=None, key_file=None, + cert_file=None, ca_certs=None, + proxy_authorization=None): # This abomination brought to you by the fact that # the HTTPHandler creates the connection instance in the middle # of do_open so we need to add the tunnel host to the class. @@ -70,28 +82,64 @@ self.key_file = key_file self.cert_file = cert_file self.ca_certs = ca_certs - try: - import ssl + if can_validate_certs(): if self.ca_certs: self.cert_reqs = ssl.CERT_REQUIRED else: self.cert_reqs = ssl.CERT_NONE - except ImportError: - pass + + def _get_hostport(self, host, port): + # Python 2.7.7rc1 (hg r90728:568041fd8090), 3.4.1 and 3.5 rename + # _set_hostport to _get_hostport and changes it's functionality. The + # Python 2.7.7rc1 version of this method is included here for + # compatibility with earlier versions of Python. Without this, HTTPS over + # HTTP CONNECT proxies cannot be used. + + # This method may be removed if compatibility with Python <2.7.7rc1 is not + # required. + + # Python bug: http://bugs.python.org/issue7776 + if port is None: + i = host.rfind(":") + j = host.rfind("]") # ipv6 addresses have [...] + if i > j: + try: + port = int(host[i+1:]) + except ValueError: + if host[i+1:] == "": # http://foo.com:/ == http://foo.com/ + port = self.default_port + else: + raise httplib.InvalidURL("nonnumeric port: '%s'" % host[i+1:]) + host = host[:i] + else: + port = self.default_port + if host and host[0] == "[" and host[-1] == "]": + host = host[1:-1] + + return (host, port) def _tunnel(self): - self._set_hostport(self._tunnel_host, None) + self.host, self.port = self._get_hostport(self._tunnel_host, None) logging.info("Connecting through tunnel to: %s:%d", self.host, self.port) - self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self.host, self.port)) + + self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port)) + + if proxy_authorization: + self.send("Proxy-Authorization: %s\r\n" % proxy_authorization) + + # blank line + self.send("\r\n") + response = self.response_class(self.sock, strict=self.strict, method=self._method) + # pylint: disable=protected-access (_, code, message) = response._read_status() if code != 200: self.close() - raise socket.error, "Tunnel connection failed: %d %s" % ( - code, message.strip()) + raise socket.error("Tunnel connection failed: %d %s" % + (code, message.strip())) while True: line = response.fp.readline() @@ -106,15 +154,15 @@ Returns: list: A list of valid host globs. """ - if 'subjectAltName' in cert: - return [x[1] for x in cert['subjectAltName'] if x[0].lower() == 'dns'] + if "subjectAltName" in cert: + return [x[1] for x in cert["subjectAltName"] if x[0].lower() == "dns"] else: # Return a list of commonName fields - return [x[0][1] for x in cert['subject'] - if x[0][0].lower() == 'commonname'] + return [x[0][1] for x in cert["subject"] + if x[0][0].lower() == "commonname"] def _validate_certificate_hostname(self, cert, hostname): - """Validates that a given hostname is valid for an SSL certificate. + """Perform RFC2818/6125 validation against a cert and hostname. Args: cert: A dictionary representing an SSL certificate. @@ -124,14 +172,19 @@ """ hosts = self._get_valid_hosts_for_cert(cert) for host in hosts: - # Convert the glob-style hostname expression (eg, '*.google.com') into a - # valid regular expression. - host_re = host.replace('.', '\.').replace('*', '[^.]*') - if re.search('^%s$' % (host_re,), hostname, re.I): + # Wildcards are only valid when the * exists at the end of the last + # (left-most) label, and there are at least 3 labels in the expression. + if ("*." in host and host.count("*") == 1 and + host.count(".") > 1 and "." in hostname): + left_expected, right_expected = host.split("*.") + left_hostname, right_hostname = hostname.split(".", 1) + if (left_hostname.startswith(left_expected) and + right_expected == right_hostname): + return True + elif host == hostname: return True return False - def connect(self): # TODO(frew): When we drop support for <2.6 (in the far distant future), # change this to socket.create_connection. @@ -141,9 +194,11 @@ self._tunnel() # ssl and FakeSocket got deprecated. Try for the new hotness of wrap_ssl, - # with fallback. - try: - import ssl + # with fallback. Note: Since can_validate_certs() just checks for the + # ssl module, it's equivalent to attempting to import ssl from + # the function, but doesn't require a dynamic import, which doesn't + # play nicely with dev_appserver. + if can_validate_certs(): self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file, certfile=self.cert_file, @@ -152,15 +207,15 @@ if self.cert_reqs & ssl.CERT_REQUIRED: cert = self.sock.getpeercert() - hostname = self.host.split(':', 0)[0] + hostname = self.host.split(":", 0)[0] if not self._validate_certificate_hostname(cert, hostname): raise InvalidCertificateException(hostname, cert, - 'hostname mismatch') - except ImportError: - ssl = socket.ssl(self.sock, - keyfile=self.key_file, - certfile=self.cert_file) - self.sock = httplib.FakeSocket(self.sock, ssl) + "hostname mismatch") + else: + ssl_socket = socket.ssl(self.sock, + keyfile=self.key_file, + certfile=self.cert_file) + self.sock = httplib.FakeSocket(self.sock, ssl_socket) return PresetProxyHTTPSConnection @@ -330,15 +385,22 @@ """An HTTPSHandler that works with CONNECT-enabled proxies.""" def do_open(self, http_class, req, **kwargs): + proxy_authorization = None + for header in req.headers: + if header.lower() == "proxy-authorization": + proxy_authorization = req.headers[header] + break + # Intentionally very specific so as to opt for false negatives # rather than false positives. try: return urllib2.HTTPSHandler.do_open( self, - _create_fancy_connection(req._tunnel_host, - req._key_file, - req._cert_file, - req._ca_certs), + create_fancy_connection(req._tunnel_host, + req._key_file, + req._cert_file, + req._ca_certs, + proxy_authorization), req, **kwargs) except urllib2.URLError, url_error: @@ -348,7 +410,7 @@ url_error.reason.args[0] == 1): # Display the reason to the user. Need to use args for python2.5 # compat. - raise InvalidCertificateException(req.host, '', + raise InvalidCertificateException(req.host, "", url_error.reason.args[1]) except ImportError: pass
diff --git a/native_client_sdk/src/doc/c-api-beta.rst b/native_client_sdk/src/doc/c-api-beta.rst index fea4584..cf32ab7 100644 --- a/native_client_sdk/src/doc/c-api-beta.rst +++ b/native_client_sdk/src/doc/c-api-beta.rst
@@ -7,8 +7,8 @@ Pepper C API Reference (Beta) ########################################## -This page lists the C API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher. +This page lists the C API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher. `Interfaces <pepper_beta/c/group___interfaces.html>`__ ============================================================= @@ -108,13 +108,13 @@ * `PPB_OpenGLES2VertexArrayObject <pepper_beta/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html>`__ - * `PPB_TCPSocket <pepper_beta/c/struct_p_p_b___t_c_p_socket__1__1.html>`__ + * `PPB_TCPSocket <pepper_beta/c/struct_p_p_b___t_c_p_socket__1__2.html>`__ * `PPB_TextInputController <pepper_beta/c/struct_p_p_b___text_input_controller__1__0.html>`__ * `PPB_TouchInputEvent <pepper_beta/c/struct_p_p_b___touch_input_event__1__0.html>`__ - * `PPB_UDPSocket <pepper_beta/c/struct_p_p_b___u_d_p_socket__1__0.html>`__ + * `PPB_UDPSocket <pepper_beta/c/struct_p_p_b___u_d_p_socket__1__1.html>`__ * `PPB_URLLoader <pepper_beta/c/struct_p_p_b___u_r_l_loader__1__0.html>`__ @@ -130,7 +130,7 @@ * `PPB_VarDictionary <pepper_beta/c/struct_p_p_b___var_dictionary__1__0.html>`__ - * `PPB_VideoDecoder <pepper_beta/c/struct_p_p_b___video_decoder__0__2.html>`__ + * `PPB_VideoDecoder <pepper_beta/c/struct_p_p_b___video_decoder__1__0.html>`__ * `PPB_VideoFrame <pepper_beta/c/struct_p_p_b___video_frame__0__1.html>`__ @@ -201,6 +201,8 @@ * `PP_VideoPicture <pepper_beta/c/struct_p_p___video_picture.html>`__ + * `PP_VideoPicture <pepper_beta/c/struct_p_p___video_picture__0__1.html>`__ + * `PP_VarValue <pepper_beta/c/union_p_p___var_value.html>`__ @@ -359,3 +361,4 @@ * `ppp_messaging.h <pepper_beta/c/ppp__messaging_8h.html>`__ * `ppp_mouse_lock.h <pepper_beta/c/ppp__mouse__lock_8h.html>`__ +
diff --git a/native_client_sdk/src/doc/c-api-dev.rst b/native_client_sdk/src/doc/c-api-dev.rst index 4d47a58..41f5886 100644 --- a/native_client_sdk/src/doc/c-api-dev.rst +++ b/native_client_sdk/src/doc/c-api-dev.rst
@@ -7,8 +7,8 @@ Pepper C API Reference (Dev) ########################################## -This page lists the C API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher. +This page lists the C API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher. `Interfaces <pepper_dev/c/group___interfaces.html>`__ ============================================================= @@ -108,13 +108,13 @@ * `PPB_OpenGLES2VertexArrayObject <pepper_dev/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html>`__ - * `PPB_TCPSocket <pepper_dev/c/struct_p_p_b___t_c_p_socket__1__1.html>`__ + * `PPB_TCPSocket <pepper_dev/c/struct_p_p_b___t_c_p_socket__1__2.html>`__ * `PPB_TextInputController <pepper_dev/c/struct_p_p_b___text_input_controller__1__0.html>`__ * `PPB_TouchInputEvent <pepper_dev/c/struct_p_p_b___touch_input_event__1__0.html>`__ - * `PPB_UDPSocket <pepper_dev/c/struct_p_p_b___u_d_p_socket__1__0.html>`__ + * `PPB_UDPSocket <pepper_dev/c/struct_p_p_b___u_d_p_socket__1__1.html>`__ * `PPB_URLLoader <pepper_dev/c/struct_p_p_b___u_r_l_loader__1__0.html>`__ @@ -130,7 +130,7 @@ * `PPB_VarDictionary <pepper_dev/c/struct_p_p_b___var_dictionary__1__0.html>`__ - * `PPB_VideoDecoder <pepper_dev/c/struct_p_p_b___video_decoder__0__2.html>`__ + * `PPB_VideoDecoder <pepper_dev/c/struct_p_p_b___video_decoder__1__0.html>`__ * `PPB_VideoFrame <pepper_dev/c/struct_p_p_b___video_frame__0__1.html>`__ @@ -201,6 +201,8 @@ * `PP_VideoPicture <pepper_dev/c/struct_p_p___video_picture.html>`__ + * `PP_VideoPicture <pepper_dev/c/struct_p_p___video_picture__0__1.html>`__ + * `PP_VarValue <pepper_dev/c/union_p_p___var_value.html>`__ @@ -359,3 +361,4 @@ * `ppp_messaging.h <pepper_dev/c/ppp__messaging_8h.html>`__ * `ppp_mouse_lock.h <pepper_dev/c/ppp__mouse__lock_8h.html>`__ +
diff --git a/native_client_sdk/src/doc/c-api.rst b/native_client_sdk/src/doc/c-api.rst index 44ab8782..1844cfa 100644 --- a/native_client_sdk/src/doc/c-api.rst +++ b/native_client_sdk/src/doc/c-api.rst
@@ -7,8 +7,8 @@ Pepper C API Reference (Stable) ########################################## -This page lists the C API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher. +This page lists the C API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher. `Interfaces <pepper_stable/c/group___interfaces.html>`__ ============================================================= @@ -60,7 +60,7 @@ * `PPB_MessageLoop <pepper_stable/c/struct_p_p_b___message_loop__1__0.html>`__ - * `PPB_Messaging <pepper_stable/c/struct_p_p_b___messaging__1__0.html>`__ + * `PPB_Messaging <pepper_stable/c/struct_p_p_b___messaging__1__2.html>`__ * `PPB_MouseCursor <pepper_stable/c/struct_p_p_b___mouse_cursor__1__0.html>`__ @@ -76,6 +76,38 @@ * `PPB_NetworkProxy <pepper_stable/c/struct_p_p_b___network_proxy__1__0.html>`__ + * `PPB_OpenGLES2 <pepper_stable/c/struct_p_p_b___open_g_l_e_s2.html>`__ + + * `PPB_OpenGLES2 <pepper_stable/c/struct_p_p_b___open_g_l_e_s2__1__0.html>`__ + + * `PPB_OpenGLES2ChromiumEnableFeature <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature.html>`__ + + * `PPB_OpenGLES2ChromiumEnableFeature <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_enable_feature__1__0.html>`__ + + * `PPB_OpenGLES2ChromiumMapSub <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub.html>`__ + + * `PPB_OpenGLES2ChromiumMapSub <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_chromium_map_sub__1__0.html>`__ + + * `PPB_OpenGLES2FramebufferBlit <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit.html>`__ + + * `PPB_OpenGLES2FramebufferBlit <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_blit__1__0.html>`__ + + * `PPB_OpenGLES2FramebufferMultisample <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample.html>`__ + + * `PPB_OpenGLES2FramebufferMultisample <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_framebuffer_multisample__1__0.html>`__ + + * `PPB_OpenGLES2InstancedArrays <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays.html>`__ + + * `PPB_OpenGLES2InstancedArrays <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_instanced_arrays__1__0.html>`__ + + * `PPB_OpenGLES2Query <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query.html>`__ + + * `PPB_OpenGLES2Query <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_query__1__0.html>`__ + + * `PPB_OpenGLES2VertexArrayObject <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object.html>`__ + + * `PPB_OpenGLES2VertexArrayObject <pepper_stable/c/struct_p_p_b___open_g_l_e_s2_vertex_array_object__1__0.html>`__ + * `PPB_TCPSocket <pepper_stable/c/struct_p_p_b___t_c_p_socket__1__1.html>`__ * `PPB_TextInputController <pepper_stable/c/struct_p_p_b___text_input_controller__1__0.html>`__ @@ -98,7 +130,7 @@ * `PPB_VarDictionary <pepper_stable/c/struct_p_p_b___var_dictionary__1__0.html>`__ - * `PPB_VideoDecoder <pepper_stable/c/struct_p_p_b___video_decoder__0__1.html>`__ + * `PPB_VideoDecoder <pepper_stable/c/struct_p_p_b___video_decoder__1__0.html>`__ * `PPB_VideoFrame <pepper_stable/c/struct_p_p_b___video_frame__0__1.html>`__ @@ -114,6 +146,8 @@ * `PPP_Instance <pepper_stable/c/struct_p_p_p___instance__1__1.html>`__ + * `PPP_MessageHandler <pepper_stable/c/struct_p_p_p___message_handler__0__2.html>`__ + * `PPP_Messaging <pepper_stable/c/struct_p_p_p___messaging__1__0.html>`__ * `PPP_MouseLock <pepper_stable/c/struct_p_p_p___mouse_lock__1__0.html>`__ @@ -167,6 +201,8 @@ * `PP_VideoPicture <pepper_stable/c/struct_p_p___video_picture.html>`__ + * `PP_VideoPicture <pepper_stable/c/struct_p_p___video_picture__0__1.html>`__ + * `PP_VarValue <pepper_stable/c/union_p_p___var_value.html>`__ @@ -282,6 +318,8 @@ * `ppb_network_proxy.h <pepper_stable/c/ppb__network__proxy_8h.html>`__ + * `ppb_opengles2.h <pepper_stable/c/ppb__opengles2_8h.html>`__ + * `ppb_tcp_socket.h <pepper_stable/c/ppb__tcp__socket_8h.html>`__ * `ppb_text_input_controller.h <pepper_stable/c/ppb__text__input__controller_8h.html>`__ @@ -318,6 +356,8 @@ * `ppp_instance.h <pepper_stable/c/ppp__instance_8h.html>`__ + * `ppp_message_handler.h <pepper_stable/c/ppp__message__handler_8h.html>`__ + * `ppp_messaging.h <pepper_stable/c/ppp__messaging_8h.html>`__ * `ppp_mouse_lock.h <pepper_stable/c/ppp__mouse__lock_8h.html>`__
diff --git a/native_client_sdk/src/doc/cpp-api-beta.rst b/native_client_sdk/src/doc/cpp-api-beta.rst index d7363d36..ded3e2f5 100644 --- a/native_client_sdk/src/doc/cpp-api-beta.rst +++ b/native_client_sdk/src/doc/cpp-api-beta.rst
@@ -7,8 +7,8 @@ Pepper C++ API Reference (Beta) ############################################ -This page lists the C++ API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher. +This page lists the C++ API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher. `Classes <pepper_beta/cpp/inherits.html>`__ ================================================== @@ -248,3 +248,4 @@ * `view.h <pepper_beta/cpp/view_8h.html>`__ * `websocket.h <pepper_beta/cpp/websocket_8h.html>`__ +
diff --git a/native_client_sdk/src/doc/cpp-api-dev.rst b/native_client_sdk/src/doc/cpp-api-dev.rst index 4c2b165..cf678d8 100644 --- a/native_client_sdk/src/doc/cpp-api-dev.rst +++ b/native_client_sdk/src/doc/cpp-api-dev.rst
@@ -7,8 +7,8 @@ Pepper C++ API Reference (Dev) ############################################ -This page lists the C++ API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher. +This page lists the C++ API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher. `Classes <pepper_dev/cpp/inherits.html>`__ ================================================== @@ -248,3 +248,4 @@ * `view.h <pepper_dev/cpp/view_8h.html>`__ * `websocket.h <pepper_dev/cpp/websocket_8h.html>`__ +
diff --git a/native_client_sdk/src/doc/cpp-api.rst b/native_client_sdk/src/doc/cpp-api.rst index f8970fb8..3e13ab3b 100644 --- a/native_client_sdk/src/doc/cpp-api.rst +++ b/native_client_sdk/src/doc/cpp-api.rst
@@ -7,8 +7,8 @@ Pepper C++ API Reference (Stable) ############################################ -This page lists the C++ API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher. +This page lists the C++ API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher. `Classes <pepper_stable/cpp/inherits.html>`__ ==================================================
diff --git a/native_client_sdk/src/doc/pepper_beta/index.rst b/native_client_sdk/src/doc/pepper_beta/index.rst index d540576d..8752eb1 100644 --- a/native_client_sdk/src/doc/pepper_beta/index.rst +++ b/native_client_sdk/src/doc/pepper_beta/index.rst
@@ -9,8 +9,8 @@ Pepper API Reference (Beta) ######################################## -This page lists the API for Pepper 39. Apps that use this API can -run in Chrome 39 or higher. +This page lists the API for Pepper 41. Apps that use this API can +run in Chrome 41 or higher. :ref:`Pepper C API Reference <pepper_beta_c_index>` ===========================================================
diff --git a/native_client_sdk/src/doc/pepper_dev/index.rst b/native_client_sdk/src/doc/pepper_dev/index.rst index 4f6e118..4269e59 100644 --- a/native_client_sdk/src/doc/pepper_dev/index.rst +++ b/native_client_sdk/src/doc/pepper_dev/index.rst
@@ -9,8 +9,8 @@ Pepper API Reference (Dev) ######################################## -This page lists the API for Pepper 40. Apps that use this API can -run in Chrome 40 or higher. +This page lists the API for Pepper 42. Apps that use this API can +run in Chrome 42 or higher. :ref:`Pepper C API Reference <pepper_dev_c_index>` ===========================================================
diff --git a/native_client_sdk/src/doc/pepper_stable/index.rst b/native_client_sdk/src/doc/pepper_stable/index.rst index fc0bc0f..158fac42 100644 --- a/native_client_sdk/src/doc/pepper_stable/index.rst +++ b/native_client_sdk/src/doc/pepper_stable/index.rst
@@ -9,8 +9,8 @@ Pepper API Reference (Stable) ######################################## -This page lists the API for Pepper 38. Apps that use this API can -run in Chrome 38 or higher. +This page lists the API for Pepper 40. Apps that use this API can +run in Chrome 40 or higher. :ref:`Pepper C API Reference <pepper_stable_c_index>` ===========================================================
diff --git a/native_client_sdk/src/getting_started/part2/example.dsc b/native_client_sdk/src/getting_started/part2/example.dsc index faf9957..bcbc7fc 100644 --- a/native_client_sdk/src/getting_started/part2/example.dsc +++ b/native_client_sdk/src/getting_started/part2/example.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['newlib', 'glibc', 'pnacl', 'win', 'linux'], # Don't copy the packaged app files: manifest.json, etc. 'NO_PACKAGE_FILES': True, 'TARGETS': [
diff --git a/native_client_sdk/src/libraries/gmock/library.dsc b/native_client_sdk/src/libraries/gmock/library.dsc index 8b685a5..cb98d31 100644 --- a/native_client_sdk/src/libraries/gmock/library.dsc +++ b/native_client_sdk/src/libraries/gmock/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['bionic', 'newlib', 'glibc', 'pnacl', 'linux', 'win'], 'SEARCH': [ '../../../../testing/gmock/include/gmock', '../../../../testing/gmock/include/gmock/internal',
diff --git a/native_client_sdk/src/libraries/gtest/library.dsc b/native_client_sdk/src/libraries/gtest/library.dsc index ce91ad3dd..82249ef8 100644 --- a/native_client_sdk/src/libraries/gtest/library.dsc +++ b/native_client_sdk/src/libraries/gtest/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['bionic', 'newlib', 'glibc', 'pnacl', 'win', 'linux'], 'SEARCH': [ '.', '../../../../testing/gtest/include/gtest', @@ -24,7 +23,6 @@ # See comment below about gtest-internal-inl.h '$(NACL_SDK_ROOT)/include/gtest/internal', ], - 'CXXFLAGS': ['-Wno-unused-const-variable'], } ], 'HEADERS': [
diff --git a/native_client_sdk/src/libraries/ppapi/library.dsc b/native_client_sdk/src/libraries/ppapi/library.dsc index cdafc89..1b035bbd 100644 --- a/native_client_sdk/src/libraries/ppapi/library.dsc +++ b/native_client_sdk/src/libraries/ppapi/library.dsc
@@ -62,6 +62,7 @@ 'ppb_var_dictionary.h', 'ppb_var.h', 'ppb_video_decoder.h', + 'ppb_video_encoder.h', 'ppb_video_frame.h', 'ppb_view.h', 'ppb_websocket.h',
diff --git a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc index a72b23d1..353c50e 100644 --- a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc +++ b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['newlib', 'glibc', 'bionic', 'pnacl', 'win', 'linux'], 'SEARCH': [ '../../../../ppapi/cpp', '../../../../ppapi/cpp/dev', @@ -58,6 +57,7 @@ 'var.cc', 'var_dictionary.cc', 'video_decoder.cc', + 'video_encoder.cc', 'video_frame.cc', 'view.cc', 'websocket.cc', @@ -143,6 +143,7 @@ 'var_dictionary.h', 'var.h', 'video_decoder.h', + 'video_encoder.h', 'video_frame.h', 'view.h', 'websocket.h',
diff --git a/native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc b/native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc index 33e64e24..402e642 100644 --- a/native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc +++ b/native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['newlib', 'glibc', 'bionic', 'pnacl', 'win', 'linux'], 'SEARCH': [ '../../../../ppapi/c/private', '../../../../ppapi/cpp/private',
diff --git a/native_client_sdk/src/libraries/ppapi_gles2/library.dsc b/native_client_sdk/src/libraries/ppapi_gles2/library.dsc index aaf19c9..1714f233 100644 --- a/native_client_sdk/src/libraries/ppapi_gles2/library.dsc +++ b/native_client_sdk/src/libraries/ppapi_gles2/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['newlib', 'glibc', 'bionic', 'pnacl', 'linux', 'win'], 'SEARCH' : [ '../../../../ppapi/lib/gl/gles2', '../../../../ppapi/lib/gl/include/EGL',
diff --git a/native_client_sdk/src/libraries/sdk_util/library.dsc b/native_client_sdk/src/libraries/sdk_util/library.dsc index 1ec8b3c0..7d3f3318 100644 --- a/native_client_sdk/src/libraries/sdk_util/library.dsc +++ b/native_client_sdk/src/libraries/sdk_util/library.dsc
@@ -1,5 +1,4 @@ { - 'TOOLS': ['newlib', 'glibc', 'bionic', 'pnacl', 'win', 'linux'], 'TARGETS': [ { 'NAME' : 'sdk_util',
diff --git a/native_client_sdk/src/tools/common.mk b/native_client_sdk/src/tools/common.mk index c2ed4945..61717e9 100644 --- a/native_client_sdk/src/tools/common.mk +++ b/native_client_sdk/src/tools/common.mk
@@ -326,11 +326,11 @@ # so that calls to assert(3) are not included in the build. # ifeq ($(CONFIG),Release) -POSIX_FLAGS ?= -g -O2 -pthread -MMD -DNDEBUG +POSIX_CFLAGS ?= -g -O2 -pthread -MMD -DNDEBUG NACL_LDFLAGS ?= -O2 PNACL_LDFLAGS ?= -O2 else -POSIX_FLAGS ?= -g -O0 -pthread -MMD -DNACL_SDK_DEBUG +POSIX_CFLAGS ?= -g -O0 -pthread -MMD -DNACL_SDK_DEBUG endif NACL_CFLAGS ?= -Wno-long-long -Werror
diff --git a/native_client_sdk/src/tools/host_gcc.mk b/native_client_sdk/src/tools/host_gcc.mk index 18160ea..7d71de3 100644 --- a/native_client_sdk/src/tools/host_gcc.mk +++ b/native_client_sdk/src/tools/host_gcc.mk
@@ -17,14 +17,23 @@ CC ?= $(NACL_COMPILER_PREFIX) gcc CXX ?= $(NACL_COMPILER_PREFIX) g++ LINK ?= $(CXX) -LIB ?= ar +AR ?= ar +ARFLAGS = -crs STRIP ?= strip + +ifneq ($(OSNAME),mac) # Adding -Wl,-Bsymbolic means that symbols defined within the module are always -# used by the moulde, and not shadowed by symbols already loaded in, for +# used by the module, and not shadowed by symbols already loaded in, for # exmaple, libc. Without this the libc symbols (or anything injected with # LD_PRELOAD will take precedence). -HOST_LDFLAGS ?= -Wl,-Map,$(OUTDIR)/$(TARGET).map -Wl,-Bsymbolic +# -pthread is not needed on mac (libpthread is a symlink to libSystem) and +# in fact generated a warning if passed at link time. +HOST_LDFLAGS ?= -Wl,-Map,$(OUTDIR)/$(TARGET).map -Wl,-Bsymbolic -pthread +else +HOST_LDFLAGS ?= -Wl,-map -Wl,$(OUTDIR)/$(TARGET).map +endif + ifeq (,$(findstring gcc,$(shell $(WHICH) gcc))) $(warning To skip the host build use:) @@ -45,14 +54,14 @@ define C_COMPILER_RULE -include $(call SRC_TO_DEP,$(1)) $(call SRC_TO_OBJ,$(1)): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(CC) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(HOST_CFLAGS) $(2)) + $(call LOG,CC ,$$@,$(CC) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(HOST_CFLAGS) $(2)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1)) endef define CXX_COMPILER_RULE -include $(call SRC_TO_DEP,$(1)) $(call SRC_TO_OBJ,$(1)): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(CXX) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(HOST_CFLAGS) $(2)) + $(call LOG,CXX ,$$@,$(CXX) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(HOST_CFLAGS) $(2)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1)) endef @@ -99,7 +108,7 @@ $(LIBDIR)/$(OSNAME)_host/$(CONFIG)/lib$(1).a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src))) $(MKDIR) -p $$(dir $$@) $(RM) -f $$@ - $(call LOG,LIB,$$@,$(LIB) -cr $$@ $$^) + $(call LOG,LIB,$$@,$(AR) $(ARFLAGS) $$@ $$^) endef @@ -117,13 +126,13 @@ define LINKER_RULE all: $(1) $(1): $(2) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp) - $(call LOG,LINK,$$@,$(LINK) -o $(1) $(2) $(HOST_LDFLAGS) $(NACL_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(OSNAME)_host)/$(CONFIG) $(foreach lib,$(3),-l$(lib)) $(6)) + $(call LOG,LINK,$$@,$(LINK) -o $(1) $(2) $(HOST_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(OSNAME)_host)/$(CONFIG) $(foreach lib,$(3),-l$(lib)) $(6)) endef else define LINKER_RULE all: $(1) $(1): $(2) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp) - $(call LOG,LINK,$$@,$(LINK) -shared -o $(1) $(2) $(HOST_LDFLAGS) $(NACL_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(OSNAME)_host)/$(CONFIG) $(foreach lib,$(3),-l$(lib)) $(6)) + $(call LOG,LINK,$$@,$(LINK) -shared -o $(1) $(2) $(HOST_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(OSNAME)_host)/$(CONFIG) $(foreach lib,$(3),-l$(lib)) $(6)) endef endif @@ -147,8 +156,8 @@ # # Strip Macro -# The host build makes shared libraries, so the best we can do is strip-debug. -# We cannot strip the symbol names. +# The host build makes shared libraries, so the best we can do is -S, which +# only strip debug symbols. We don't strip the symbol names. # # $1 = Target Name # $2 = Input Name @@ -156,7 +165,7 @@ define STRIP_RULE all: $(OUTDIR)/$(1)$(HOST_EXT) $(OUTDIR)/$(1)$(HOST_EXT): $(OUTDIR)/$(2)$(HOST_EXT) - $(call LOG,STRIP,$$@,$(STRIP) --strip-debug -o $$@ $$^) + $(call LOG,STRIP,$$@,$(STRIP) -S -o $$@ $$^) endef
diff --git a/native_client_sdk/src/tools/nacl_gcc.mk b/native_client_sdk/src/tools/nacl_gcc.mk index 9f7c478..1b0d984d 100644 --- a/native_client_sdk/src/tools/nacl_gcc.mk +++ b/native_client_sdk/src/tools/nacl_gcc.mk
@@ -96,64 +96,64 @@ define C_COMPILER_RULE -include $(call SRC_TO_DEP,$(1),_x86_32) $(call SRC_TO_OBJ,$(1),_x86_32): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(X86_32_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_32_CFLAGS)) + $(call LOG,CC ,$$@,$(X86_32_CC) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(X86_32_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_32) -include $(call SRC_TO_DEP,$(1),_x86_64) $(call SRC_TO_OBJ,$(1),_x86_64): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(X86_64_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_64_CFLAGS)) + $(call LOG,CC ,$$@,$(X86_64_CC) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(X86_64_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_64) -include $(call SRC_TO_DEP,$(1),_arm) $(call SRC_TO_OBJ,$(1),_arm): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(ARM_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(ARM_CFLAGS)) + $(call LOG,CC ,$$@,$(ARM_CC) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(ARM_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_arm) -include $(call SRC_TO_DEP,$(1),_x86_32_pic) $(call SRC_TO_OBJ,$(1),_x86_32_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(X86_32_CC) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_32_CFLAGS)) + $(call LOG,CC ,$$@,$(X86_32_CC) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(X86_32_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_32_pic) -include $(call SRC_TO_DEP,$(1),_x86_64_pic) $(call SRC_TO_OBJ,$(1),_x86_64_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(X86_64_CC) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_64_CFLAGS)) + $(call LOG,CC ,$$@,$(X86_64_CC) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(X86_64_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_64_pic) -include $(call SRC_TO_DEP,$(1),_arm_pic) $(call SRC_TO_OBJ,$(1),_arm_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(ARM_CC) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(ARM_CFLAGS)) + $(call LOG,CC ,$$@,$(ARM_CC) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS) $(ARM_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_arm_pic) endef define CXX_COMPILER_RULE -include $(call SRC_TO_DEP,$(1),_x86_32) $(call SRC_TO_OBJ,$(1),_x86_32): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(X86_32_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_32_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(X86_32_CXX) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(X86_32_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_32) -include $(call SRC_TO_DEP,$(1),_x86_64) $(call SRC_TO_OBJ,$(1),_x86_64): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(X86_64_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_64_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(X86_64_CXX) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(X86_64_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_64) -include $(call SRC_TO_DEP,$(1),_arm) $(call SRC_TO_OBJ,$(1),_arm): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(ARM_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(ARM_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(ARM_CXX) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(ARM_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_arm) -include $(call SRC_TO_DEP,$(1),_x86_32_pic) $(call SRC_TO_OBJ,$(1),_x86_32_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(X86_32_CXX) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_32_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(X86_32_CXX) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(X86_32_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_32_pic) -include $(call SRC_TO_DEP,$(1),_x86_64_pic) $(call SRC_TO_OBJ,$(1),_x86_64_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(X86_64_CXX) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_64_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(X86_64_CXX) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(X86_64_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_x86_64_pic) -include $(call SRC_TO_DEP,$(1),_arm_pic) $(call SRC_TO_OBJ,$(1),_arm_pic): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(ARM_CXX) -o $$@ -c $$< -fPIC $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(ARM_CXXFLAGS)) + $(call LOG,CXX ,$$@,$(ARM_CXX) -o $$@ -c $$< -fPIC $(POSIX_CFLAGS) $(2) $(NACL_CXXFLAGS) $(ARM_CXXFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1),_arm_pic) endef
diff --git a/native_client_sdk/src/tools/nacl_llvm.mk b/native_client_sdk/src/tools/nacl_llvm.mk index c46b4d2..e1ce7df 100644 --- a/native_client_sdk/src/tools/nacl_llvm.mk +++ b/native_client_sdk/src/tools/nacl_llvm.mk
@@ -28,14 +28,14 @@ define C_COMPILER_RULE -include $(call SRC_TO_DEP,$(1)) $(call SRC_TO_OBJ,$(1)): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC ,$$@,$(PNACL_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS)) + $(call LOG,CC ,$$@,$(PNACL_CC) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1)) endef define CXX_COMPILER_RULE -include $(call SRC_TO_DEP,$(1)) $(call SRC_TO_OBJ,$(1)): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX ,$$@,$(PNACL_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS)) + $(call LOG,CXX ,$$@,$(PNACL_CXX) -o $$@ -c $$< $(POSIX_CFLAGS) $(2) $(NACL_CFLAGS)) @$(FIXDEPS) $(call SRC_TO_DEP_PRE_FIXUP,$(1)) endef
diff --git a/net/android/network_change_notifier_android.cc b/net/android/network_change_notifier_android.cc index 0a109b8..d1ad338a 100644 --- a/net/android/network_change_notifier_android.cc +++ b/net/android/network_change_notifier_android.cc
@@ -77,20 +77,16 @@ // We're only interested in tunnel interface changes. base::Bind(NotifyNetworkChangeNotifierObservers)) {} - virtual ~DnsConfigServiceThread() { - Stop(); - } + ~DnsConfigServiceThread() override { Stop(); } - virtual void Init() override { + void Init() override { address_tracker_.Init(); dns_config_service_ = DnsConfigService::CreateSystemService(); dns_config_service_->WatchConfig( base::Bind(&NetworkChangeNotifier::SetDnsConfig)); } - virtual void CleanUp() override { - dns_config_service_.reset(); - } + void CleanUp() override { dns_config_service_.reset(); } static void NotifyNetworkChangeNotifierObservers() { NetworkChangeNotifier::NotifyObserversOfIPAddressChange();
diff --git a/net/android/network_change_notifier_android.h b/net/android/network_change_notifier_android.h index 0d90a56..f6d43d0 100644 --- a/net/android/network_change_notifier_android.h +++ b/net/android/network_change_notifier_android.h
@@ -42,17 +42,17 @@ : public NetworkChangeNotifier, public NetworkChangeNotifierDelegateAndroid::Observer { public: - virtual ~NetworkChangeNotifierAndroid(); + ~NetworkChangeNotifierAndroid() override; // NetworkChangeNotifier: - virtual ConnectionType GetCurrentConnectionType() const override; + ConnectionType GetCurrentConnectionType() const override; // Requires ACCESS_WIFI_STATE permission in order to provide precise WiFi link // speed. - virtual double GetCurrentMaxBandwidth() const override; + double GetCurrentMaxBandwidth() const override; // NetworkChangeNotifierDelegateAndroid::Observer: - virtual void OnConnectionTypeChanged() override; - virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps) override; + void OnConnectionTypeChanged() override; + void OnMaxBandwidthChanged(double max_bandwidth_mbps) override; static bool Register(JNIEnv* env);
diff --git a/net/android/network_change_notifier_android_unittest.cc b/net/android/network_change_notifier_android_unittest.cc index 54e5583..83dd70e7 100644 --- a/net/android/network_change_notifier_android_unittest.cc +++ b/net/android/network_change_notifier_android_unittest.cc
@@ -25,11 +25,9 @@ : type_notifications_count_(0), max_bandwidth_notifications_count_(0) {} // NetworkChangeNotifierDelegateAndroid::Observer: - virtual void OnConnectionTypeChanged() override { - type_notifications_count_++; - } + void OnConnectionTypeChanged() override { type_notifications_count_++; } - virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps) override { + void OnMaxBandwidthChanged(double max_bandwidth_mbps) override { max_bandwidth_notifications_count_++; } @@ -49,7 +47,7 @@ NetworkChangeNotifierObserver() : notifications_count_(0) {} // NetworkChangeNotifier::Observer: - virtual void OnConnectionTypeChanged( + void OnConnectionTypeChanged( NetworkChangeNotifier::ConnectionType connection_type) override { notifications_count_++; } @@ -68,7 +66,7 @@ protected: typedef NetworkChangeNotifier::ConnectionType ConnectionType; - virtual ~BaseNetworkChangeNotifierAndroidTest() {} + ~BaseNetworkChangeNotifierAndroidTest() override {} void RunTest( const base::Callback<int(void)>& notifications_count_getter, @@ -148,7 +146,7 @@ delegate_.AddObserver(&other_delegate_observer_); } - virtual ~NetworkChangeNotifierDelegateAndroidTest() { + ~NetworkChangeNotifierDelegateAndroidTest() override { delegate_.RemoveObserver(&delegate_observer_); delegate_.RemoveObserver(&other_delegate_observer_); }
diff --git a/net/android/network_change_notifier_factory_android.h b/net/android/network_change_notifier_factory_android.h index d443fcd..035a84e81 100644 --- a/net/android/network_change_notifier_factory_android.h +++ b/net/android/network_change_notifier_factory_android.h
@@ -26,10 +26,10 @@ NetworkChangeNotifierFactoryAndroid(); // Must be called on the JNI thread. - virtual ~NetworkChangeNotifierFactoryAndroid(); + ~NetworkChangeNotifierFactoryAndroid() override; // NetworkChangeNotifierFactory: - virtual NetworkChangeNotifier* CreateInstance() override; + NetworkChangeNotifier* CreateInstance() override; private: // Delegate passed to the instances created by this class.
diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc index fc2af1b..69741e5 100644 --- a/net/base/file_stream_context.cc +++ b/net/base/file_stream_context.cc
@@ -77,12 +77,6 @@ orphaned_ = true; -#if defined(OS_WIN) - // Clean up weak pointers here to ensure that they are destroyed on the - // same thread where they were created. - weak_ptr_factory_.InvalidateWeakPtrs(); -#endif - if (!async_in_progress_) { CloseAndDelete(); } else if (file_.IsValid()) { @@ -221,7 +215,10 @@ } void FileStream::Context::CloseAndDelete() { - DCHECK(!async_in_progress_); + // TODO(ananta) + // Replace this CHECK with a DCHECK once we figure out the root cause of + // http://crbug.com/455066 + CHECK(!async_in_progress_); if (file_.IsValid()) { bool posted = task_runner_.get()->PostTask(
diff --git a/net/base/file_stream_context.h b/net/base/file_stream_context.h index 4f01d9d2..8d037bc 100644 --- a/net/base/file_stream_context.h +++ b/net/base/file_stream_context.h
@@ -161,12 +161,16 @@ DWORD bytes_read, DWORD error) override; + // Invokes the user callback. + void InvokeUserCallback(); + // The ReadFile call on Windows can execute synchonously at times. // http://support.microsoft.com/kb/156932. This ends up blocking the calling // thread which is undesirable. To avoid this we execute the ReadFile call // on a worker thread. - // The |context| parameter is a weak pointer instance passed to the worker - // pool. + // The |context| parameter is a pointer to the current Context instance. It + // is safe to pass this as is to the pool as the Context instance should + // remain valid until the pending Read operation completes. // The |file| parameter is the handle to the file being read. // The |buf| parameter is the buffer where we want the ReadFile to read the // data into. @@ -176,7 +180,7 @@ // The |origin_thread_loop| is a MessageLoopProxy instance used to post tasks // back to the originating thread. static void ReadAsync( - const base::WeakPtr<FileStream::Context>& context, + FileStream::Context* context, HANDLE file, scoped_refptr<net::IOBuffer> buf, int buf_len, @@ -185,9 +189,11 @@ // This callback executes on the main calling thread. It informs the caller // about the result of the ReadFile call. + // The |bytes_read| contains the number of bytes read from the file, if + // ReadFile succeeds. // The |os_error| parameter contains the value of the last error returned by // the ReadFile API. - void ReadAsyncResult(DWORD os_error); + void ReadAsyncResult(DWORD bytes_read, DWORD os_error); #elif defined(OS_POSIX) // ReadFileImpl() is a simple wrapper around read() that handles EINTR @@ -209,8 +215,18 @@ base::MessageLoopForIO::IOContext io_context_; CompletionCallback callback_; scoped_refptr<IOBuffer> in_flight_buf_; - // WeakPtrFactory for posting tasks back to |this|. - base::WeakPtrFactory<Context> weak_ptr_factory_; + // This flag is set to true when we receive a Read request which is queued to + // the thread pool. + bool async_read_initiated_; + // This flag is set to true when we receive a notification ReadAsyncResult() + // on the calling thread which indicates that the asynchronous Read + // operation is complete. + bool async_read_completed_; + // This flag is set to true when we receive an IO completion notification for + // an asynchonously initiated Read operaton. OnIOComplete(). + bool io_complete_for_read_received_; + // Tracks the result of the IO completion operation. Set in OnIOComplete. + int result_; #endif DISALLOW_COPY_AND_ASSIGN(Context);
diff --git a/net/base/file_stream_context_win.cc b/net/base/file_stream_context_win.cc index d225ee3..fd1289d 100644 --- a/net/base/file_stream_context_win.cc +++ b/net/base/file_stream_context_win.cc
@@ -41,7 +41,10 @@ async_in_progress_(false), orphaned_(false), task_runner_(task_runner), - weak_ptr_factory_(this) { + async_read_initiated_(false), + async_read_completed_(false), + io_complete_for_read_received_(false), + result_(0) { io_context_.handler = this; memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); } @@ -53,7 +56,10 @@ async_in_progress_(false), orphaned_(false), task_runner_(task_runner), - weak_ptr_factory_(this) { + async_read_initiated_(false), + async_read_completed_(false), + io_complete_for_read_received_(false), + result_(0) { io_context_.handler = this; memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); if (file_.IsValid()) { @@ -72,24 +78,29 @@ tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 FileStream::Context::Read")); - DCHECK(!async_in_progress_); + CHECK(!async_in_progress_); + DCHECK(!async_read_initiated_); + DCHECK(!async_read_completed_); + DCHECK(!io_complete_for_read_received_); IOCompletionIsPending(callback, buf); - base::WorkerPool::PostTask( - FROM_HERE, - base::Bind(&FileStream::Context::ReadAsync, - weak_ptr_factory_.GetWeakPtr(), file_.GetPlatformFile(), - make_scoped_refptr(buf), buf_len, &io_context_.overlapped, - base::MessageLoop::current()->message_loop_proxy()), - false); + async_read_initiated_ = true; + task_runner_->PostTask( + FROM_HERE, + base::Bind(&FileStream::Context::ReadAsync, base::Unretained(this), + file_.GetPlatformFile(), make_scoped_refptr(buf), buf_len, + &io_context_.overlapped, + base::MessageLoop::current()->message_loop_proxy())); return ERR_IO_PENDING; } int FileStream::Context::Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { + CHECK(!async_in_progress_); + DWORD bytes_written = 0; if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len, &bytes_written, &io_context_.overlapped)) { @@ -140,49 +151,72 @@ DCHECK(!callback_.is_null()); DCHECK(async_in_progress_); - async_in_progress_ = false; + if (!async_read_initiated_) + async_in_progress_ = false; + if (orphaned_) { + async_in_progress_ = false; callback_.Reset(); in_flight_buf_ = NULL; CloseAndDelete(); return; } - int result; if (error == ERROR_HANDLE_EOF) { - result = 0; + result_ = 0; } else if (error) { IOResult error_result = IOResult::FromOSError(error); - result = static_cast<int>(error_result.result); + result_ = static_cast<int>(error_result.result); } else { - result = bytes_read; + result_ = bytes_read; IncrementOffset(&io_context_.overlapped, bytes_read); } + if (async_read_initiated_) + io_complete_for_read_received_ = true; + + InvokeUserCallback(); +} + +void FileStream::Context::InvokeUserCallback() { + // For an asynchonous Read operation don't invoke the user callback until + // we receive the IO completion notification and the asynchronous Read + // completion notification. + if (async_read_initiated_) { + if (!io_complete_for_read_received_ || !async_read_completed_) + return; + async_read_initiated_ = false; + io_complete_for_read_received_ = false; + async_read_completed_ = false; + async_in_progress_ = false; + } CompletionCallback temp_callback = callback_; callback_.Reset(); scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; in_flight_buf_ = NULL; - temp_callback.Run(result); + temp_callback.Run(result_); } // static void FileStream::Context::ReadAsync( - const base::WeakPtr<FileStream::Context>& context, + FileStream::Context* context, HANDLE file, scoped_refptr<net::IOBuffer> buf, int buf_len, OVERLAPPED* overlapped, scoped_refptr<base::MessageLoopProxy> origin_thread_loop) { DWORD bytes_read = 0; - if (!ReadFile(file, buf->data(), buf_len, &bytes_read, overlapped)) { - origin_thread_loop->PostTask( - FROM_HERE, base::Bind(&FileStream::Context::ReadAsyncResult, context, - ::GetLastError())); - } + BOOL ret = ::ReadFile(file, buf->data(), buf_len, &bytes_read, overlapped); + origin_thread_loop->PostTask( + FROM_HERE, base::Bind(&FileStream::Context::ReadAsyncResult, + base::Unretained(context), ret ? bytes_read : 0, + ret ? 0 : ::GetLastError())); } -void FileStream::Context::ReadAsyncResult(DWORD os_error) { +void FileStream::Context::ReadAsyncResult(DWORD bytes_read, DWORD os_error) { + if (!os_error) + result_ = bytes_read; + IOResult error = IOResult::FromOSError(os_error); if (error.os_error == ERROR_HANDLE_EOF) { // Report EOF by returning 0 bytes read. @@ -190,10 +224,13 @@ } else if (error.os_error != ERROR_IO_PENDING) { // We don't need to inform the caller about ERROR_PENDING_IO as that was // already done when the ReadFile call was queued to the worker pool. - if (error.os_error) + if (error.os_error) { LOG(WARNING) << "ReadFile failed: " << error.os_error; - OnIOCompleted(&io_context_, 0, error.os_error); + OnIOCompleted(&io_context_, 0, error.os_error); + } } + async_read_completed_ = true; + InvokeUserCallback(); } } // namespace net
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc index a7fe9f3e..e03cb4c 100644 --- a/net/base/mime_util.cc +++ b/net/base/mime_util.cc
@@ -359,6 +359,7 @@ "audio/mp3", "audio/x-mp3", "audio/mpeg", + "audio/aac", #if defined(ENABLE_MPEG2TS_STREAM_PARSER) // MPEG-2 TS. @@ -475,9 +476,8 @@ return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; case MimeUtil::OPUS: - // TODO(vigneshv): Change this similar to the VP9 check once Opus is - // supported on Android (http://crbug.com/318436). - return false; + // Opus is supported only in Lollipop+ (API Level 21). + return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; case MimeUtil::THEORA: return false;
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc index a28c8b69..b5335b63 100644 --- a/net/base/mime_util_unittest.cc +++ b/net/base/mime_util_unittest.cc
@@ -231,6 +231,7 @@ EXPECT_TRUE(IsSupportedMediaMimeType("audio/mp3")); EXPECT_TRUE(IsSupportedMediaMimeType("audio/x-mp3")); EXPECT_TRUE(IsSupportedMediaMimeType("audio/mpeg")); + EXPECT_TRUE(IsSupportedMediaMimeType("audio/aac")); #if defined(ENABLE_MPEG2TS_STREAM_PARSER) EXPECT_TRUE(IsSupportedMediaMimeType("video/mp2t")); @@ -246,6 +247,7 @@ EXPECT_FALSE(IsSupportedMediaMimeType("audio/mp3")); EXPECT_FALSE(IsSupportedMediaMimeType("audio/x-mp3")); EXPECT_FALSE(IsSupportedMediaMimeType("audio/mpeg")); + EXPECT_FALSE(IsSupportedMediaMimeType("audio/aac")); #endif // USE_PROPRIETARY_CODECS EXPECT_FALSE(IsSupportedMediaMimeType("video/mp3"));
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc index 05125941..03cc4c0 100644 --- a/net/base/network_change_notifier_win.cc +++ b/net/base/network_change_notifier_win.cc
@@ -227,7 +227,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "NetworkChangeNotifierWin_OnObjectSignaled")); + "418183 NetworkChangeNotifierWin::OnObjectSignaled")); DCHECK(CalledOnValidThread()); DCHECK(is_watching_);
diff --git a/net/base/upload_file_element_reader.cc b/net/base/upload_file_element_reader.cc index 9be9117c..864584d 100644 --- a/net/base/upload_file_element_reader.cc +++ b/net/base/upload_file_element_reader.cc
@@ -174,12 +174,15 @@ } // If the underlying file has been changed and the expected file modification - // time is set, treat it as error. Note that the expected modification time - // from WebKit is based on time_t precision. So we have to convert both to - // time_t to compare. This check is used for sliced files. + // time is set, treat it as error. Note that |expected_modification_time_| may + // have gone through multiple conversion steps involving loss of precision + // (including conversion to time_t). Therefore the check below only verifies + // that the timestamps are within one second of each other. This check is used + // for sliced files. if (!expected_modification_time_.is_null() && - expected_modification_time_.ToTimeT() != - file_info->last_modified.ToTimeT()) { + (expected_modification_time_ - file_info->last_modified) + .magnitude() + .InSeconds() != 0) { callback.Run(ERR_UPLOAD_FILE_CHANGED); return; }
diff --git a/net/base/upload_file_element_reader_unittest.cc b/net/base/upload_file_element_reader_unittest.cc index b0374ac..719ce1e 100644 --- a/net/base/upload_file_element_reader_unittest.cc +++ b/net/base/upload_file_element_reader_unittest.cc
@@ -210,25 +210,33 @@ // Expect one second before the actual modification time to simulate change. const base::Time expected_modification_time = info.last_modified - base::TimeDelta::FromSeconds(1); - reader_.reset( - new UploadFileElementReader(base::MessageLoopProxy::current().get(), - temp_file_path_, - 0, - kuint64max, - expected_modification_time)); + reader_.reset(new UploadFileElementReader( + base::MessageLoopProxy::current().get(), temp_file_path_, 0, kuint64max, + expected_modification_time)); TestCompletionCallback init_callback; ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult()); } +TEST_F(UploadFileElementReaderTest, InexactExpectedTimeStamp) { + base::File::Info info; + ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info)); + + const base::Time expected_modification_time = + info.last_modified - base::TimeDelta::FromMilliseconds(900); + reader_.reset(new UploadFileElementReader( + base::MessageLoopProxy::current().get(), temp_file_path_, 0, kuint64max, + expected_modification_time)); + TestCompletionCallback init_callback; + ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); + EXPECT_EQ(OK, init_callback.WaitForResult()); +} + TEST_F(UploadFileElementReaderTest, WrongPath) { const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path")); reader_.reset( new UploadFileElementReader(base::MessageLoopProxy::current().get(), - wrong_path, - 0, - kuint64max, - base::Time())); + wrong_path, 0, kuint64max, base::Time())); TestCompletionCallback init_callback; ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
diff --git a/net/cert/cert_verify_proc_android.h b/net/cert/cert_verify_proc_android.h index 7002718..6830df6 100644 --- a/net/cert/cert_verify_proc_android.h +++ b/net/cert/cert_verify_proc_android.h
@@ -15,18 +15,18 @@ public: CertVerifyProcAndroid(); - virtual bool SupportsAdditionalTrustAnchors() const override; + bool SupportsAdditionalTrustAnchors() const override; protected: - virtual ~CertVerifyProcAndroid(); + ~CertVerifyProcAndroid() override; private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) override; + int VerifyInternal(X509Certificate* cert, + const std::string& hostname, + int flags, + CRLSet* crl_set, + const CertificateList& additional_trust_anchors, + CertVerifyResult* verify_result) override; }; } // namespace net
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc index 7099225..388d0fc4 100644 --- a/net/cert/cert_verify_proc_mac.cc +++ b/net/cert/cert_verify_proc_mac.cc
@@ -175,12 +175,21 @@ return noErr; } -// Saves some information about the certificate chain |cert_chain| in -// |*verify_result|. The caller MUST initialize |*verify_result| before -// calling this function. +// Stores the constructed certificate chain |cert_chain| and information about +// the signature algorithms used into |*verify_result|. If the leaf cert in +// |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that +// in |*leaf_is_weak|. void GetCertChainInfo(CFArrayRef cert_chain, CSSM_TP_APPLE_EVIDENCE_INFO* chain_info, - CertVerifyResult* verify_result) { + CertVerifyResult* verify_result, + bool* leaf_is_weak) { + *leaf_is_weak = false; + verify_result->verified_cert = nullptr; + verify_result->has_md2 = false; + verify_result->has_md4 = false; + verify_result->has_md5 = false; + verify_result->has_sha1 = false; + SecCertificateRef verified_cert = NULL; std::vector<SecCertificateRef> verified_chain; for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { @@ -223,10 +232,16 @@ const CSSM_OID* alg_oid = &sig_algorithm->algorithm; if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA)) { verify_result->has_md2 = true; + if (i == 0) + *leaf_is_weak = true; } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA)) { verify_result->has_md4 = true; + if (i == 0) + *leaf_is_weak = true; } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA)) { verify_result->has_md5 = true; + if (i == 0) + *leaf_is_weak = true; } else if (CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) || CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) || CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) || @@ -234,6 +249,8 @@ CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) || CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) { verify_result->has_sha1 = true; + if (i == 0) + *leaf_is_weak = true; } } if (!verified_cert) @@ -446,80 +463,6 @@ return OK; } -// OS X ships with both "GTE CyberTrust Global Root" and "Baltimore CyberTrust -// Root" as part of its trusted root store. However, a cross-certified version -// of the "Baltimore CyberTrust Root" exists that chains to "GTE CyberTrust -// Global Root". When OS X/Security.framework attempts to evaluate such a -// certificate chain, it disregards the "Baltimore CyberTrust Root" that exists -// within Keychain and instead attempts to terminate the chain in the "GTE -// CyberTrust Global Root". However, the GTE root is scheduled to be removed in -// a future OS X update (for sunsetting purposes), and once removed, such -// chains will fail validation, even though a trust anchor still exists. -// -// Rather than over-generalizing a solution that may mask a number of TLS -// misconfigurations, attempt to specifically match the affected -// cross-certified certificate and remove it from certificate chain processing. -bool IsBadBaltimoreGTECertificate(SecCertificateRef cert) { - // Matches the GTE-signed Baltimore CyberTrust Root - // https://cacert.omniroot.com/Baltimore-to-GTE-04-12.pem - static const SHA1HashValue kBadBaltimoreHashNew = - { { 0x4D, 0x34, 0xEA, 0x92, 0x76, 0x4B, 0x3A, 0x31, 0x49, 0x11, - 0x99, 0x52, 0xF4, 0x19, 0x30, 0xCA, 0x11, 0x34, 0x83, 0x61 } }; - // Matches the legacy GTE-signed Baltimore CyberTrust Root - // https://cacert.omniroot.com/gte-2-2025.pem - static const SHA1HashValue kBadBaltimoreHashOld = - { { 0x54, 0xD8, 0xCB, 0x49, 0x1F, 0xA1, 0x6D, 0xF8, 0x87, 0xDC, - 0x94, 0xA9, 0x34, 0xCC, 0x83, 0x6B, 0xDA, 0xA8, 0xA3, 0x69 } }; - - SHA1HashValue fingerprint = X509Certificate::CalculateFingerprint(cert); - - return fingerprint.Equals(kBadBaltimoreHashNew) || - fingerprint.Equals(kBadBaltimoreHashOld); -} - -// Attempts to re-verify |cert_array| after adjusting the inputs to work around -// known issues in OS X. To be used if BuildAndEvaluateSecTrustRef fails to -// return a positive result for verification. -// -// This function should only be called while the Mac Security Services lock is -// held. -void RetrySecTrustEvaluateWithAdjustedChain( - CFArrayRef cert_array, - CFArrayRef trust_policies, - int flags, - ScopedCFTypeRef<SecTrustRef>* trust_ref, - SecTrustResultType* trust_result, - ScopedCFTypeRef<CFArrayRef>* verified_chain, - CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) { - CFIndex count = CFArrayGetCount(*verified_chain); - CFIndex slice_point = 0; - - for (CFIndex i = 1; i < count; ++i) { - SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(*verified_chain, i))); - if (cert == NULL) - return; // Strange times; can't fix things up. - - if (IsBadBaltimoreGTECertificate(cert)) { - slice_point = i; - break; - } - } - if (slice_point == 0) - return; // Nothing to do. - - ScopedCFTypeRef<CFMutableArrayRef> adjusted_cert_array( - CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); - // Note: This excludes the certificate at |slice_point|. - CFArrayAppendArray(adjusted_cert_array, cert_array, - CFRangeMake(0, slice_point)); - - // Ignore the result; failure will preserve the old verification results. - BuildAndEvaluateSecTrustRef( - adjusted_cert_array, trust_policies, flags, trust_ref, trust_result, - verified_chain, chain_info); -} - } // namespace CertVerifyProcMac::CertVerifyProcMac() {} @@ -547,7 +490,8 @@ // array of certificates, the first of which is the certificate we're // verifying, and the subsequent (optional) certificates are used for // chain building. - ScopedCFTypeRef<CFArrayRef> cert_array(cert->CreateOSCertChainForCert()); + ScopedCFTypeRef<CFMutableArrayRef> cert_array( + cert->CreateOSCertChainForCert()); // Serialize all calls that may use the Keychain, to work around various // issues in OS X 10.6+ with multi-threaded access to Security.framework. @@ -557,17 +501,106 @@ SecTrustResultType trust_result = kSecTrustResultDeny; ScopedCFTypeRef<CFArrayRef> completed_chain; CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL; + bool candidate_untrusted = true; + bool candidate_weak = false; - int rv = BuildAndEvaluateSecTrustRef( - cert_array, trust_policies, flags, &trust_ref, &trust_result, - &completed_chain, &chain_info); - if (rv != OK) - return rv; - if (trust_result != kSecTrustResultUnspecified && - trust_result != kSecTrustResultProceed) { - RetrySecTrustEvaluateWithAdjustedChain( - cert_array, trust_policies, flags, &trust_ref, &trust_result, - &completed_chain, &chain_info); + // OS X lacks proper path discovery; it will take the input certs and never + // backtrack the graph attempting to discover valid paths. + // This can create issues in some situations: + // - When OS X changes the trust store, there may be a chain + // A -> B -> C -> D + // where OS X trusts D (on some versions) and trusts C (on some versions). + // If a server supplies a chain A, B, C (cross-signed by D), then this chain + // will successfully validate on systems that trust D, but fail for systems + // that trust C. If the server supplies a chain of A -> B, then it forces + // all clients to fetch C (via AIA) if they trust D, and not all clients + // (notably, Firefox and Android) will do this, thus breaking them. + // An example of this is the Verizon Business Services root - GTE CyberTrust + // and Baltimore CyberTrust roots represent old and new roots that cause + // issues depending on which version of OS X being used. + // + // - A server may be (misconfigured) to send an expired intermediate + // certificate. On platforms with path discovery, the graph traversal + // will back up to immediately before this intermediate, and then + // attempt an AIA fetch or retrieval from local store. However, OS X + // does not do this, and thus prevents access. While this is ostensibly + // a server misconfiguration issue, the fact that it works on other + // platforms is a jarring inconsistency for users. + // + // - When OS X trusts both C and D (simultaneously), it's possible that the + // version of C signed by D is signed using a weak algorithm (e.g. SHA-1), + // while the version of C in the trust store's signature doesn't matter. + // Since a 'strong' chain exists, it would be desirable to prefer this + // chain. + // + // - A variant of the above example, it may be that the version of B sent by + // the server is signed using a weak algorithm, but the version of B + // present in the AIA of A is signed using a strong algorithm. Since a + // 'strong' chain exists, it would be desirable to prefer this chain. + // + // Because of this, the code below first attempts to validate the peer's + // identity using the supplied chain. If it is not trusted (e.g. the OS only + // trusts C, but the version of C signed by D was sent, and D is not trusted), + // or if it contains a weak chain, it will begin lopping off certificates + // from the end of the chain and attempting to verify. If a stronger, trusted + // chain is found, it is used, otherwise, the algorithm continues until only + // the peer's certificate remains. + // + // This does cause a performance hit for these users, but only in cases where + // OS X is building weaker chains than desired, or when it would otherwise + // fail the connection. + while (CFArrayGetCount(cert_array) > 0) { + ScopedCFTypeRef<SecTrustRef> temp_ref; + SecTrustResultType temp_trust_result = kSecTrustResultDeny; + ScopedCFTypeRef<CFArrayRef> temp_chain; + CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; + + int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags, + &temp_ref, &temp_trust_result, + &temp_chain, &temp_chain_info); + if (rv != OK) + return rv; + + CertVerifyResult temp_verify_result; + bool leaf_is_weak = false; + GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result, + &leaf_is_weak); + + bool untrusted = (temp_trust_result != kSecTrustResultUnspecified && + temp_trust_result != kSecTrustResultProceed); + bool weak_chain = + !leaf_is_weak && + (temp_verify_result.has_md2 || temp_verify_result.has_md4 || + temp_verify_result.has_md5 || temp_verify_result.has_sha1); + // Set the result to the current chain if: + // - This is the first verification attempt. This ensures that if + // everything is awful (e.g. it may just be an untrusted cert), that + // what is reported is exactly what was sent by the server + // - If the current chain is trusted, and the old chain was not trusted, + // then prefer this chain. This ensures that if there is at least a + // valid path to a trust anchor, it's preferred over reporting an error. + // - If the current chain is trusted, and the old chain is trusted, but + // the old chain contained weak algorithms while the current chain only + // contains strong algorithms, then prefer the current chain over the + // old chain. + // + // Note: If the leaf certificate itself is weak, then the only + // consideration is whether or not there is a trusted chain. That's + // because no amount of path discovery will fix a weak leaf. + if (!trust_ref || (!untrusted && (candidate_untrusted || + (candidate_weak && !weak_chain)))) { + trust_ref = temp_ref; + trust_result = temp_trust_result; + completed_chain = temp_chain; + chain_info = temp_chain_info; + + candidate_untrusted = untrusted; + candidate_weak = weak_chain; + } + // Short-circuit when a current, trusted chain is found. + if (!untrusted && !weak_chain) + break; + CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1); } if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) @@ -576,7 +609,9 @@ if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set)) verify_result->cert_status |= CERT_STATUS_REVOKED; - GetCertChainInfo(completed_chain, chain_info, verify_result); + bool leaf_is_weak_unused = false; + GetCertChainInfo(completed_chain, chain_info, verify_result, + &leaf_is_weak_unused); // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h index c1a4f6de..6c0f0e9 100644 --- a/net/cert/x509_certificate.h +++ b/net/cert/x509_certificate.h
@@ -251,12 +251,12 @@ // Does this certificate's usage allow SSL client authentication? bool SupportsSSLClientAuth() const; - // Returns a new CFArrayRef containing this certificate and its intermediate - // certificates in the form expected by Security.framework and Keychain - // Services, or NULL on failure. + // Returns a new CFMutableArrayRef containing this certificate and its + // intermediate certificates in the form expected by Security.framework + // and Keychain Services, or NULL on failure. // The first item in the array will be this certificate, followed by its // intermediates, if any. - CFArrayRef CreateOSCertChainForCert() const; + CFMutableArrayRef CreateOSCertChainForCert() const; #endif // Do any of the given issuer names appear in this cert's chain of trust?
diff --git a/net/cert/x509_certificate_mac.cc b/net/cert/x509_certificate_mac.cc index f8bfe12..10cfb56 100644 --- a/net/cert/x509_certificate_mac.cc +++ b/net/cert/x509_certificate_mac.cc
@@ -449,7 +449,7 @@ return true; } -CFArrayRef X509Certificate::CreateOSCertChainForCert() const { +CFMutableArrayRef X509Certificate::CreateOSCertChainForCert() const { CFMutableArrayRef cert_list = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index f689553..c4da9e8 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -57,6 +57,7 @@ #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_proxy.h" #include "base/metrics/histogram.h" +#include "base/profiler/scoped_tracker.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -1468,6 +1469,10 @@ // We need to do this repeatedly until no more tasks were added to the queue // during the period where we release the lock. while (true) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456373 is + // fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION("456373 CookieMonster::OnKeyLoaded1")); { base::AutoLock autolock(lock_); std::map<std::string, std::deque<scoped_refptr<CookieMonsterTask> > > @@ -1484,6 +1489,10 @@ it->second.swap(tasks_pending_for_key); } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456373 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION("456373 CookieMonster::OnKeyLoaded2")); while (!tasks_pending_for_key.empty()) { scoped_refptr<CookieMonsterTask> task = tasks_pending_for_key.front(); task->Run(); @@ -1494,6 +1503,10 @@ void CookieMonster::StoreLoadedCookies( const std::vector<CanonicalCookie*>& cookies) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456373 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456373 CookieMonster::StoreLoadedCookies")); // Initialize the store and sync in any saved persistent cookies. We don't // care if it's expired, insert it so it can be garbage collected, removed, // and sync'd.
diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc index 4f6888b..135f3fd6 100644 --- a/net/dns/dns_config_service_posix.cc +++ b/net/dns/dns_config_service_posix.cc
@@ -64,7 +64,7 @@ NetworkChangeNotifier::AddNetworkChangeObserver(this); } - virtual ~DnsConfigWatcher() { + ~DnsConfigWatcher() override { NetworkChangeNotifier::RemoveNetworkChangeObserver(this); } @@ -73,8 +73,7 @@ return true; } - virtual void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) - override { + void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) override { if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE) callback_.Run(true); }
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc index b0da34e..8d0ac54 100644 --- a/net/dns/dns_config_service_win.cc +++ b/net/dns/dns_config_service_win.cc
@@ -312,7 +312,8 @@ void OnObjectSignaled() { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("RegistryWatcher_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 RegistryWatcher::OnObjectSignaled")); DCHECK(CalledOnValidThread()); DCHECK(!callback_.is_null());
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc index 2b308c7..ef6adb8b 100644 --- a/net/ftp/ftp_network_transaction.cc +++ b/net/ftp/ftp_network_transaction.cc
@@ -239,11 +239,6 @@ return OK; } -int FtpNetworkTransaction::RestartIgnoringLastError( - const CompletionCallback& callback) { - return ERR_NOT_IMPLEMENTED; -} - int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, const CompletionCallback& callback, const BoundNetLog& net_log) { @@ -1033,16 +1028,18 @@ int FtpNetworkTransaction::ProcessResponseRETR( const FtpCtrlResponse& response) { + // Resource type should be either filled in by DetectTypecode() or + // detected with CWD. RETR is sent only when the resource is a file. + DCHECK_EQ(RESOURCE_TYPE_FILE, resource_type_); + switch (GetErrorClass(response.status_code)) { case ERROR_CLASS_INITIATED: // We want the client to start reading the response at this point. // It got here either through Start or RestartWithAuth. We want that // method to complete. Not setting next state here will make DoLoop exit // and in turn make Start/RestartWithAuth complete. - resource_type_ = RESOURCE_TYPE_FILE; break; case ERROR_CLASS_OK: - resource_type_ = RESOURCE_TYPE_FILE; next_state_ = STATE_CTRL_WRITE_QUIT; break; case ERROR_CLASS_INFO_NEEDED: @@ -1056,10 +1053,6 @@ return Stop(ERR_UNEXPECTED); } - // We should be sure about our resource type now. Otherwise we risk - // an infinite loop (RETR can later send CWD, and CWD can later send RETR). - DCHECK_NE(RESOURCE_TYPE_UNKNOWN, resource_type_); - return OK; } @@ -1095,6 +1088,7 @@ break; case ERROR_CLASS_PERMANENT_ERROR: // It's possible that SIZE failed because the path is a directory. + // TODO(xunjieli): Add a test for this case. if (resource_type_ == RESOURCE_TYPE_UNKNOWN && response.status_code != 550) { return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); @@ -1104,6 +1098,9 @@ NOTREACHED(); return Stop(ERR_UNEXPECTED); } + + // If the resource is known beforehand to be a file, RETR should be issued, + // otherwise do CWD which will detect the resource type. if (resource_type_ == RESOURCE_TYPE_FILE) EstablishDataConnection(STATE_CTRL_WRITE_RETR); else @@ -1119,13 +1116,14 @@ } int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { - // We should never issue CWD if we know the target resource is a file. + // CWD should be invoked only when the resource is not a file. DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); switch (GetErrorClass(response.status_code)) { case ERROR_CLASS_INITIATED: return Stop(ERR_INVALID_RESPONSE); case ERROR_CLASS_OK: + resource_type_ = RESOURCE_TYPE_DIRECTORY; EstablishDataConnection(STATE_CTRL_WRITE_LIST); break; case ERROR_CLASS_INFO_NEEDED: @@ -1158,9 +1156,7 @@ return Stop(ERR_FILE_NOT_FOUND); } - // We are here because SIZE failed and we are not sure what the resource - // type is. It could still be file, and SIZE could fail because of - // an access error (http://crbug.com/56734). Try RETR just to be sure. + // If it is not a directory, it is probably a file. resource_type_ = RESOURCE_TYPE_FILE; EstablishDataConnection(STATE_CTRL_WRITE_RETR); @@ -1182,6 +1178,10 @@ int FtpNetworkTransaction::ProcessResponseLIST( const FtpCtrlResponse& response) { + // Resource type should be either filled in by DetectTypecode() or + // detected with CWD. LIST is sent only when the resource is a directory. + DCHECK_EQ(RESOURCE_TYPE_DIRECTORY, resource_type_); + switch (GetErrorClass(response.status_code)) { case ERROR_CLASS_INITIATED: // We want the client to start reading the response at this point.
diff --git a/net/ftp/ftp_network_transaction.h b/net/ftp/ftp_network_transaction.h index fc94ae78..6bf01bd 100644 --- a/net/ftp/ftp_network_transaction.h +++ b/net/ftp/ftp_network_transaction.h
@@ -33,8 +33,7 @@ ClientSocketFactory* socket_factory); ~FtpNetworkTransaction() override; - virtual int Stop(int error); - virtual int RestartIgnoringLastError(const CompletionCallback& callback); + int Stop(int error); // FtpTransaction methods: int Start(const FtpRequestInfo* request_info,
diff --git a/net/ftp/ftp_network_transaction_unittest.cc b/net/ftp/ftp_network_transaction_unittest.cc index ede22d3..79e1687 100644 --- a/net/ftp/ftp_network_transaction_unittest.cc +++ b/net/ftp/ftp_network_transaction_unittest.cc
@@ -918,7 +918,7 @@ TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) { FtpSocketDataProviderDirectoryListing ctrl_socket; - ExecuteTransaction(&ctrl_socket, "ftp://host;type=d", OK); + ExecuteTransaction(&ctrl_socket, "ftp://host/;type=d", OK); EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc index 6a5ee175..303e13d6 100644 --- a/net/http/disk_cache_based_quic_server_info.cc +++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -104,7 +104,10 @@ void DiskCacheBasedQuicServerInfo::CancelWaitForDataReadyCallback() { DCHECK(CalledOnValidThread()); - RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL); + // TODO(rtenneti): crbug.com/456524. Implement a better fix. During shutdown, + // HttpCache could be deleted and leads to crash because backend_ is deleted. + // Temporary weekend fix is to return without collecting data in histograms. + // RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL); if (!wait_for_ready_callback_.is_null()) { RecordLastFailure(); wait_for_ready_callback_.Reset();
diff --git a/net/http/disk_cache_based_quic_server_info_unittest.cc b/net/http/disk_cache_based_quic_server_info_unittest.cc index ef69b43..e74bc98 100644 --- a/net/http/disk_cache_based_quic_server_info_unittest.cc +++ b/net/http/disk_cache_based_quic_server_info_unittest.cc
@@ -418,6 +418,28 @@ RemoveMockTransaction(&kHostInfoTransaction1); } +TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyAfterDeleteCache) { + scoped_ptr<QuicServerInfo> quic_server_info; + { + MockHttpCache cache; + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED); + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + quic_server_info->CancelWaitForDataReadyCallback(); + EXPECT_EQ(OK, callback.GetResult(rv)); + EXPECT_TRUE(quic_server_info->IsDataReady()); + RemoveMockTransaction(&kHostInfoTransaction1); + } + // Cancel the callback after Cache is deleted. + quic_server_info->CancelWaitForDataReadyCallback(); +} + // Test Start() followed by Persist() without calling WaitForDataReady. TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) { MockHttpCache cache;
diff --git a/net/http/http_atom_list.h b/net/http/http_atom_list.h deleted file mode 100644 index 4dac9fb6..0000000 --- a/net/http/http_atom_list.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -HTTP_ATOM(ACCEPT) -HTTP_ATOM(ACCEPT_CHARSET) -HTTP_ATOM(ACCEPT_ENCODING) -HTTP_ATOM(ACCEPT_LANGUAGE) -HTTP_ATOM(ACCEPT_RANGES) -HTTP_ATOM(AGE) -HTTP_ATOM(ALLOW) -HTTP_ATOM(AUTHORIZATION) -HTTP_ATOM(CACHE_CONTROL) -HTTP_ATOM(CONNECTION) -HTTP_ATOM(CONTENT_BASE) -HTTP_ATOM(CONTENT_DISPOSITION) -HTTP_ATOM(CONTENT_ENCODING) -HTTP_ATOM(CONTENT_LANGUAGE) -HTTP_ATOM(CONTENT_LENGTH) -HTTP_ATOM(CONTENT_LOCATION) -HTTP_ATOM(CONTENT_MD5) -HTTP_ATOM(CONTENT_RANGE) -HTTP_ATOM(CONTENT_TRANSFER_ENCODING) -HTTP_ATOM(CONTENT_TYPE) -HTTP_ATOM(COOKIE) -HTTP_ATOM(DATE) -HTTP_ATOM(DERIVED_FROM) -HTTP_ATOM(ETAG) -HTTP_ATOM(EXPECT) -HTTP_ATOM(EXPIRES) -HTTP_ATOM(FORWARDED) -HTTP_ATOM(FROM) -HTTP_ATOM(HOST) -HTTP_ATOM(IF_MATCH) -HTTP_ATOM(IF_MODIFIED_SINCE) -HTTP_ATOM(IF_NONE_MATCH) -HTTP_ATOM(IF_RANGE) -HTTP_ATOM(IF_UNMODIFIED_SINCE) -HTTP_ATOM(LAST_MODIFIED) -HTTP_ATOM(LINK) -HTTP_ATOM(LOCATION) -HTTP_ATOM(MAX_FORWARDS) -HTTP_ATOM(MESSAGE_ID) -HTTP_ATOM(PRAGMA) -HTTP_ATOM(PROXY_AUTHENTICATE) -HTTP_ATOM(PROXY_AUTHORIZATION) -HTTP_ATOM(PROXY_CONNECTION) -HTTP_ATOM(RANGE) -HTTP_ATOM(REFERER) -HTTP_ATOM(REFRESH) -HTTP_ATOM(RETRY_AFTER) -HTTP_ATOM(SERVER) -HTTP_ATOM(SET_COOKIE) -HTTP_ATOM(TITLE) -HTTP_ATOM(TRANSFER_ENCODING) -HTTP_ATOM(UPGRADE) -HTTP_ATOM(USER_AGENT) -HTTP_ATOM(VARY) -HTTP_ATOM(VIA) -HTTP_ATOM(WARNING) -HTTP_ATOM(WWW_AUTHENTICATE)
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 3376051..3908d743 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -97,7 +97,7 @@ enable_user_alternate_protocol_ports(false), quic_crypto_client_stream_factory(NULL), proxy_delegate(NULL) { - quic_supported_versions.push_back(QUIC_VERSION_23); + quic_supported_versions.push_back(QUIC_VERSION_24); } HttpNetworkSession::Params::~Params() {}
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 8f33e20..69a3aa5 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -571,7 +571,8 @@ } bool HttpNetworkTransaction::UsingHttpProxyWithoutTunnel() const { - return (proxy_info_.is_http() || proxy_info_.is_https()) && + return (proxy_info_.is_http() || proxy_info_.is_https() || + proxy_info_.is_quic()) && !(request_->url.SchemeIs("https") || request_->url.SchemeIsWSOrWSS()); }
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc index 9c8a5317..b97c957c 100644 --- a/net/http/http_proxy_client_socket_pool.cc +++ b/net/http/http_proxy_client_socket_pool.cc
@@ -128,6 +128,10 @@ } void HttpProxyConnectJob::OnIOComplete(int result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455884 HttpProxyConnectJob::OnIOComplete")); int rv = DoLoop(result); if (rv != ERR_IO_PENDING) { NotifyProxyDelegateOfCompletion(rv);
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index a73b4eb1..dcb4cdc 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" +#include "net/base/net_util.h" #include "net/quic/quic_bandwidth.h" #include "net/socket/next_proto.h" #include "net/spdy/spdy_framer.h" // TODO(willchan): Reconsider this. @@ -147,7 +148,6 @@ typedef base::MRUCache< HostPortPair, AlternateProtocolInfo> AlternateProtocolMap; typedef base::MRUCache<HostPortPair, SettingsMap> SpdySettingsMap; -typedef std::map<HostPortPair, SupportsQuic> SupportsQuicMap; typedef base::MRUCache<HostPortPair, ServerNetworkStats> ServerNetworkStatsMap; extern const char kAlternateProtocolHeader[]; @@ -247,15 +247,10 @@ // Returns all persistent SPDY settings. virtual const SpdySettingsMap& spdy_settings_map() const = 0; - // TODO(rtenneti): Make SupportsQuic a global (instead of per host_port_pair). - virtual SupportsQuic GetSupportsQuic( - const HostPortPair& host_port_pair) const = 0; + virtual bool GetSupportsQuic(IPAddressNumber* last_address) const = 0; - virtual void SetSupportsQuic(const HostPortPair& host_port_pair, - bool used_quic, - const std::string& address) = 0; - - virtual const SupportsQuicMap& supports_quic_map() const = 0; + virtual void SetSupportsQuic(bool used_quic, + const IPAddressNumber& last_address) = 0; virtual void SetServerNetworkStats(const HostPortPair& host_port_pair, ServerNetworkStats stats) = 0;
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 0b6b9743..9f17afc 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc
@@ -102,12 +102,9 @@ } void HttpServerPropertiesImpl::InitializeSupportsQuic( - SupportsQuicMap* supports_quic_map) { - for (SupportsQuicMap::reverse_iterator it = supports_quic_map->rbegin(); - it != supports_quic_map->rend(); - ++it) { - supports_quic_map_.insert(std::make_pair(it->first, it->second)); - } + IPAddressNumber* last_address) { + if (last_address) + last_quic_address_ = *last_address; } void HttpServerPropertiesImpl::InitializeServerNetworkStats( @@ -164,7 +161,7 @@ alternate_protocol_map_.Clear(); canonical_host_to_origin_map_.clear(); spdy_settings_map_.Clear(); - supports_quic_map_.clear(); + last_quic_address_.clear(); server_network_stats_map_.Clear(); } @@ -321,13 +318,14 @@ it = alternate_protocol_map_.Put(server, alternate); } it->second.is_broken = true; - int count = ++broken_alternate_protocol_map_[server]; + const BrokenAlternateProtocolEntry entry(server, alternate.port, + alternate.protocol); + int count = ++broken_alternate_protocol_map_[entry]; base::TimeDelta delay = base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); - BrokenAlternateProtocolEntry entry; - entry.server = server; - entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); - broken_alternate_protocol_list_.push_back(entry); + base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); + broken_alternate_protocol_list_.push_back( + BrokenAlternateProtocolEntryWithTime(entry, when)); // Do not leave this host as canonical so that we don't infer the other // hosts are also broken without testing them first. @@ -342,12 +340,22 @@ bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( const HostPortPair& server) { - return ContainsKey(broken_alternate_protocol_map_, server); + const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); + if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) + return false; + const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, + alternate_protocol.protocol); + return ContainsKey(broken_alternate_protocol_map_, entry); } void HttpServerPropertiesImpl::ConfirmAlternateProtocol( const HostPortPair& server) { - broken_alternate_protocol_map_.erase(server); + const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); + if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) + return; + const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, + alternate_protocol.protocol); + broken_alternate_protocol_map_.erase(entry); } void HttpServerPropertiesImpl::ClearAlternateProtocol( @@ -411,26 +419,22 @@ return spdy_settings_map_; } -SupportsQuic HttpServerPropertiesImpl::GetSupportsQuic( - const HostPortPair& host_port_pair) const { - SupportsQuicMap::const_iterator it = supports_quic_map_.find(host_port_pair); - if (it == supports_quic_map_.end()) { - CR_DEFINE_STATIC_LOCAL(SupportsQuic, kEmptySupportsQuic, ()); - return kEmptySupportsQuic; +bool HttpServerPropertiesImpl::GetSupportsQuic( + IPAddressNumber* last_address) const { + if (last_quic_address_.empty()) + return false; + + *last_address = last_quic_address_; + return true; +} + +void HttpServerPropertiesImpl::SetSupportsQuic(bool used_quic, + const IPAddressNumber& address) { + if (!used_quic) { + last_quic_address_.clear(); + } else { + last_quic_address_ = address; } - return it->second; -} - -void HttpServerPropertiesImpl::SetSupportsQuic( - const HostPortPair& host_port_pair, - bool used_quic, - const std::string& address) { - SupportsQuic supports_quic(used_quic, address); - supports_quic_map_.insert(std::make_pair(host_port_pair, supports_quic)); -} - -const SupportsQuicMap& HttpServerPropertiesImpl::supports_quic_map() const { - return supports_quic_map_; } void HttpServerPropertiesImpl::SetServerNetworkStats( @@ -501,12 +505,14 @@ void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() { base::TimeTicks now = base::TimeTicks::Now(); while (!broken_alternate_protocol_list_.empty()) { - BrokenAlternateProtocolEntry entry = + BrokenAlternateProtocolEntryWithTime entry_with_time = broken_alternate_protocol_list_.front(); - if (now < entry.when) { + if (now < entry_with_time.when) { break; } + const BrokenAlternateProtocolEntry& entry = + entry_with_time.broken_alternate_protocol_entry; ClearAlternateProtocol(entry.server); broken_alternate_protocol_list_.pop_front(); }
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index 9c2a73c..5c84226 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h
@@ -5,6 +5,7 @@ #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ #define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ +#include <deque> #include <map> #include <set> #include <string> @@ -43,7 +44,7 @@ void InitializeSpdySettingsServers(SpdySettingsMap* spdy_settings_map); - void InitializeSupportsQuic(SupportsQuicMap* supports_quic_map); + void InitializeSupportsQuic(IPAddressNumber* last_address); void InitializeServerNetworkStats( ServerNetworkStatsMap* server_network_stats_map); @@ -100,12 +101,8 @@ void ClearSpdySettings(const HostPortPair& host_port_pair) override; void ClearAllSpdySettings() override; const SpdySettingsMap& spdy_settings_map() const override; - SupportsQuic GetSupportsQuic( - const HostPortPair& host_port_pair) const override; - void SetSupportsQuic(const HostPortPair& host_port_pair, - bool used_quic, - const std::string& address) override; - const SupportsQuicMap& supports_quic_map() const override; + bool GetSupportsQuic(IPAddressNumber* last_address) const override; + void SetSupportsQuic(bool used_quic, const IPAddressNumber& address) override; void SetServerNetworkStats(const HostPortPair& host_port_pair, ServerNetworkStats stats) override; const ServerNetworkStats* GetServerNetworkStats( @@ -119,16 +116,48 @@ typedef std::map<HostPortPair, HostPortPair> CanonicalHostMap; typedef std::vector<std::string> CanonicalSufficList; typedef std::set<HostPortPair> Http11ServerHostPortSet; - // List of broken host:ports and the times when they can be expired. + + // Server, port, and AlternateProtocol: an entity that can be broken. (Once + // we use AlternativeService, the same AltSvc can be broken for one server but + // not for another depending on what certificate it can offer.) struct BrokenAlternateProtocolEntry { + BrokenAlternateProtocolEntry(const BrokenAlternateProtocolEntry&) = default; + BrokenAlternateProtocolEntry(const HostPortPair& server, + uint16 port, + AlternateProtocol protocol) + : server(server), port(port), protocol(protocol) {} + + bool operator<(const BrokenAlternateProtocolEntry& other) const { + if (!server.Equals(other.server)) + return server < other.server; + if (port != other.port) + return port < other.port; + return protocol < other.protocol; + } + HostPortPair server; + uint16 port; + AlternateProtocol protocol; + }; + // BrokenAlternateProtocolEntry with expiration time. + struct BrokenAlternateProtocolEntryWithTime { + BrokenAlternateProtocolEntryWithTime( + const BrokenAlternateProtocolEntry& broken_alternate_protocol_entry, + base::TimeTicks when) + : broken_alternate_protocol_entry(broken_alternate_protocol_entry), + when(when) {} + + BrokenAlternateProtocolEntry broken_alternate_protocol_entry; base::TimeTicks when; }; - typedef std::list<BrokenAlternateProtocolEntry> + // Deque of BrokenAlternateProtocolEntryWithTime items, ordered by expiration + // time. + typedef std::deque<BrokenAlternateProtocolEntryWithTime> BrokenAlternateProtocolList; - // Map from host:port to the number of times alternate protocol has - // been marked broken. - typedef std::map<HostPortPair, int> BrokenAlternateProtocolMap; + // Map from (server, alternate protocol and port) to the number of + // times that alternate protocol has been marked broken for that server. + typedef std::map<BrokenAlternateProtocolEntry, int> + BrokenAlternateProtocolMap; // Return the iterator for |server|, or for its canonical host, or end. AlternateProtocolMap::const_iterator GetAlternateProtocolIterator( @@ -148,8 +177,8 @@ BrokenAlternateProtocolList broken_alternate_protocol_list_; BrokenAlternateProtocolMap broken_alternate_protocol_map_; + IPAddressNumber last_quic_address_; SpdySettingsMap spdy_settings_map_; - SupportsQuicMap supports_quic_map_; ServerNetworkStatsMap server_network_stats_map_; // Contains a map of servers which could share the same alternate protocol. // Map from a Canonical host/port (host is some postfix of host names) to an
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index e4d70470..d6c2c1c9 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc
@@ -680,37 +680,37 @@ TEST_F(SupportsQuicServerPropertiesTest, Initialize) { HostPortPair quic_server_google("www.google.com", 443); - // Check by initializing empty SupportsQuic. - SupportsQuicMap supports_quic_map; - impl_.InitializeSupportsQuic(&supports_quic_map); - SupportsQuic supports_quic = impl_.GetSupportsQuic(quic_server_google); - EXPECT_FALSE(supports_quic.used_quic); - EXPECT_EQ("", supports_quic.address); + // Check by initializing empty address. + IPAddressNumber initial_address; + impl_.InitializeSupportsQuic(&initial_address); - // Check by initializing with www.google.com:443. - SupportsQuic supports_quic1(true, "foo"); - supports_quic_map.insert(std::make_pair(quic_server_google, supports_quic1)); - impl_.InitializeSupportsQuic(&supports_quic_map); + IPAddressNumber address; + EXPECT_FALSE(impl_.GetSupportsQuic(&address)); + EXPECT_TRUE(address.empty()); - SupportsQuic supports_quic2 = impl_.GetSupportsQuic(quic_server_google); - EXPECT_TRUE(supports_quic2.used_quic); - EXPECT_EQ("foo", supports_quic2.address); + // Check by initializing with a valid address. + CHECK(ParseIPLiteralToNumber("127.0.0.1", &initial_address)); + impl_.InitializeSupportsQuic(&initial_address); + + EXPECT_TRUE(impl_.GetSupportsQuic(&address)); + EXPECT_EQ(initial_address, address); } TEST_F(SupportsQuicServerPropertiesTest, SetSupportsQuic) { - HostPortPair test_host_port_pair("foo", 80); - SupportsQuic supports_quic = impl_.GetSupportsQuic(test_host_port_pair); - EXPECT_FALSE(supports_quic.used_quic); - EXPECT_EQ("", supports_quic.address); - impl_.SetSupportsQuic(test_host_port_pair, true, "foo"); - SupportsQuic supports_quic1 = impl_.GetSupportsQuic(test_host_port_pair); - EXPECT_TRUE(supports_quic1.used_quic); - EXPECT_EQ("foo", supports_quic1.address); + IPAddressNumber address; + EXPECT_FALSE(impl_.GetSupportsQuic(&address)); + EXPECT_TRUE(address.empty()); + + IPAddressNumber actual_address; + CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address)); + impl_.SetSupportsQuic(true, actual_address); + + EXPECT_TRUE(impl_.GetSupportsQuic(&address)); + EXPECT_EQ(actual_address, address); impl_.Clear(); - SupportsQuic supports_quic2 = impl_.GetSupportsQuic(test_host_port_pair); - EXPECT_FALSE(supports_quic2.used_quic); - EXPECT_EQ("", supports_quic2.address); + + EXPECT_FALSE(impl_.GetSupportsQuic(&address)); } typedef HttpServerPropertiesImplTest ServerNetworkStatsServerPropertiesTest;
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc index c6783d3..d6bfb38 100644 --- a/net/http/http_server_properties_manager.cc +++ b/net/http/http_server_properties_manager.cc
@@ -276,28 +276,20 @@ return http_server_properties_impl_->spdy_settings_map(); } -SupportsQuic HttpServerPropertiesManager::GetSupportsQuic( - const HostPortPair& host_port_pair) const { +bool HttpServerPropertiesManager::GetSupportsQuic( + IPAddressNumber* last_address) const { DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); - return http_server_properties_impl_->GetSupportsQuic(host_port_pair); + return http_server_properties_impl_->GetSupportsQuic(last_address); } void HttpServerPropertiesManager::SetSupportsQuic( - const HostPortPair& host_port_pair, bool used_quic, - const std::string& address) { + const IPAddressNumber& address) { DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); - http_server_properties_impl_->SetSupportsQuic( - host_port_pair, used_quic, address); + http_server_properties_impl_->SetSupportsQuic(used_quic, address); ScheduleUpdatePrefsOnNetworkThread(); } -const SupportsQuicMap& HttpServerPropertiesManager::supports_quic_map() - const { - DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); - return http_server_properties_impl_->supports_quic_map(); -} - void HttpServerPropertiesManager::SetServerNetworkStats( const HostPortPair& host_port_pair, ServerNetworkStats stats) { @@ -366,13 +358,15 @@ return; } + IPAddressNumber* addr = new IPAddressNumber; + ReadSupportsQuic(http_server_properties_dict, addr); + // String is host/port pair of spdy server. scoped_ptr<StringVector> spdy_servers(new StringVector); scoped_ptr<SpdySettingsMap> spdy_settings_map( new SpdySettingsMap(kMaxSpdySettingsHostsToPersist)); scoped_ptr<AlternateProtocolMap> alternate_protocol_map( new AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist)); - scoped_ptr<SupportsQuicMap> supports_quic_map(new SupportsQuicMap()); scoped_ptr<ServerNetworkStatsMap> server_network_stats_map( new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist)); @@ -404,8 +398,6 @@ AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map.get()); if (!AddToAlternateProtocolMap(server, *server_pref_dict, alternate_protocol_map.get()) || - !AddToSupportsQuicMap(server, *server_pref_dict, - supports_quic_map.get()) || !AddToNetworkStatsMap(server, *server_pref_dict, server_network_stats_map.get())) { detected_corrupted_prefs = true; @@ -418,8 +410,7 @@ &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread, base::Unretained(this), base::Owned(spdy_servers.release()), base::Owned(spdy_settings_map.release()), - base::Owned(alternate_protocol_map.release()), - base::Owned(supports_quic_map.release()), + base::Owned(alternate_protocol_map.release()), base::Owned(addr), base::Owned(server_network_stats_map.release()), detected_corrupted_prefs)); } @@ -459,73 +450,86 @@ spdy_settings_map->Put(server, settings_map); } +AlternateProtocolInfo HttpServerPropertiesManager::ParseAlternateProtocolDict( + const base::DictionaryValue& alternate_protocol_dict, + const std::string& server_str) { + AlternateProtocolInfo alternate_protocol; + int port = 0; + if (!alternate_protocol_dict.GetInteger(kPortKey, &port) || + !IsPortValid(port)) { + DVLOG(1) << "Malformed AltSvc port for server: " << server_str; + return alternate_protocol; + } + alternate_protocol.port = static_cast<uint16>(port); + + double probability = 1.0; + if (alternate_protocol_dict.HasKey(kProbabilityKey) && + !alternate_protocol_dict.GetDoubleWithoutPathExpansion(kProbabilityKey, + &probability)) { + DVLOG(1) << "Malformed AltSvc probability for server: " << server_str; + return alternate_protocol; + } + alternate_protocol.probability = probability; + + std::string protocol_str; + if (!alternate_protocol_dict.GetStringWithoutPathExpansion(kProtocolKey, + &protocol_str)) { + DVLOG(1) << "Malformed AltSvc protocol string for server: " << server_str; + return alternate_protocol; + } + AlternateProtocol protocol = AlternateProtocolFromString(protocol_str); + if (!IsAlternateProtocolValid(protocol)) { + DVLOG(1) << "Invalid AltSvc protocol string for server: " << server_str; + return alternate_protocol; + } + alternate_protocol.protocol = protocol; + + return alternate_protocol; +} + bool HttpServerPropertiesManager::AddToAlternateProtocolMap( const HostPortPair& server, const base::DictionaryValue& server_pref_dict, AlternateProtocolMap* alternate_protocol_map) { // Get alternate_protocol server. DCHECK(alternate_protocol_map->Peek(server) == alternate_protocol_map->end()); - const base::DictionaryValue* port_alternate_protocol_dict = NULL; + const base::DictionaryValue* alternate_protocol_dict = NULL; if (!server_pref_dict.GetDictionaryWithoutPathExpansion( - kAlternateProtocolKey, &port_alternate_protocol_dict)) { + kAlternateProtocolKey, &alternate_protocol_dict)) { return true; } - int port = 0; - if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(kPortKey, - &port) || - !IsPortValid(port)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); + AlternateProtocolInfo alternate_protocol = + ParseAlternateProtocolDict(*alternate_protocol_dict, server.ToString()); + if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) return false; - } - std::string protocol_str; - if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion( - kProtocolKey, &protocol_str)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); - return false; - } - AlternateProtocol protocol = AlternateProtocolFromString(protocol_str); - if (!IsAlternateProtocolValid(protocol)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); - return false; - } - double probability = 1; - if (port_alternate_protocol_dict->HasKey(kProbabilityKey) && - !port_alternate_protocol_dict->GetDoubleWithoutPathExpansion( - kProbabilityKey, &probability)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); - return false; - } - - AlternateProtocolInfo port_alternate_protocol(static_cast<uint16>(port), - protocol, probability); - alternate_protocol_map->Put(server, port_alternate_protocol); + alternate_protocol_map->Put(server, alternate_protocol); return true; } -bool HttpServerPropertiesManager::AddToSupportsQuicMap( - const HostPortPair& server, - const base::DictionaryValue& server_pref_dict, - SupportsQuicMap* supports_quic_map) { - DCHECK(supports_quic_map->find(server) == supports_quic_map->end()); +bool HttpServerPropertiesManager::ReadSupportsQuic( + const base::DictionaryValue& http_server_properties_dict, + IPAddressNumber* last_quic_address) { const base::DictionaryValue* supports_quic_dict = NULL; - if (!server_pref_dict.GetDictionaryWithoutPathExpansion( + if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( kSupportsQuicKey, &supports_quic_dict)) { return true; } - bool used_quic = 0; + bool used_quic = false; if (!supports_quic_dict->GetBooleanWithoutPathExpansion(kUsedQuicKey, &used_quic)) { - DVLOG(1) << "Malformed SupportsQuic server: " << server.ToString(); + DVLOG(1) << "Malformed SupportsQuic"; return false; } + if (!used_quic) + return false; + std::string address; if (!supports_quic_dict->GetStringWithoutPathExpansion(kAddressKey, - &address)) { - DVLOG(1) << "Malformed SupportsQuic server: " << server.ToString(); + &address) || + !ParseIPLiteralToNumber(address, last_quic_address)) { + DVLOG(1) << "Malformed SupportsQuic"; return false; } - SupportsQuic supports_quic(used_quic, address); - supports_quic_map->insert(std::make_pair(server, supports_quic)); return true; } @@ -558,7 +562,7 @@ StringVector* spdy_servers, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map, bool detected_corrupted_prefs) { // Preferences have the master data because admins might have pushed new @@ -580,7 +584,7 @@ http_server_properties_impl_->InitializeAlternateProtocolServers( alternate_protocol_map); - http_server_properties_impl_->InitializeSupportsQuic(supports_quic_map); + http_server_properties_impl_->InitializeSupportsQuic(last_quic_address); http_server_properties_impl_->InitializeServerNetworkStats( server_network_stats_map); @@ -657,14 +661,6 @@ ++count; } - SupportsQuicMap* supports_quic_map = new SupportsQuicMap(); - const SupportsQuicMap& main_supports_quic_map = - http_server_properties_impl_->supports_quic_map(); - for (SupportsQuicMap::const_iterator it = main_supports_quic_map.begin(); - it != main_supports_quic_map.end(); ++it) { - supports_quic_map->insert(std::make_pair(it->first, it->second)); - } - ServerNetworkStatsMap* server_network_stats_map = new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist); const ServerNetworkStatsMap& main_server_network_stats_map = @@ -675,13 +671,15 @@ server_network_stats_map->Put(it->first, it->second); } + IPAddressNumber* last_quic_addr = new IPAddressNumber; + http_server_properties_impl_->GetSupportsQuic(last_quic_addr); // Update the preferences on the pref thread. pref_task_runner_->PostTask( FROM_HERE, base::Bind( &HttpServerPropertiesManager::UpdatePrefsOnPrefThread, pref_weak_ptr_, base::Owned(spdy_server_list), base::Owned(spdy_settings_map), - base::Owned(alternate_protocol_map), base::Owned(supports_quic_map), + base::Owned(alternate_protocol_map), base::Owned(last_quic_addr), base::Owned(server_network_stats_map), completion)); } @@ -716,7 +714,7 @@ base::ListValue* spdy_server_list, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map, const base::Closure& completion) { typedef std::map<HostPortPair, ServerPref> ServerPrefMap; @@ -754,13 +752,6 @@ server_pref_map[server].alternate_protocol = &map_it->second; } - // Add SupportsQuic servers to server_pref_map. - for (SupportsQuicMap::const_iterator map_it = supports_quic_map->begin(); - map_it != supports_quic_map->end(); ++map_it) { - const HostPortPair& server = map_it->first; - server_pref_map[server].supports_quic = &map_it->second; - } - // Add ServerNetworkStats servers to server_pref_map. for (ServerNetworkStatsMap::const_iterator map_it = server_network_stats_map->begin(); @@ -786,7 +777,6 @@ SaveSpdySettingsToServerPrefs(server_pref.settings_map, server_pref_dict); SaveAlternateProtocolToServerPrefs(server_pref.alternate_protocol, server_pref_dict); - SaveSupportsQuicToServerPrefs(server_pref.supports_quic, server_pref_dict); SaveNetworkStatsToServerPrefs(server_pref.server_network_stats, server_pref_dict); @@ -796,6 +786,9 @@ http_server_properties_dict.SetWithoutPathExpansion(kServersKey, servers_dict); SetVersion(&http_server_properties_dict, kVersionNumber); + + SaveSupportsQuicToPrefs(last_quic_address, &http_server_properties_dict); + setting_prefs_ = true; pref_service_->Set(path_, http_server_properties_dict); setting_prefs_ = false; @@ -844,18 +837,18 @@ port_alternate_protocol_dict); } -void HttpServerPropertiesManager::SaveSupportsQuicToServerPrefs( - const SupportsQuic* supports_quic, - base::DictionaryValue* server_pref_dict) { - // Save supports_quic. - if (!supports_quic) +void HttpServerPropertiesManager::SaveSupportsQuicToPrefs( + const IPAddressNumber* last_quic_address, + base::DictionaryValue* http_server_properties_dict) { + if (!last_quic_address || last_quic_address->empty()) return; base::DictionaryValue* supports_quic_dict = new base::DictionaryValue; - supports_quic_dict->SetBoolean(kUsedQuicKey, supports_quic->used_quic); - supports_quic_dict->SetString(kAddressKey, supports_quic->address); - server_pref_dict->SetWithoutPathExpansion(kSupportsQuicKey, - supports_quic_dict); + supports_quic_dict->SetBoolean(kUsedQuicKey, true); + supports_quic_dict->SetString(kAddressKey, + IPAddressToString(*last_quic_address)); + http_server_properties_dict->SetWithoutPathExpansion(kSupportsQuicKey, + supports_quic_dict); } void HttpServerPropertiesManager::SaveNetworkStatsToServerPrefs(
diff --git a/net/http/http_server_properties_manager.h b/net/http/http_server_properties_manager.h index 21d817a0..b71671a 100644 --- a/net/http/http_server_properties_manager.h +++ b/net/http/http_server_properties_manager.h
@@ -107,12 +107,9 @@ void ClearSpdySettings(const HostPortPair& host_port_pair) override; void ClearAllSpdySettings() override; const SpdySettingsMap& spdy_settings_map() const override; - SupportsQuic GetSupportsQuic( - const HostPortPair& host_port_pair) const override; - void SetSupportsQuic(const HostPortPair& host_port_pair, - bool used_quic, - const std::string& address) override; - const SupportsQuicMap& supports_quic_map() const override; + bool GetSupportsQuic(IPAddressNumber* last_address) const override; + void SetSupportsQuic(bool used_quic, + const IPAddressNumber& last_address) override; void SetServerNetworkStats(const HostPortPair& host_port_pair, ServerNetworkStats stats) override; const ServerNetworkStats* GetServerNetworkStats( @@ -144,7 +141,7 @@ std::vector<std::string>* spdy_servers, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map, bool detected_corrupted_prefs); @@ -173,22 +170,24 @@ void UpdatePrefsOnPrefThread(base::ListValue* spdy_server_list, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map, const base::Closure& completion); private: void OnHttpServerPropertiesChanged(); + bool ReadSupportsQuic(const base::DictionaryValue& server_dict, + IPAddressNumber* last_quic_address); void AddToSpdySettingsMap(const HostPortPair& server, const base::DictionaryValue& server_dict, SpdySettingsMap* spdy_settings_map); + AlternateProtocolInfo ParseAlternateProtocolDict( + const base::DictionaryValue& alternate_protocol_dict, + const std::string& server_str); bool AddToAlternateProtocolMap(const HostPortPair& server, const base::DictionaryValue& server_dict, AlternateProtocolMap* alternate_protocol_map); - bool AddToSupportsQuicMap(const HostPortPair& server, - const base::DictionaryValue& server_dict, - SupportsQuicMap* supports_quic_map); bool AddToNetworkStatsMap(const HostPortPair& server, const base::DictionaryValue& server_dict, ServerNetworkStatsMap* network_stats_map); @@ -198,12 +197,14 @@ void SaveAlternateProtocolToServerPrefs( const AlternateProtocolInfo* port_alternate_protocol, base::DictionaryValue* server_pref_dict); - void SaveSupportsQuicToServerPrefs(const SupportsQuic* supports_quic, - base::DictionaryValue* server_pref_dict); void SaveNetworkStatsToServerPrefs( const ServerNetworkStats* server_network_stats, base::DictionaryValue* server_pref_dict); + void SaveSupportsQuicToPrefs( + const IPAddressNumber* last_quic_address, + base::DictionaryValue* http_server_properties_dict); + // ----------- // Pref thread // -----------
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc index cbc2275e..f2e36499 100644 --- a/net/http/http_server_properties_manager_unittest.cc +++ b/net/http/http_server_properties_manager_unittest.cc
@@ -5,6 +5,7 @@ #include "net/http/http_server_properties_manager.h" #include "base/basictypes.h" +#include "base/json/json_writer.h" #include "base/message_loop/message_loop.h" #include "base/prefs/pref_registry_simple.h" #include "base/prefs/testing_pref_service.h" @@ -74,14 +75,14 @@ void(std::vector<std::string>* spdy_servers, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map, bool detected_corrupted_prefs)); MOCK_METHOD5(UpdatePrefsOnPref, void(base::ListValue* spdy_server_list, SpdySettingsMap* spdy_settings_map, AlternateProtocolMap* alternate_protocol_map, - SupportsQuicMap* supports_quic_map, + IPAddressNumber* last_quic_address, ServerNetworkStatsMap* server_network_stats_map)); private: @@ -169,12 +170,6 @@ server_pref_dict->SetWithoutPathExpansion("alternate_protocol", alternate_protocol); - // Set up SupportsQuic for www.google.com:80. - base::DictionaryValue* supports_quic = new base::DictionaryValue; - supports_quic->SetBoolean("used_quic", true); - supports_quic->SetString("address", "foo"); - server_pref_dict->SetWithoutPathExpansion("supports_quic", supports_quic); - // Set up ServerNetworkStats for www.google.com:80. base::DictionaryValue* stats = new base::DictionaryValue; stats->SetInteger("srtt", 10); @@ -198,12 +193,6 @@ server_pref_dict1->SetWithoutPathExpansion("alternate_protocol", alternate_protocol1); - // Set up SupportsQuic for mail.google.com:80 - base::DictionaryValue* supports_quic1 = new base::DictionaryValue; - supports_quic1->SetBoolean("used_quic", false); - supports_quic1->SetString("address", "bar"); - server_pref_dict1->SetWithoutPathExpansion("supports_quic", supports_quic1); - // Set up ServerNetworkStats for mail.google.com:80. base::DictionaryValue* stats1 = new base::DictionaryValue; stats1->SetInteger("srtt", 20); @@ -216,6 +205,11 @@ new base::DictionaryValue; HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1); http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict); + base::DictionaryValue* supports_quic = new base::DictionaryValue; + supports_quic->SetBoolean("used_quic", true); + supports_quic->SetString("address", "127.0.0.1"); + http_server_properties_dict->SetWithoutPathExpansion("supports_quic", + supports_quic); // Set the same value for kHttpServerProperties multiple times. pref_service_.SetManagedPref(kTestHttpServerProperties, @@ -246,13 +240,9 @@ EXPECT_EQ(NPN_SPDY_3_1, port_alternate_protocol.protocol); // Verify SupportsQuic. - SupportsQuic supports_quic2 = - http_server_props_manager_->GetSupportsQuic(google_server); - EXPECT_TRUE(supports_quic2.used_quic); - EXPECT_EQ("foo", supports_quic2.address); - supports_quic2 = http_server_props_manager_->GetSupportsQuic(mail_server); - EXPECT_FALSE(supports_quic2.used_quic); - EXPECT_EQ("bar", supports_quic2.address); + IPAddressNumber last_address; + EXPECT_TRUE(http_server_props_manager_->GetSupportsQuic(&last_address)); + EXPECT_EQ("127.0.0.1", IPAddressToString(last_address)); // Verify ServerNetworkStats. const ServerNetworkStats* stats2 = @@ -280,12 +270,6 @@ server_pref_dict->SetWithoutPathExpansion("alternate_protocol", alternate_protocol); - // Set up SupportsQuic for www.google.com:65536. - base::DictionaryValue* supports_quic = new base::DictionaryValue; - supports_quic->SetBoolean("used_quic", true); - supports_quic->SetString("address", "foo"); - server_pref_dict->SetWithoutPathExpansion("supports_quic", supports_quic); - // Set up ServerNetworkStats for www.google.com:65536. base::DictionaryValue* stats = new base::DictionaryValue; stats->SetInteger("srtt", 10); @@ -313,9 +297,6 @@ HostPortPair::FromString("www.google.com:65536"))); EXPECT_FALSE( HasAlternateProtocol(HostPortPair::FromString("www.google.com:65536"))); - SupportsQuic supports_quic2 = http_server_props_manager_->GetSupportsQuic( - HostPortPair::FromString("www.google.com:65536")); - EXPECT_FALSE(supports_quic2.used_quic); const ServerNetworkStats* stats1 = http_server_props_manager_->GetServerNetworkStats( HostPortPair::FromString("www.google.com:65536")); @@ -503,21 +484,19 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsQuic) { ExpectPrefsUpdate(); - HostPortPair quic_server_mail("mail.google.com", 80); - SupportsQuic supports_quic = - http_server_props_manager_->GetSupportsQuic(quic_server_mail); - EXPECT_FALSE(supports_quic.used_quic); - EXPECT_EQ("", supports_quic.address); - http_server_props_manager_->SetSupportsQuic(quic_server_mail, true, "foo"); + IPAddressNumber address; + EXPECT_FALSE(http_server_props_manager_->GetSupportsQuic(&address)); + + IPAddressNumber actual_address; + CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address)); + http_server_props_manager_->SetSupportsQuic(true, actual_address); // Run the task. base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); - SupportsQuic supports_quic1 = - http_server_props_manager_->GetSupportsQuic(quic_server_mail); - EXPECT_TRUE(supports_quic1.used_quic); - EXPECT_EQ("foo", supports_quic1.address); + EXPECT_TRUE(http_server_props_manager_->GetSupportsQuic(&address)); + EXPECT_EQ(actual_address, address); } TEST_F(HttpServerPropertiesManagerTest, ServerNetworkStats) { @@ -547,7 +526,9 @@ http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true); http_server_props_manager_->SetAlternateProtocol(spdy_server_mail, 443, NPN_SPDY_3, 1.0); - http_server_props_manager_->SetSupportsQuic(spdy_server_mail, true, "foo"); + IPAddressNumber actual_address; + CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address)); + http_server_props_manager_->SetSupportsQuic(true, actual_address); ServerNetworkStats stats; stats.srtt = base::TimeDelta::FromMicroseconds(10); http_server_props_manager_->SetServerNetworkStats(spdy_server_mail, stats); @@ -564,10 +545,9 @@ EXPECT_TRUE( http_server_props_manager_->SupportsRequestPriority(spdy_server_mail)); EXPECT_TRUE(HasAlternateProtocol(spdy_server_mail)); - SupportsQuic supports_quic = - http_server_props_manager_->GetSupportsQuic(spdy_server_mail); - EXPECT_TRUE(supports_quic.used_quic); - EXPECT_EQ("foo", supports_quic.address); + IPAddressNumber address; + EXPECT_TRUE(http_server_props_manager_->GetSupportsQuic(&address)); + EXPECT_EQ(actual_address, address); const ServerNetworkStats* stats1 = http_server_props_manager_->GetServerNetworkStats(spdy_server_mail); EXPECT_EQ(10, stats1->srtt.ToInternalValue()); @@ -593,10 +573,7 @@ EXPECT_FALSE( http_server_props_manager_->SupportsRequestPriority(spdy_server_mail)); EXPECT_FALSE(HasAlternateProtocol(spdy_server_mail)); - SupportsQuic supports_quic1 = - http_server_props_manager_->GetSupportsQuic(spdy_server_mail); - EXPECT_FALSE(supports_quic1.used_quic); - EXPECT_EQ("", supports_quic1.address); + EXPECT_FALSE(http_server_props_manager_->GetSupportsQuic(&address)); const ServerNetworkStats* stats2 = http_server_props_manager_->GetServerNetworkStats(spdy_server_mail); EXPECT_EQ(NULL, stats2); @@ -629,11 +606,6 @@ // Set the preference for mail.google.com server. base::DictionaryValue* server_pref_dict1 = new base::DictionaryValue; - // Set up SupportsQuic for mail.google.com:80 - base::DictionaryValue* supports_quic = new base::DictionaryValue; - supports_quic->SetBoolean("used_quic", true); - supports_quic->SetString("address", "bar"); - server_pref_dict1->SetWithoutPathExpansion("supports_quic", supports_quic); // Set the server preference for mail.google.com:80. servers_dict->SetWithoutPathExpansion("mail.google.com:80", @@ -644,6 +616,13 @@ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1); http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict); + // Set up SupportsQuic for 127.0.0.1 + base::DictionaryValue* supports_quic = new base::DictionaryValue; + supports_quic->SetBoolean("used_quic", true); + supports_quic->SetString("address", "127.0.0.1"); + http_server_properties_dict->SetWithoutPathExpansion("supports_quic", + supports_quic); + // Set up the pref. pref_service_.SetManagedPref(kTestHttpServerProperties, http_server_properties_dict); @@ -662,10 +641,67 @@ } // Verify SupportsQuic. - SupportsQuic supports_quic1 = http_server_props_manager_->GetSupportsQuic( - HostPortPair::FromString("mail.google.com:80")); - EXPECT_TRUE(supports_quic1.used_quic); - EXPECT_EQ("bar", supports_quic1.address); + IPAddressNumber address; + ASSERT_TRUE(http_server_props_manager_->GetSupportsQuic(&address)); + EXPECT_EQ("127.0.0.1", IPAddressToString(address)); +} + +TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { + const HostPortPair server_www("www.google.com", 80); + const HostPortPair server_mail("mail.google.com", 80); + + // Set alternate protocol. + http_server_props_manager_->SetAlternateProtocol(server_www, 443, NPN_SPDY_3, + 1.0); + http_server_props_manager_->SetAlternateProtocol(server_mail, 444, + NPN_SPDY_3_1, 0.2); + + // Set ServerNetworkStats. + ServerNetworkStats stats; + stats.srtt = base::TimeDelta::FromInternalValue(42); + http_server_props_manager_->SetServerNetworkStats(server_mail, stats); + + // Set SupportsQuic. + IPAddressNumber actual_address; + CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address)); + http_server_props_manager_->SetSupportsQuic(true, actual_address); + + // Update cache. + ExpectPrefsUpdate(); + ExpectCacheUpdate(); + http_server_props_manager_->ScheduleUpdateCacheOnPrefThread(); + base::RunLoop().RunUntilIdle(); + + // Verify preferences. + const char expected_json[] = "{" + "\"servers\":{" + "\"mail.google.com:80\":{" + "\"alternate_protocol\":{" + "\"port\":444,\"probability\":0.2,\"protocol_str\":\"npn-spdy/3.1\"" + "}," + "\"network_stats\":{" + "\"srtt\":42" + "}" + "}," + "\"www.google.com:80\":{" + "\"alternate_protocol\":{" + "\"port\":443,\"probability\":1.0,\"protocol_str\":\"npn-spdy/3\"" + "}" + "}" + "}," + "\"supports_quic\":{" + "\"address\":\"127.0.0.1\",\"used_quic\":true" + "}," + "\"version\":3" + "}"; + + const base::Value* http_server_properties = + pref_service_.GetUserPref(kTestHttpServerProperties); + ASSERT_NE(nullptr, http_server_properties); + std::string preferences_json; + EXPECT_TRUE( + base::JSONWriter::Write(http_server_properties, &preferences_json)); + EXPECT_EQ(expected_json, preferences_json); } TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 78238b94..235122d 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -24,11 +24,10 @@ GURL UpgradeUrlToHttps(const GURL& original_url, int port) { GURL::Replacements replacements; - // new_sheme and new_port need to be in scope here because GURL::Replacements - // references the memory contained by them directly. - const std::string new_scheme = "https"; + // new_port needs to be in scope here because GURL::Replacements references + // the memory contained by it directly. const std::string new_port = base::IntToString(port); - replacements.SetSchemeStr(new_scheme); + replacements.SetSchemeStr("https"); replacements.SetPortStr(new_port); return original_url.ReplaceComponents(replacements); }
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 45a0970b..8729dfbb 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/logging.h" +#include "base/profiler/scoped_tracker.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -436,6 +437,10 @@ } void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455884 HttpStreamFactoryImpl::Job::OnIOComplete")); RunLoop(result); }
diff --git a/net/net.gyp b/net/net.gyp index 6dac5c8..cd381e02 100644 --- a/net/net.gyp +++ b/net/net.gyp
@@ -837,6 +837,7 @@ 'cookies/cookie_monster_perftest.cc', 'disk_cache/blockfile/disk_cache_perftest.cc', 'proxy/proxy_resolver_perftest.cc', + 'udp/udp_socket_perftest.cc', 'websockets/websocket_frame_perftest.cc', ], 'conditions': [
diff --git a/net/net.gypi b/net/net.gypi index 5b5a5f9..12d0a40 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -607,7 +607,6 @@ 'http/disk_cache_based_quic_server_info.h', 'http/failing_http_transaction_factory.cc', 'http/failing_http_transaction_factory.h', - 'http/http_atom_list.h', 'http/http_auth.cc', 'http/http_auth.h', 'http/http_auth_cache.cc', @@ -773,8 +772,6 @@ 'quic/congestion_control/pacing_sender.h', 'quic/congestion_control/prr_sender.cc', 'quic/congestion_control/prr_sender.h', - 'quic/congestion_control/receive_algorithm_interface.cc', - 'quic/congestion_control/receive_algorithm_interface.h', 'quic/congestion_control/rtt_stats.cc', 'quic/congestion_control/rtt_stats.h', 'quic/congestion_control/send_algorithm_interface.cc', @@ -783,8 +780,6 @@ 'quic/congestion_control/tcp_cubic_sender.h', 'quic/congestion_control/tcp_loss_algorithm.cc', 'quic/congestion_control/tcp_loss_algorithm.h', - 'quic/congestion_control/tcp_receiver.cc', - 'quic/congestion_control/tcp_receiver.h', 'quic/congestion_control/time_loss_algorithm.cc', 'quic/congestion_control/time_loss_algorithm.h', 'quic/crypto/aead_base_decrypter.h', @@ -1467,7 +1462,6 @@ 'quic/congestion_control/send_algorithm_simulator.h', 'quic/congestion_control/tcp_cubic_sender_test.cc', 'quic/congestion_control/tcp_loss_algorithm_test.cc', - 'quic/congestion_control/tcp_receiver_test.cc', 'quic/congestion_control/time_loss_algorithm_test.cc', 'quic/crypto/aes_128_gcm_12_decrypter_test.cc', 'quic/crypto/aes_128_gcm_12_encrypter_test.cc',
diff --git a/net/net_unittests.isolate b/net/net_unittests.isolate index ec515fbe..877c21e 100644 --- a/net/net_unittests.isolate +++ b/net/net_unittests.isolate
@@ -34,6 +34,13 @@ 'read_only': 1, }, }], + ['OS=="mac" and asan==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/net_unittests.dSYM/', + ], + }, + }], ['OS=="win" and (fastbuild==0 or fastbuild==1)', { 'variables': { 'files': [
diff --git a/net/proxy/polling_proxy_config_service.cc b/net/proxy/polling_proxy_config_service.cc index 611ea59..7c086db 100644 --- a/net/proxy/polling_proxy_config_service.cc +++ b/net/proxy/polling_proxy_config_service.cc
@@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop_proxy.h" #include "base/observer_list.h" +#include "base/profiler/scoped_tracker.h" #include "base/synchronization/lock.h" #include "base/threading/worker_pool.h" #include "net/proxy/proxy_config.h" @@ -113,6 +114,11 @@ // Called after the worker thread has finished retrieving a configuration. void GetConfigCompleted(const ProxyConfig& config) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455942 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455942 PollingProxyConfigService::Core::GetConfigCompleted")); DCHECK(poll_task_outstanding_); poll_task_outstanding_ = false;
diff --git a/net/proxy/proxy_config_service_android.cc b/net/proxy/proxy_config_service_android.cc index 80e3b929..503388a 100644 --- a/net/proxy/proxy_config_service_android.cc +++ b/net/proxy/proxy_config_service_android.cc
@@ -302,12 +302,12 @@ explicit JNIDelegateImpl(Delegate* delegate) : delegate_(delegate) {} // ProxyConfigServiceAndroid::JNIDelegate overrides. - virtual void ProxySettingsChangedTo(JNIEnv* env, - jobject jself, - jstring jhost, - jint jport, - jstring jpac_url, - jobjectArray jexclusion_list) override { + void ProxySettingsChangedTo(JNIEnv* env, + jobject jself, + jstring jhost, + jint jport, + jstring jpac_url, + jobjectArray jexclusion_list) override { std::string host = ConvertJavaStringToUTF8(env, jhost); std::string pac_url; if (jpac_url) @@ -318,7 +318,7 @@ delegate_->ProxySettingsChangedTo(host, jport, pac_url, exclusion_list); } - virtual void ProxySettingsChanged(JNIEnv* env, jobject self) override { + void ProxySettingsChanged(JNIEnv* env, jobject self) override { delegate_->ProxySettingsChanged(); }
diff --git a/net/proxy/proxy_config_service_android.h b/net/proxy/proxy_config_service_android.h index cb15bc5..64e6b49 100644 --- a/net/proxy/proxy_config_service_android.h +++ b/net/proxy/proxy_config_service_android.h
@@ -59,7 +59,7 @@ const scoped_refptr<base::SequencedTaskRunner>& network_task_runner, const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner); - virtual ~ProxyConfigServiceAndroid(); + ~ProxyConfigServiceAndroid() override; // Register JNI bindings. static bool Register(JNIEnv* env); @@ -71,9 +71,9 @@ // ProxyConfigService: // Called only on the network thread. - virtual void AddObserver(Observer* observer) override; - virtual void RemoveObserver(Observer* observer) override; - virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override; private: friend class ProxyConfigServiceAndroidTestBase;
diff --git a/net/proxy/proxy_config_service_android_unittest.cc b/net/proxy/proxy_config_service_android_unittest.cc index 41f2387b..2e4f7bb 100644 --- a/net/proxy/proxy_config_service_android_unittest.cc +++ b/net/proxy/proxy_config_service_android_unittest.cc
@@ -23,7 +23,7 @@ TestObserver() : availability_(ProxyConfigService::CONFIG_UNSET) {} // ProxyConfigService::Observer: - virtual void OnProxyConfigChanged( + void OnProxyConfigChanged( const ProxyConfig& config, ProxyConfigService::ConfigAvailability availability) override { config_ = config; @@ -59,17 +59,15 @@ base::Bind(&ProxyConfigServiceAndroidTestBase::GetProperty, base::Unretained(this))) {} - virtual ~ProxyConfigServiceAndroidTestBase() {} + ~ProxyConfigServiceAndroidTestBase() override {} // testing::Test: - virtual void SetUp() override { + void SetUp() override { message_loop_->RunUntilIdle(); service_.AddObserver(&observer_); } - virtual void TearDown() override { - service_.RemoveObserver(&observer_); - } + void TearDown() override { service_.RemoveObserver(&observer_); } void ClearConfiguration() { configuration_.clear();
diff --git a/net/proxy/proxy_config_service_win.cc b/net/proxy/proxy_config_service_win.cc index 6547659..df9014e9 100644 --- a/net/proxy/proxy_config_service_win.cc +++ b/net/proxy/proxy_config_service_win.cc
@@ -116,7 +116,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "ProxyConfigServiceWin_OnObjectSignaled")); + "418183 ProxyConfigServiceWin::OnObjectSignaled")); // Figure out which registry key signalled this change. RegKeyList::iterator it =
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index a62732d..bd7d825 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/profiler/scoped_tracker.h" #include "base/strings/string_util.h" #include "base/thread_task_runner_handle.h" #include "base/values.h" @@ -1479,6 +1480,10 @@ void ProxyService::OnProxyConfigChanged( const ProxyConfig& config, ProxyConfigService::ConfigAvailability availability) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455942 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455942 ProxyService::OnProxyConfigChanged")); // Retrieve the current proxy configuration from the ProxyConfigService. // If a configuration is not available yet, we will get called back later // by our ProxyConfigService::Observer once it changes.
diff --git a/net/quic/congestion_control/receive_algorithm_interface.cc b/net/quic/congestion_control/receive_algorithm_interface.cc deleted file mode 100644 index a619dd5..0000000 --- a/net/quic/congestion_control/receive_algorithm_interface.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/congestion_control/receive_algorithm_interface.h" - -#include "net/quic/congestion_control/tcp_receiver.h" - -namespace net { - -// Factory for receive side congestion control algorithm. -ReceiveAlgorithmInterface* ReceiveAlgorithmInterface::Create() { - return new TcpReceiver(); -} - -} // namespace net
diff --git a/net/quic/congestion_control/receive_algorithm_interface.h b/net/quic/congestion_control/receive_algorithm_interface.h deleted file mode 100644 index ef4fb60a0..0000000 --- a/net/quic/congestion_control/receive_algorithm_interface.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// The pure virtual class for receive side congestion algorithm. - -#ifndef NET_QUIC_CONGESTION_CONTROL_RECEIVE_ALGORITHM_INTERFACE_H_ -#define NET_QUIC_CONGESTION_CONTROL_RECEIVE_ALGORITHM_INTERFACE_H_ - -#include "base/basictypes.h" -#include "net/base/net_export.h" -#include "net/quic/quic_clock.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/quic_time.h" - -namespace net { - -class NET_EXPORT_PRIVATE ReceiveAlgorithmInterface { - public: - static ReceiveAlgorithmInterface* Create(); - - virtual ~ReceiveAlgorithmInterface() {} - - // Should be called for each incoming packet. - // bytes: is the packet size in bytes including IP headers. - // sequence_number: is the unique sequence number from the QUIC packet header. - // timestamp: is the sent timestamp from the QUIC packet header. - virtual void RecordIncomingPacket(QuicByteCount bytes, - QuicPacketSequenceNumber sequence_number, - QuicTime timestamp) = 0; -}; - -} // namespace net - -#endif // NET_QUIC_CONGESTION_CONTROL_RECEIVE_ALGORITHM_INTERFACE_H_
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc index 8df0ea8..17ca8bf 100644 --- a/net/quic/congestion_control/tcp_cubic_sender_test.cc +++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -8,8 +8,8 @@ #include "base/memory/scoped_ptr.h" #include "net/quic/congestion_control/rtt_stats.h" #include "net/quic/congestion_control/tcp_cubic_sender.h" -#include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/crypto/crypto_protocol.h" +#include "net/quic/quic_protocol.h" #include "net/quic/quic_utils.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/quic_config_peer.h" @@ -65,7 +65,6 @@ : one_ms_(QuicTime::Delta::FromMilliseconds(1)), sender_(new TcpCubicSenderPeer(&clock_, true, kMaxTcpCongestionWindow)), - receiver_(new TcpReceiver()), sequence_number_(1), acked_sequence_number_(0), bytes_in_flight_(0) { @@ -133,7 +132,6 @@ const QuicTime::Delta one_ms_; MockClock clock_; scoped_ptr<TcpCubicSenderPeer> sender_; - scoped_ptr<TcpReceiver> receiver_; QuicPacketSequenceNumber sequence_number_; QuicPacketSequenceNumber acked_sequence_number_; QuicByteCount bytes_in_flight_;
diff --git a/net/quic/congestion_control/tcp_loss_algorithm_test.cc b/net/quic/congestion_control/tcp_loss_algorithm_test.cc index bb56d88..f220511 100644 --- a/net/quic/congestion_control/tcp_loss_algorithm_test.cc +++ b/net/quic/congestion_control/tcp_loss_algorithm_test.cc
@@ -35,9 +35,9 @@ } void SendDataPacket(QuicPacketSequenceNumber sequence_number) { - packets_.push_back(QuicPacket::NewDataPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_1BYTE_SEQUENCE_NUMBER)); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_1BYTE_SEQUENCE_NUMBER)); SerializedPacket packet(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER, packets_.back(), 0, new RetransmittableFrames()); unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(), @@ -80,7 +80,7 @@ // Loss on three acks. unacked_packets_.RemoveFromInFlight(4); unacked_packets_.NackPacket(1, 3); - QuicPacketSequenceNumber lost[] = { 1 }; + QuicPacketSequenceNumber lost[] = {1}; VerifyLosses(4, lost, arraysize(lost)); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); }
diff --git a/net/quic/congestion_control/tcp_receiver.cc b/net/quic/congestion_control/tcp_receiver.cc deleted file mode 100644 index d29c711..0000000 --- a/net/quic/congestion_control/tcp_receiver.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/basictypes.h" -#include "net/quic/congestion_control/tcp_receiver.h" - -namespace net { - -// Originally 64K bytes, but increased it to 256K to support higher bitrates. -// static -const QuicByteCount TcpReceiver::kReceiveWindowTCP = 256000; - -TcpReceiver::TcpReceiver() - : receive_window_(kReceiveWindowTCP) { -} - -void TcpReceiver::RecordIncomingPacket(QuicByteCount bytes, - QuicPacketSequenceNumber sequence_number, - QuicTime timestamp) { -} - -} // namespace net
diff --git a/net/quic/congestion_control/tcp_receiver.h b/net/quic/congestion_control/tcp_receiver.h deleted file mode 100644 index 8c1658445..0000000 --- a/net/quic/congestion_control/tcp_receiver.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TCP receiver side congestion algorithm, emulates the behaviour of TCP. - -#ifndef NET_QUIC_CONGESTION_CONTROL_TCP_RECEIVER_H_ -#define NET_QUIC_CONGESTION_CONTROL_TCP_RECEIVER_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "net/base/net_export.h" -#include "net/quic/congestion_control/receive_algorithm_interface.h" -#include "net/quic/quic_clock.h" -#include "net/quic/quic_protocol.h" - -namespace net { - -class NET_EXPORT_PRIVATE TcpReceiver : public ReceiveAlgorithmInterface { - public: - TcpReceiver(); - - // Size of the (currently fixed) receive window. - static const QuicByteCount kReceiveWindowTCP; - - void RecordIncomingPacket(QuicByteCount bytes, - QuicPacketSequenceNumber sequence_number, - QuicTime timestamp) override; - - private: - QuicByteCount receive_window_; - - DISALLOW_COPY_AND_ASSIGN(TcpReceiver); -}; - -} // namespace net -#endif // NET_QUIC_CONGESTION_CONTROL_TCP_RECEIVER_H_
diff --git a/net/quic/congestion_control/tcp_receiver_test.cc b/net/quic/congestion_control/tcp_receiver_test.cc deleted file mode 100644 index 5ae1a00..0000000 --- a/net/quic/congestion_control/tcp_receiver_test.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "net/quic/congestion_control/tcp_receiver.h" -#include "net/quic/test_tools/mock_clock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { -namespace test { - -class QuicTcpReceiverTest : public ::testing::Test { - protected: - void SetUp() override { receiver_.reset(new TcpReceiver()); } - scoped_ptr<TcpReceiver> receiver_; -}; - -TEST_F(QuicTcpReceiverTest, SimpleReceiver) { - QuicTime timestamp(QuicTime::Zero()); - receiver_->RecordIncomingPacket(1, 1, timestamp); -} - -} // namespace test -} // namespace net
diff --git a/net/quic/congestion_control/time_loss_algorithm_test.cc b/net/quic/congestion_control/time_loss_algorithm_test.cc index 1e9b7e5..6412792 100644 --- a/net/quic/congestion_control/time_loss_algorithm_test.cc +++ b/net/quic/congestion_control/time_loss_algorithm_test.cc
@@ -35,9 +35,9 @@ } void SendDataPacket(QuicPacketSequenceNumber sequence_number) { - packets_.push_back(QuicPacket::NewDataPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_1BYTE_SEQUENCE_NUMBER)); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_1BYTE_SEQUENCE_NUMBER)); SerializedPacket packet(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER, packets_.back(), 0, new RetransmittableFrames()); unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(),
diff --git a/net/quic/quic_ack_notifier.cc b/net/quic/quic_ack_notifier.cc index b399a61b..48ee23df 100644 --- a/net/quic/quic_ack_notifier.cc +++ b/net/quic/quic_ack_notifier.cc
@@ -29,21 +29,18 @@ QuicAckNotifier::~QuicAckNotifier() { } -void QuicAckNotifier::AddSequenceNumber( - const QuicPacketSequenceNumber& sequence_number, - int packet_payload_size) { +void QuicAckNotifier::OnSerializedPacket() { ++unacked_packets_; - DVLOG(1) << "AckNotifier waiting for packet: " << sequence_number; } -bool QuicAckNotifier::OnAck(QuicPacketSequenceNumber sequence_number, - QuicTime::Delta delta_largest_observed) { +bool QuicAckNotifier::OnAck(QuicTime::Delta delta_largest_observed) { if (unacked_packets_ <= 0) { - LOG(DFATAL) << "Acked more packets than were tracked."; + LOG(DFATAL) << "Acked more packets than were tracked." + << " unacked_packets:" << unacked_packets_; return true; } --unacked_packets_; - if (IsEmpty()) { + if (!HasUnackedPackets()) { // We have seen all the sequence numbers we were waiting for, trigger // callback notification. delegate_->OnAckNotification(retransmitted_packet_count_, @@ -54,6 +51,16 @@ return false; } +bool QuicAckNotifier::OnPacketAbandoned() { + if (unacked_packets_ <= 0) { + LOG(DFATAL) << "Abandoned more packets than were tracked." + << " unacked_packets:" << unacked_packets_; + return true; + } + --unacked_packets_; + return unacked_packets_ == 0; +} + void QuicAckNotifier::OnPacketRetransmitted(int packet_payload_size) { ++retransmitted_packet_count_; retransmitted_byte_count_ += packet_payload_size;
diff --git a/net/quic/quic_ack_notifier.h b/net/quic/quic_ack_notifier.h index 160108e..602d86f 100644 --- a/net/quic/quic_ack_notifier.h +++ b/net/quic/quic_ack_notifier.h
@@ -40,22 +40,22 @@ explicit QuicAckNotifier(DelegateInterface* delegate); virtual ~QuicAckNotifier(); - // Register a sequence number that this AckNotifier should be interested in. - void AddSequenceNumber(const QuicPacketSequenceNumber& sequence_number, - int packet_payload_size); + // Register a serialized packet the notifier should track. + void OnSerializedPacket(); - // Called by the QuicConnection on receipt of new ACK frame, with the sequence - // number referenced by the ACK frame. - // Deletes the matching sequence number from the stored set of sequence - // numbers. If this set is now empty, call the stored delegate's - // OnAckNotification method. + // Called on receipt of new ACK frame for an unacked packet. + // Decrements the number of unacked packets and if there are none left, calls + // the stored delegate's OnAckNotification method. // - // Returns true if the provided sequence_number caused the delegate to be - // called, false otherwise. - bool OnAck(QuicPacketSequenceNumber sequence_number, - QuicTime::Delta delta_largest_observed); + // Returns true if the delegate was called, false otherwise. + bool OnAck(QuicTime::Delta delta_largest_observed); - bool IsEmpty() { return unacked_packets_ == 0; } + // Called when we've given up waiting for a sequence number, typically when + // the connection is torn down. + // Returns true if there are no more unacked packets being tracked. + bool OnPacketAbandoned(); + + bool HasUnackedPackets() const { return unacked_packets_ > 0; } // If a packet is retransmitted by the connection, it will be sent with a // different sequence number.
diff --git a/net/quic/quic_ack_notifier_manager.cc b/net/quic/quic_ack_notifier_manager.cc index 0d37752..73e3c8e1 100644 --- a/net/quic/quic_ack_notifier_manager.cc +++ b/net/quic/quic_ack_notifier_manager.cc
@@ -20,7 +20,13 @@ AckNotifierManager::AckNotifierManager() {} AckNotifierManager::~AckNotifierManager() { - STLDeleteElements(&ack_notifiers_); + for (const auto& pair : ack_notifier_map_) { + for (QuicAckNotifier* notifier : pair.second) { + if (notifier->OnPacketAbandoned()) { + delete notifier; + } + } + } } void AckNotifierManager::OnPacketAcked(QuicPacketSequenceNumber sequence_number, @@ -34,14 +40,10 @@ // One or more AckNotifiers are registered as interested in this sequence // number. Iterate through them and call OnAck on each. - AckNotifierList& ack_notifier_list = map_it->second; - for (QuicAckNotifier* ack_notifier : ack_notifier_list) { - ack_notifier->OnAck(sequence_number, delta_largest_observed); - - // If this has resulted in an empty AckNotifer, erase it. - if (ack_notifier->IsEmpty()) { + for (QuicAckNotifier* ack_notifier : map_it->second) { + if (ack_notifier->OnAck(delta_largest_observed)) { + // If this has resulted in an empty AckNotifer, erase it. delete ack_notifier; - ack_notifiers_.erase(ack_notifier); } } @@ -75,21 +77,19 @@ void AckNotifierManager::OnSerializedPacket( const SerializedPacket& serialized_packet) { if (FLAGS_quic_attach_ack_notifiers_to_packets) { - // Inform each attached AckNotifier of the packet's sequence number. + // Inform each attached AckNotifier of the packet's serialization. + AckNotifierList& notifier_list = + ack_notifier_map_[serialized_packet.sequence_number]; for (QuicAckNotifier* notifier : serialized_packet.notifiers) { if (notifier == nullptr) { LOG(DFATAL) << "AckNotifier should not be nullptr."; continue; } - notifier->AddSequenceNumber(serialized_packet.sequence_number, - serialized_packet.packet->length()); + notifier->OnSerializedPacket(); // Update the mapping in the other direction, from sequence number to // AckNotifier. - ack_notifier_map_[serialized_packet.sequence_number].push_back(notifier); - - // Take ownership of the AckNotifier. - ack_notifiers_.insert(notifier); + notifier_list.push_back(notifier); } } else { // AckNotifiers can only be attached to retransmittable frames. @@ -107,15 +107,11 @@ } QuicAckNotifier* notifier = quic_frame.stream_frame->notifier; - notifier->AddSequenceNumber(serialized_packet.sequence_number, - serialized_packet.packet->length()); + notifier->OnSerializedPacket(); // Update the mapping in the other direction, from sequence number to // AckNotifier. ack_notifier_map_[serialized_packet.sequence_number].push_back(notifier); - - // Take ownership of the AckNotifier. - ack_notifiers_.insert(notifier); } } }
diff --git a/net/quic/quic_ack_notifier_manager.h b/net/quic/quic_ack_notifier_manager.h index bf4d574..d4d97ad 100644 --- a/net/quic/quic_ack_notifier_manager.h +++ b/net/quic/quic_ack_notifier_manager.h
@@ -48,22 +48,14 @@ private: typedef std::list<QuicAckNotifier*> AckNotifierList; - typedef base::hash_set<QuicAckNotifier*> AckNotifierSet; // TODO(ianswett): Further improvement may come from changing this to a deque. typedef base::hash_map<QuicPacketSequenceNumber, AckNotifierList> AckNotifierMap; - // On every ACK frame received by the connection, all the ack_notifiers_ will - // be told which sequeunce numbers were ACKed. - // Once a given QuicAckNotifier has seen all the sequence numbers it is - // interested in, it will be deleted, and removed from this set. - // Owns the AckNotifiers in this set. - AckNotifierSet ack_notifiers_; - // Maps from sequence number to the AckNotifiers which are registered // for that sequence number. On receipt of an ACK for a given sequence // number, call OnAck for all mapped AckNotifiers. - // Does not own the AckNotifiers. + // When the last reference is removed from the map, the notifier is deleted. AckNotifierMap ack_notifier_map_; DISALLOW_COPY_AND_ASSIGN(AckNotifierManager);
diff --git a/net/quic/quic_ack_notifier_test.cc b/net/quic/quic_ack_notifier_test.cc index 21c876665..7e9d6525 100644 --- a/net/quic/quic_ack_notifier_test.cc +++ b/net/quic/quic_ack_notifier_test.cc
@@ -22,9 +22,9 @@ delegate_ = new MockAckNotifierDelegate; notifier_.reset(new QuicAckNotifier(delegate_)); - notifier_->AddSequenceNumber(26, 100); - notifier_->AddSequenceNumber(99, 20); - notifier_->AddSequenceNumber(1234, 3); + notifier_->OnSerializedPacket(); + notifier_->OnSerializedPacket(); + notifier_->OnSerializedPacket(); } MockAckNotifierDelegate* delegate_; @@ -35,17 +35,26 @@ // Should trigger callback when we receive acks for all the registered seqnums. TEST_F(QuicAckNotifierTest, TriggerCallback) { EXPECT_CALL(*delegate_, OnAckNotification(0, 0, zero_)).Times(1); - EXPECT_FALSE(notifier_->OnAck(26, zero_)); - EXPECT_FALSE(notifier_->OnAck(99, zero_)); - EXPECT_TRUE(notifier_->OnAck(1234, zero_)); + EXPECT_FALSE(notifier_->OnAck(zero_)); + EXPECT_FALSE(notifier_->OnAck(zero_)); + EXPECT_TRUE(notifier_->OnAck(zero_)); } // Should not trigger callback if we never provide all the seqnums. TEST_F(QuicAckNotifierTest, DoesNotTrigger) { // Should not trigger callback as not all packets have been seen. EXPECT_CALL(*delegate_, OnAckNotification(_, _, _)).Times(0); - EXPECT_FALSE(notifier_->OnAck(26, zero_)); - EXPECT_FALSE(notifier_->OnAck(99, zero_)); + EXPECT_FALSE(notifier_->OnAck(zero_)); + EXPECT_FALSE(notifier_->OnAck(zero_)); +} + +// Should not trigger callback if we abandon all three packets. +TEST_F(QuicAckNotifierTest, AbandonDoesNotTrigger) { + // Should not trigger callback as not all packets have been seen. + EXPECT_CALL(*delegate_, OnAckNotification(_, _, _)).Times(0); + EXPECT_FALSE(notifier_->OnPacketAbandoned()); + EXPECT_FALSE(notifier_->OnPacketAbandoned()); + EXPECT_TRUE(notifier_->OnPacketAbandoned()); } // Should trigger even after updating sequence numbers and receiving ACKs for @@ -56,9 +65,9 @@ notifier_->OnPacketRetransmitted(3); EXPECT_CALL(*delegate_, OnAckNotification(2, 20 + 3, _)).Times(1); - EXPECT_FALSE(notifier_->OnAck(26, zero_)); // original - EXPECT_FALSE(notifier_->OnAck(3000, zero_)); // updated - EXPECT_TRUE(notifier_->OnAck(3001, zero_)); // updated + EXPECT_FALSE(notifier_->OnAck(zero_)); // original + EXPECT_FALSE(notifier_->OnAck(zero_)); // updated + EXPECT_TRUE(notifier_->OnAck(zero_)); // updated } // Make sure the delegate is called with the delta time from the last ACK. @@ -68,9 +77,9 @@ const QuicTime::Delta third_delta = QuicTime::Delta::FromSeconds(10); EXPECT_CALL(*delegate_, OnAckNotification(0, 0, third_delta)).Times(1); - EXPECT_FALSE(notifier_->OnAck(26, first_delta)); - EXPECT_FALSE(notifier_->OnAck(99, second_delta)); - EXPECT_TRUE(notifier_->OnAck(1234, third_delta)); + EXPECT_FALSE(notifier_->OnAck(first_delta)); + EXPECT_FALSE(notifier_->OnAck(second_delta)); + EXPECT_TRUE(notifier_->OnAck(third_delta)); } } // namespace
diff --git a/net/quic/quic_config.cc b/net/quic/quic_config.cc index 9d0a7c9b..803ae7f51 100644 --- a/net/quic/quic_config.cc +++ b/net/quic/quic_config.cc
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "net/quic/crypto/crypto_handshake_message.h" #include "net/quic/crypto/crypto_protocol.h" -#include "net/quic/quic_flags.h" #include "net/quic/quic_utils.h" using std::min; @@ -594,9 +593,8 @@ // TODO(ianswett): Add the negotiated parameters once and iterate over all // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and // ProcessServerHello. - return congestion_feedback_.negotiated() && - idle_connection_state_lifetime_seconds_.negotiated() && - max_streams_per_connection_.negotiated(); + return idle_connection_state_lifetime_seconds_.negotiated() && + max_streams_per_connection_.negotiated(); } void QuicConfig::SetDefaults() { @@ -609,11 +607,7 @@ congestion_feedback_.set(congestion_feedback, kQBIC); idle_connection_state_lifetime_seconds_.set(kMaximumIdleTimeoutSecs, kDefaultIdleTimeoutSecs); - if (FLAGS_quic_allow_silent_close) { - silent_close_.set(1, 0); - } else { - silent_close_.set(0, 0); - } + silent_close_.set(1, 0); SetMaxStreamsPerConnection(kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection); max_time_before_crypto_handshake_ = @@ -647,10 +641,6 @@ QuicErrorCode error = QUIC_NO_ERROR; if (error == QUIC_NO_ERROR) { - error = congestion_feedback_.ProcessPeerHello( - peer_hello, hello_type, error_details); - } - if (error == QUIC_NO_ERROR) { error = idle_connection_state_lifetime_seconds_.ProcessPeerHello( peer_hello, hello_type, error_details); }
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 454a15b5..019e044 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc
@@ -291,7 +291,7 @@ if (config.negotiated()) { SetNetworkTimeouts(QuicTime::Delta::Infinite(), config.IdleConnectionStateLifetime()); - if (FLAGS_quic_allow_silent_close && config.SilentClose()) { + if (config.SilentClose()) { silent_close_enabled_ = true; } } else { @@ -969,18 +969,16 @@ } } -QuicAckFrame* QuicConnection::CreateAckFrame() { - QuicAckFrame* outgoing_ack = new QuicAckFrame(); - received_packet_manager_.UpdateReceivedPacketInfo( - outgoing_ack, clock_->ApproximateNow()); - DVLOG(1) << ENDPOINT << "Creating ack frame: " << *outgoing_ack; - return outgoing_ack; +void QuicConnection::PopulateAckFrame(QuicAckFrame* ack) { + received_packet_manager_.UpdateReceivedPacketInfo(ack, + clock_->ApproximateNow()); } -QuicStopWaitingFrame* QuicConnection::CreateStopWaitingFrame() { - QuicStopWaitingFrame stop_waiting; - UpdateStopWaiting(&stop_waiting); - return new QuicStopWaitingFrame(stop_waiting); +void QuicConnection::PopulateStopWaitingFrame( + QuicStopWaitingFrame* stop_waiting) { + stop_waiting->least_unacked = GetLeastUnacked(); + stop_waiting->entropy_hash = sent_entropy_manager_.GetCumulativeEntropy( + stop_waiting->least_unacked - 1); } bool QuicConnection::ShouldLastPacketInstigateAck() const { @@ -1123,29 +1121,22 @@ } const QuicConnectionStats& QuicConnection::GetStats() { - if (!FLAGS_quic_use_initial_rtt_for_stats) { - stats_.min_rtt_us = - sent_packet_manager_.GetRttStats()->min_rtt().ToMicroseconds(); - stats_.srtt_us = - sent_packet_manager_.GetRttStats()->smoothed_rtt().ToMicroseconds(); - } else { - const RttStats* rtt_stats = sent_packet_manager_.GetRttStats(); + const RttStats* rtt_stats = sent_packet_manager_.GetRttStats(); - // Update rtt and estimated bandwidth. - QuicTime::Delta min_rtt = rtt_stats->min_rtt(); - if (min_rtt.IsZero()) { - // If min RTT has not been set, use initial RTT instead. - min_rtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); - } - stats_.min_rtt_us = min_rtt.ToMicroseconds(); - - QuicTime::Delta srtt = rtt_stats->smoothed_rtt(); - if (srtt.IsZero()) { - // If SRTT has not been set, use initial RTT instead. - srtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); - } - stats_.srtt_us = srtt.ToMicroseconds(); + // Update rtt and estimated bandwidth. + QuicTime::Delta min_rtt = rtt_stats->min_rtt(); + if (min_rtt.IsZero()) { + // If min RTT has not been set, use initial RTT instead. + min_rtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); } + stats_.min_rtt_us = min_rtt.ToMicroseconds(); + + QuicTime::Delta srtt = rtt_stats->smoothed_rtt(); + if (srtt.IsZero()) { + // If SRTT has not been set, use initial RTT instead. + srtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); + } + stats_.srtt_us = srtt.ToMicroseconds(); stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate(); stats_.max_packet_size = packet_generator_.max_packet_length(); @@ -1403,7 +1394,8 @@ return true; } // Connection close packets are encrypted and saved, so don't exit early. - if (writer_->IsWriteBlocked() && !IsConnectionClose(*packet)) { + const bool is_connection_close = IsConnectionClose(*packet); + if (writer_->IsWriteBlocked() && !is_connection_close) { return false; } @@ -1427,7 +1419,7 @@ // Connection close packets are eventually owned by TimeWaitListManager. // Others are deleted at the end of this call. scoped_ptr<QuicEncryptedPacket> encrypted_deleter; - if (IsConnectionClose(*packet)) { + if (is_connection_close) { DCHECK(connection_close_packet_.get() == nullptr); connection_close_packet_.reset(encrypted); // This assures we won't try to write *forced* packets when blocked. @@ -1445,15 +1437,14 @@ } DCHECK_LE(encrypted->length(), packet_generator_.max_packet_length()); DVLOG(1) << ENDPOINT << "Sending packet " << sequence_number << " : " - << (packet->serialized_packet.packet->is_fec_packet() ? "FEC " : - (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA - ? "data bearing " : " ack only ")) - << ", encryption level: " + << (packet->serialized_packet.is_fec_packet + ? "FEC " + : (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA + ? "data bearing " + : " ack only ")) << ", encryption level: " << QuicUtils::EncryptionLevelToString(packet->encryption_level) - << ", length:" - << packet->serialized_packet.packet->length() - << ", encrypted length:" - << encrypted->length(); + << ", length:" << packet->serialized_packet.packet->length() + << ", encrypted length:" << encrypted->length(); DVLOG(2) << ENDPOINT << "packet(" << sequence_number << "): " << std::endl << QuicUtils::StringToHexASCIIDump( packet->serialized_packet.packet->AsStringPiece()); @@ -1542,6 +1533,10 @@ if (result.status == WRITE_STATUS_ERROR) { OnWriteError(result.error_code); + DLOG(ERROR) << ENDPOINT << "failed writing " << encrypted->length() + << "bytes " + << " from host " << self_address().ToStringWithoutPort() + << " to address " << peer_address().ToString(); return false; } @@ -1606,7 +1601,7 @@ sent_packet_manager_.OnSerializedPacket(serialized_packet); } } - if (serialized_packet.packet->is_fec_packet() && fec_alarm_->IsSet()) { + if (serialized_packet.is_fec_packet && fec_alarm_->IsSet()) { // If an FEC packet is serialized with the FEC alarm set, cancel the alarm. fec_alarm_->Cancel(); } @@ -1655,12 +1650,6 @@ } } -void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { - stop_waiting->least_unacked = GetLeastUnacked(); - stop_waiting->entropy_hash = sent_entropy_manager_.GetCumulativeEntropy( - stop_waiting->least_unacked - 1); -} - void QuicConnection::SendPing() { if (retransmission_alarm_->IsSet()) { return; @@ -2104,15 +2093,14 @@ } } -bool QuicConnection::IsConnectionClose( - QueuedPacket packet) { - RetransmittableFrames* retransmittable_frames = +bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) { + const RetransmittableFrames* retransmittable_frames = packet.serialized_packet.retransmittable_frames; - if (!retransmittable_frames) { + if (retransmittable_frames == nullptr) { return false; } - for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { - if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { + for (const QuicFrame& frame : retransmittable_frames->frames()) { + if (frame.type == CONNECTION_CLOSE_FRAME) { return true; } }
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 8afd79d..e944aea 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h
@@ -370,8 +370,8 @@ bool ShouldGeneratePacket(TransmissionType transmission_type, HasRetransmittableData retransmittable, IsHandshake handshake) override; - QuicAckFrame* CreateAckFrame() override; - QuicStopWaitingFrame* CreateStopWaitingFrame() override; + void PopulateAckFrame(QuicAckFrame* ack) override; + void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting) override; void OnSerializedPacket(const SerializedPacket& packet) override; // QuicSentPacketManager::NetworkChangeVisitor @@ -629,9 +629,6 @@ void ProcessStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting); - // Update |stop_waiting| for an outgoing ack. - void UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting); - // Queues an ack or sets the ack alarm when an incoming packet arrives that // should be acked. void MaybeQueueAck(); @@ -670,7 +667,7 @@ const IPEndPoint& peer_address); HasRetransmittableData IsRetransmittable(const QueuedPacket& packet); - bool IsConnectionClose(QueuedPacket packet); + bool IsConnectionClose(const QueuedPacket& packet); QuicFramer framer_; QuicConnectionHelperInterface* helper_; // Not owned.
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 8b4e8b9..52e4561 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc
@@ -326,9 +326,11 @@ session_(session), last_received_packet_sequence_number_(0), last_received_packet_size_(0), + previous_received_packet_size_(0), largest_received_packet_sequence_number_(0), largest_received_missing_packet_sequence_number_(0), num_out_of_order_received_packets_(0), + num_out_of_order_large_received_packets_(0), num_packets_received_(0), num_truncated_acks_sent_(0), num_truncated_acks_received_(0), @@ -345,6 +347,8 @@ QuicConnectionLogger::~QuicConnectionLogger() { UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived", num_out_of_order_received_packets_); + UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderLargePacketsReceived", + num_out_of_order_large_received_packets_); UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksSent", num_truncated_acks_sent_); UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksReceived", @@ -496,6 +500,7 @@ ADDRESS_FAMILY_LAST); } + previous_received_packet_size_ = last_received_packet_size_; last_received_packet_size_ = packet.length(); net_log_.AddEvent( NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED, @@ -546,6 +551,8 @@ } if (header.packet_sequence_number < last_received_packet_sequence_number_) { ++num_out_of_order_received_packets_; + if (previous_received_packet_size_ < last_received_packet_size_) + ++num_out_of_order_large_received_packets_; UMA_HISTOGRAM_COUNTS( "Net.QuicSession.OutOfOrderGapReceived", static_cast<base::HistogramBase::Sample>(
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index 09e3c46..8f6b7ff 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h
@@ -118,6 +118,8 @@ QuicPacketSequenceNumber last_received_packet_sequence_number_; // The size of the most recently received packet. size_t last_received_packet_size_; + // The size of the previously received packet. + size_t previous_received_packet_size_; // The largest packet sequence number received. In the case where a packet is // received late (out of order), this value will not be updated. QuicPacketSequenceNumber largest_received_packet_sequence_number_; @@ -127,6 +129,11 @@ // Number of times that the current received packet sequence number is // smaller than the last received packet sequence number. size_t num_out_of_order_received_packets_; + // Number of times that the current received packet sequence number is + // smaller than the last received packet sequence number and where the + // size of the current packet is larger than the size of the previous + // packet. + size_t num_out_of_order_large_received_packets_; // The number of times that OnPacketHeader was called. // If the network replicates packets, then this number may be slightly // different from the real number of distinct packets received.
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 091dc9ec..4cbc97b7 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc
@@ -9,7 +9,6 @@ #include "base/stl_util.h" #include "net/base/net_errors.h" #include "net/quic/congestion_control/loss_detection_interface.h" -#include "net/quic/congestion_control/receive_algorithm_interface.h" #include "net/quic/congestion_control/send_algorithm_interface.h" #include "net/quic/crypto/null_encrypter.h" #include "net/quic/crypto/quic_decrypter.h" @@ -64,17 +63,6 @@ const int kDefaultRetransmissionTimeMs = 500; -class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { - public: - TestReceiveAlgorithm() {} - - MOCK_METHOD3(RecordIncomingPacket, - void(QuicByteCount, QuicPacketSequenceNumber, QuicTime)); - - private: - DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm); -}; - // TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message. class TaggingEncrypter : public QuicEncrypter { public: @@ -408,10 +396,6 @@ QuicConnectionPeer::SendAck(this); } - void SetReceiveAlgorithm(TestReceiveAlgorithm* receive_algorithm) { - QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); - } - void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); } @@ -603,7 +587,6 @@ peer_creator_(connection_id_, &framer_, &random_generator_), send_algorithm_(new StrictMock<MockSendAlgorithm>), loss_algorithm_(new MockLossAlgorithm()), - receive_algorithm_(new TestReceiveAlgorithm), helper_(new TestConnectionHelper(&clock_, &random_generator_)), writer_(new TestPacketWriter(version(), &clock_)), factory_(writer_.get()), @@ -624,12 +607,9 @@ connection_.SetSendAlgorithm(send_algorithm_); connection_.SetLossAlgorithm(loss_algorithm_); framer_.set_received_entropy_calculator(&entropy_calculator_); - connection_.SetReceiveAlgorithm(receive_algorithm_); EXPECT_CALL( *send_algorithm_, TimeUntilSend(_, _, _)).WillRepeatedly(Return( QuicTime::Delta::Zero())); - EXPECT_CALL(*receive_algorithm_, - RecordIncomingPacket(_, _, _)).Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( @@ -662,14 +642,13 @@ } QuicAckFrame* outgoing_ack() { - outgoing_ack_.reset(QuicConnectionPeer::CreateAckFrame(&connection_)); - return outgoing_ack_.get(); + QuicConnectionPeer::PopulateAckFrame(&connection_, &ack_); + return &ack_; } QuicStopWaitingFrame* stop_waiting() { - stop_waiting_.reset( - QuicConnectionPeer::CreateStopWaitingFrame(&connection_)); - return stop_waiting_.get(); + QuicConnectionPeer::PopulateStopWaitingFrame(&connection_, &stop_waiting_); + return &stop_waiting_; } QuicPacketSequenceNumber least_unacked() { @@ -991,7 +970,6 @@ MockSendAlgorithm* send_algorithm_; MockLossAlgorithm* loss_algorithm_; - TestReceiveAlgorithm* receive_algorithm_; MockClock clock_; MockRandom random_generator_; scoped_ptr<TestConnectionHelper> helper_; @@ -1006,8 +984,8 @@ QuicPacketHeader header_; QuicStreamFrame frame1_; QuicStreamFrame frame2_; - scoped_ptr<QuicAckFrame> outgoing_ack_; - scoped_ptr<QuicStopWaitingFrame> stop_waiting_; + QuicAckFrame ack_; + QuicStopWaitingFrame stop_waiting_; QuicSequenceNumberLength sequence_number_length_; QuicConnectionIdLength connection_id_length_; @@ -3157,7 +3135,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendSilentClose) { // Same test as above, but complete a handshake which enables silent close, // causing no connection close packet to be sent. - ValueRestore<bool> old_flag(&FLAGS_quic_allow_silent_close, true); EXPECT_TRUE(connection_.connected()); EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)); QuicConfig config;
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc index 26bd1717..bcf0456 100644 --- a/net/quic/quic_crypto_client_stream.cc +++ b/net/quic/quic_crypto_client_stream.cc
@@ -196,7 +196,7 @@ break; case STATE_SEND_CHLO: DoSendCHLO(in, cached); - return; + return; // return waiting to hear from server. case STATE_RECV_REJ: DoReceiveREJ(in, cached); break; @@ -638,7 +638,7 @@ return false; } const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); - if (!scfg) { // scfg may be null when we send an inchoate CHLO. + if (!scfg) { // scfg may be null then we send an inchoate CHLO. return false; } const QuicTag* their_proof_demands;
diff --git a/net/quic/quic_dispatcher.cc b/net/quic/quic_dispatcher.cc index ee2c0c6d..f1ae736 100644 --- a/net/quic/quic_dispatcher.cc +++ b/net/quic/quic_dispatcher.cc
@@ -204,6 +204,13 @@ const QuicPacketPublicHeader& header) { QuicSession* session = nullptr; + // Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC. + // Given that we can't even send a reply rejecting the packet, just black hole + // it. + if (current_client_address_.port() == 0) { + return false; + } + QuicConnectionId connection_id = header.connection_id; SessionMap::iterator it = session_map_.find(connection_id); if (it == session_map_.end()) {
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc index 8eb6ec1..5997e90e 100644 --- a/net/quic/quic_flags.cc +++ b/net/quic/quic_flags.cc
@@ -41,9 +41,6 @@ // congestion control. bool FLAGS_quic_enable_pacing = false; -// If true, the silent close option will be honored. -bool FLAGS_quic_allow_silent_close = true; - // If true, use std::cbrt instead of custom cube root. bool FLAGS_quic_use_std_cbrt = true; @@ -51,10 +48,6 @@ // store multiple addresses. bool FLAGS_quic_use_multiple_address_in_source_tokens = false; -// If true, if min RTT and/or SRTT have not yet been set then initial RTT is -// used to initialize them in a call to QuicConnection::GetStats. -bool FLAGS_quic_use_initial_rtt_for_stats = true; - // If true, uses the last sent packet for the RTO timer instead of the earliest. bool FLAGS_quic_rto_uses_last_sent = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h index 58f04086..5ad6062 100644 --- a/net/quic/quic_flags.h +++ b/net/quic/quic_flags.h
@@ -19,10 +19,8 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_bandwidth_resumption_experiment; NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_pacing; -NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_silent_close; NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_std_cbrt; NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_multiple_address_in_source_tokens; -NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_initial_rtt_for_stats; NET_EXPORT_PRIVATE extern bool FLAGS_quic_rto_uses_last_sent; NET_EXPORT_PRIVATE extern bool FLAGS_quic_attach_ack_notifiers_to_packets; NET_EXPORT_PRIVATE extern bool FLAGS_quic_ack_notifier_informed_on_serialized;
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index 5cde3c23..19ae626 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc
@@ -410,7 +410,7 @@ // Less than or equal because truncated acks end up with max_plaintex_size // length, even though they're typically slightly shorter. DCHECK_LE(len, packet_size); - QuicPacket* packet = QuicPacket::NewDataPacket( + QuicPacket* packet = new QuicPacket( writer.take(), len, true, header.public_header.connection_id_length, header.public_header.version_flag, header.public_header.sequence_number_length); @@ -445,14 +445,16 @@ return kNoPacket; } - return SerializedPacket( + SerializedPacket packet( header.packet_sequence_number, header.public_header.sequence_number_length, - QuicPacket::NewFecPacket(writer.take(), len, true, - header.public_header.connection_id_length, - header.public_header.version_flag, - header.public_header.sequence_number_length), + new QuicPacket(writer.take(), len, true, + header.public_header.connection_id_length, + header.public_header.version_flag, + header.public_header.sequence_number_length), GetPacketEntropyHash(header), nullptr); + packet.is_fec_packet = true; + return packet; } // static
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc index 0fa4ce97..7e83033 100644 --- a/net/quic/quic_framer_test.cc +++ b/net/quic/quic_framer_test.cc
@@ -1312,8 +1312,7 @@ ASSERT_EQ(1u, visitor_.stream_frames_.size()); EXPECT_EQ(0u, visitor_.ack_frames_.size()); - EXPECT_EQ(GG_UINT64_C(0x00020304), - visitor_.stream_frames_[0]->stream_id); + EXPECT_EQ(GG_UINT64_C(0x00020304), visitor_.stream_frames_[0]->stream_id); EXPECT_TRUE(visitor_.stream_frames_[0]->fin); EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset); @@ -3936,10 +3935,9 @@ 'm', 'n', 'o', 'p', }; - scoped_ptr<QuicPacket> raw( - QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false, - PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - PACKET_6BYTE_SEQUENCE_NUMBER)); + scoped_ptr<QuicPacket> raw(new QuicPacket( + AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, + !kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER)); scoped_ptr<QuicEncryptedPacket> encrypted( framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw)); @@ -3972,10 +3970,9 @@ 'm', 'n', 'o', 'p', }; - scoped_ptr<QuicPacket> raw( - QuicPacket::NewDataPacket(AsChars(packet), arraysize(packet), false, - PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, - PACKET_6BYTE_SEQUENCE_NUMBER)); + scoped_ptr<QuicPacket> raw(new QuicPacket( + AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, + kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER)); scoped_ptr<QuicEncryptedPacket> encrypted( framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index a22bb74..5b69e46 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc
@@ -13,7 +13,6 @@ #include "net/base/upload_bytes_element_reader.h" #include "net/http/http_response_headers.h" #include "net/http/transport_security_state.h" -#include "net/quic/congestion_control/receive_algorithm_interface.h" #include "net/quic/congestion_control/send_algorithm_interface.h" #include "net/quic/crypto/crypto_protocol.h" #include "net/quic/crypto/quic_decrypter.h" @@ -74,16 +73,6 @@ void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); } - - void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { - QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); - } -}; - -class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { - public: - MOCK_METHOD3(RecordIncomingPacket, - void(QuicByteCount, QuicPacketSequenceNumber, QuicTime)); }; // Subclass of QuicHttpStream that closes itself when the first piece of data @@ -198,9 +187,6 @@ socket->Connect(peer_addr_); runner_ = new TestTaskRunner(&clock_); send_algorithm_ = new MockSendAlgorithm(); - receive_algorithm_ = new TestReceiveAlgorithm(); - EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)). - Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( @@ -220,7 +206,6 @@ helper_.get(), writer_factory); connection_->set_visitor(&visitor_); connection_->SetSendAlgorithm(send_algorithm_); - connection_->SetReceiveAlgorithm(receive_algorithm_); session_.reset( new QuicClientSession(connection_, scoped_ptr<DatagramClientSocket>(socket), @@ -307,7 +292,6 @@ BoundNetLog net_log_; bool use_closing_stream_; MockSendAlgorithm* send_algorithm_; - TestReceiveAlgorithm* receive_algorithm_; scoped_refptr<TestTaskRunner> runner_; scoped_ptr<MockWrite[]> mock_writes_; MockClock clock_;
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 203aa3e..3c85ca4 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -102,6 +102,21 @@ scoped_ptr<SocketDataProvider> socket_data_; }; +class ProxyHeadersHandler { + public: + ProxyHeadersHandler() : was_called_(false) {} + + bool was_called() { return was_called_; } + + void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info, + HttpRequestHeaders* request_headers) { + was_called_ = true; + } + + private: + bool was_called_; +}; + class QuicNetworkTransactionTest : public PlatformTest, public ::testing::WithParamInterface<QuicVersion> { @@ -269,11 +284,11 @@ } void SendRequestAndExpectQuicResponse(const std::string& expected) { - scoped_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); - RunTransaction(trans.get()); - CheckWasQuicResponse(trans); - CheckResponseData(trans.get(), expected); + SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false); + } + + void SendRequestAndExpectQuicResponseFromProxy(const std::string& expected) { + SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true); } void AddQuicAlternateProtocolMapping( @@ -321,6 +336,22 @@ HttpRequestInfo request_; CapturingBoundNetLog net_log_; StaticSocketDataProvider hanging_data_; + + private: + void SendRequestAndExpectQuicResponseMaybeFromProxy( + const std::string& expected, + bool used_proxy) { + scoped_ptr<HttpNetworkTransaction> trans( + new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + ProxyHeadersHandler proxy_headers_handler; + trans->SetBeforeProxyHeadersSentCallback( + base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent, + base::Unretained(&proxy_headers_handler))); + RunTransaction(trans.get()); + CheckWasQuicResponse(trans); + CheckResponseData(trans.get(), expected); + EXPECT_EQ(used_proxy, proxy_headers_handler.was_called()); + } }; INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest, @@ -411,7 +442,7 @@ CreateSession(); - SendRequestAndExpectQuicResponse("hello!"); + SendRequestAndExpectQuicResponseFromProxy("hello!"); } TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc index bfecf5d..e475d1e 100644 --- a/net/quic/quic_packet_generator.cc +++ b/net/quic/quic_packet_generator.cc
@@ -46,7 +46,9 @@ fec_timeout_(QuicTime::Delta::Zero()), should_fec_protect_(false), should_send_ack_(false), - should_send_stop_waiting_(false) { + should_send_stop_waiting_(false), + ack_queued_(false), + stop_waiting_queued_(false) { } QuicPacketGenerator::~QuicPacketGenerator() { @@ -101,12 +103,12 @@ } void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { - if (pending_ack_frame_ != nullptr) { + if (ack_queued_) { // Ack already queued, nothing to do. return; } - if (also_send_stop_waiting && pending_stop_waiting_frame_ != nullptr) { + if (also_send_stop_waiting && stop_waiting_queued_) { LOG(DFATAL) << "Should only ever be one pending stop waiting frame."; return; } @@ -360,19 +362,21 @@ bool QuicPacketGenerator::AddNextPendingFrame() { if (should_send_ack_) { - pending_ack_frame_.reset(delegate_->CreateAckFrame()); + delegate_->PopulateAckFrame(&pending_ack_frame_); + ack_queued_ = true; // If we can't this add the frame now, then we still need to do so later. - should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get())); + should_send_ack_ = !AddFrame(QuicFrame(&pending_ack_frame_)); // Return success if we have cleared out this flag (i.e., added the frame). // If we still need to send, then the frame is full, and we have failed. return !should_send_ack_; } if (should_send_stop_waiting_) { - pending_stop_waiting_frame_.reset(delegate_->CreateStopWaitingFrame()); + delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_); + stop_waiting_queued_ = true; // If we can't this add the frame now, then we still need to do so later. should_send_stop_waiting_ = - !AddFrame(QuicFrame(pending_stop_waiting_frame_.get())); + !AddFrame(QuicFrame(&pending_stop_waiting_frame_)); // Return success if we have cleared out this flag (i.e., added the frame). // If we still need to send, then the frame is full, and we have failed. return !should_send_stop_waiting_; @@ -409,9 +413,9 @@ delegate_->OnSerializedPacket(serialized_packet); MaybeSendFecPacketAndCloseGroup(/*force=*/false); - // The packet has now been serialized, safe to delete pending frames. - pending_ack_frame_.reset(); - pending_stop_waiting_frame_.reset(); + // The packet has now been serialized, so the frames are no longer queued. + ack_queued_ = false; + stop_waiting_queued_ = false; } void QuicPacketGenerator::StopSendingVersion() {
diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h index 0da94f0..25b2cc68 100644 --- a/net/quic/quic_packet_generator.h +++ b/net/quic/quic_packet_generator.h
@@ -75,8 +75,9 @@ virtual bool ShouldGeneratePacket(TransmissionType transmission_type, HasRetransmittableData retransmittable, IsHandshake handshake) = 0; - virtual QuicAckFrame* CreateAckFrame() = 0; - virtual QuicStopWaitingFrame* CreateStopWaitingFrame() = 0; + virtual void PopulateAckFrame(QuicAckFrame* ack) = 0; + virtual void PopulateStopWaitingFrame( + QuicStopWaitingFrame* stop_waiting) = 0; // Takes ownership of |packet.packet| and |packet.retransmittable_frames|. virtual void OnSerializedPacket(const SerializedPacket& packet) = 0; virtual void CloseConnection(QuicErrorCode error, bool from_peer) = 0; @@ -254,8 +255,12 @@ // have to hold a reference to it until we flush (and serialize it). // Retransmittable frames are referenced elsewhere so that they // can later be (optionally) retransmitted. - scoped_ptr<QuicAckFrame> pending_ack_frame_; - scoped_ptr<QuicStopWaitingFrame> pending_stop_waiting_frame_; + QuicAckFrame pending_ack_frame_; + QuicStopWaitingFrame pending_stop_waiting_frame_; + // True if an ack or stop waiting frame is already queued, and should not be + // re-added. + bool ack_queued_; + bool stop_waiting_queued_; // Stores notifiers that should be attached to the next serialized packet. std::list<QuicAckNotifier*> ack_notifiers_;
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc index 1ab7ca55..26f1658 100644 --- a/net/quic/quic_packet_generator_test.cc +++ b/net/quic/quic_packet_generator_test.cc
@@ -43,8 +43,8 @@ bool(TransmissionType transmission_type, HasRetransmittableData retransmittable, IsHandshake handshake)); - MOCK_METHOD0(CreateAckFrame, QuicAckFrame*()); - MOCK_METHOD0(CreateStopWaitingFrame, QuicStopWaitingFrame*()); + MOCK_METHOD1(PopulateAckFrame, void(QuicAckFrame*)); + MOCK_METHOD1(PopulateStopWaitingFrame, void(QuicStopWaitingFrame*)); MOCK_METHOD1(OnSerializedPacket, void(const SerializedPacket& packet)); MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool)); @@ -137,18 +137,6 @@ delete packet8_.retransmittable_frames; } - QuicAckFrame* CreateAckFrame() { - // TODO(rch): Initialize this so it can be verified later. - return new QuicAckFrame(MakeAckFrame(0)); - } - - QuicStopWaitingFrame* CreateStopWaitingFrame() { - QuicStopWaitingFrame* frame = new QuicStopWaitingFrame(); - frame->entropy_hash = 0; - frame->least_unacked = 0; - return frame; - } - QuicRstStreamFrame* CreateRstStreamFrame() { return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR, 0); } @@ -256,7 +244,7 @@ delegate_.SetCanWriteOnlyNonRetransmittable(); generator_.StartBatchOperations(); - EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)); EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1); generator_.SetShouldSendAck(false); @@ -266,7 +254,7 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) { delegate_.SetCanWriteOnlyNonRetransmittable(); - EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)); EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); generator_.SetShouldSendAck(false); @@ -285,9 +273,7 @@ delegate_.SetCanWriteAnything(); // Only one AckFrame should be created. - EXPECT_CALL(delegate_, CreateAckFrame()) - .Times(1) - .WillOnce(Return(CreateAckFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)).Times(1); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .Times(1) .WillOnce(SaveArg<0>(&packet_)); @@ -871,9 +857,8 @@ generator_.StartBatchOperations(); // Set up frames to write into the creator when control frames are written. - EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); - EXPECT_CALL(delegate_, CreateStopWaitingFrame()).WillOnce( - Return(CreateStopWaitingFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)); + EXPECT_CALL(delegate_, PopulateStopWaitingFrame(_)); // Generator should have queued control frames, and creator should be empty. EXPECT_TRUE(generator_.HasQueuedFrames()); @@ -1026,7 +1011,7 @@ generator_.StartBatchOperations(); // When the first write operation is invoked, the ack frame will be returned. - EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)); // Send some data and a control frame generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, @@ -1058,7 +1043,7 @@ generator_.StartBatchOperations(); // When the first write operation is invoked, the ack frame will be returned. - EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); + EXPECT_CALL(delegate_, PopulateAckFrame(_)); { InSequence dummy;
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc index 56dfa97..161e25a1 100644 --- a/net/quic/quic_protocol.cc +++ b/net/quic/quic_protocol.cc
@@ -509,11 +509,9 @@ bool owns_buffer, QuicConnectionIdLength connection_id_length, bool includes_version, - QuicSequenceNumberLength sequence_number_length, - bool is_fec_packet) + QuicSequenceNumberLength sequence_number_length) : QuicData(buffer, length, owns_buffer), buffer_(buffer), - is_fec_packet_(is_fec_packet), connection_id_length_(connection_id_length), includes_version_(includes_version), sequence_number_length_(sequence_number_length) { @@ -639,7 +637,8 @@ sequence_number_length(sequence_number_length), packet(packet), entropy_hash(entropy_hash), - retransmittable_frames(retransmittable_frames) { + retransmittable_frames(retransmittable_frames), + is_fec_packet(false) { } SerializedPacket::~SerializedPacket() {}
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index 3daf9174..2b603cb 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h
@@ -513,6 +513,8 @@ QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68, // The connection has too many outstanding received packets. QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69, + // The quic connection job to load server config is cancelled. + QUIC_CONNECTION_CANCELLED = 70, // Crypto errors. @@ -570,7 +572,7 @@ QUIC_VERSION_NEGOTIATION_MISMATCH = 55, // No error. Used as bound while iterating. - QUIC_LAST_ERROR = 70, + QUIC_LAST_ERROR = 71, }; struct NET_EXPORT_PRIVATE QuicPacketPublicHeader { @@ -918,48 +920,22 @@ class NET_EXPORT_PRIVATE QuicPacket : public QuicData { public: - static QuicPacket* NewDataPacket( - char* buffer, - size_t length, - bool owns_buffer, - QuicConnectionIdLength connection_id_length, - bool includes_version, - QuicSequenceNumberLength sequence_number_length) { - return new QuicPacket(buffer, length, owns_buffer, connection_id_length, - includes_version, sequence_number_length, false); - } - - static QuicPacket* NewFecPacket( - char* buffer, - size_t length, - bool owns_buffer, - QuicConnectionIdLength connection_id_length, - bool includes_version, - QuicSequenceNumberLength sequence_number_length) { - return new QuicPacket(buffer, length, owns_buffer, connection_id_length, - includes_version, sequence_number_length, true); - } + QuicPacket(char* buffer, + size_t length, + bool owns_buffer, + QuicConnectionIdLength connection_id_length, + bool includes_version, + QuicSequenceNumberLength sequence_number_length); base::StringPiece FecProtectedData() const; base::StringPiece AssociatedData() const; base::StringPiece BeforePlaintext() const; base::StringPiece Plaintext() const; - bool is_fec_packet() const { return is_fec_packet_; } - char* mutable_data() { return buffer_; } private: - QuicPacket(char* buffer, - size_t length, - bool owns_buffer, - QuicConnectionIdLength connection_id_length, - bool includes_version, - QuicSequenceNumberLength sequence_number_length, - bool is_fec_packet); - char* buffer_; - const bool is_fec_packet_; const QuicConnectionIdLength connection_id_length_; const bool includes_version_; const QuicSequenceNumberLength sequence_number_length_; @@ -1031,6 +1007,7 @@ QuicPacket* packet; QuicPacketEntropyHash entropy_hash; RetransmittableFrames* retransmittable_frames; + bool is_fec_packet; // Optional notifiers which will be informed when this packet has been ACKed. std::list<QuicAckNotifier*> notifiers;
diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc index 38ceec68..f5e2c36 100644 --- a/net/quic/quic_received_packet_manager.cc +++ b/net/quic/quic_received_packet_manager.cc
@@ -135,7 +135,6 @@ QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats) : peer_least_packet_awaiting_ack_(0), time_largest_observed_(QuicTime::Zero()), - receive_algorithm_(ReceiveAlgorithmInterface::Create()), stats_(stats) { ack_frame_.largest_observed = 0; ack_frame_.entropy_hash = 0; @@ -178,9 +177,6 @@ entropy_tracker_.RecordPacketEntropyHash(sequence_number, header.entropy_hash); - receive_algorithm_->RecordIncomingPacket( - bytes, sequence_number, receipt_time); - received_packet_times_.push_back( std::make_pair(sequence_number, receipt_time)); @@ -237,8 +233,8 @@ // Remove all packets that are too far from largest_observed to express. received_packet_times_.remove_if(isTooLarge(ack_frame_.largest_observed)); - ack_frame->received_packet_times = received_packet_times_; - received_packet_times_.clear(); + ack_frame->received_packet_times.clear(); + ack_frame->received_packet_times.swap(received_packet_times_); } QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash(
diff --git a/net/quic/quic_received_packet_manager.h b/net/quic/quic_received_packet_manager.h index 94bd3d5..b16af55 100644 --- a/net/quic/quic_received_packet_manager.h +++ b/net/quic/quic_received_packet_manager.h
@@ -10,7 +10,6 @@ #include <deque> -#include "net/quic/congestion_control/receive_algorithm_interface.h" #include "net/quic/quic_config.h" #include "net/quic/quic_framer.h" #include "net/quic/quic_protocol.h" @@ -166,8 +165,6 @@ // Needed for calculating delta_time_largest_observed. QuicTime time_largest_observed_; - scoped_ptr<ReceiveAlgorithmInterface> receive_algorithm_; - QuicConnectionStats* stats_; PacketTimeList received_packet_times_;
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index 34bb972..c1811cf 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc
@@ -598,8 +598,8 @@ // Since FEC packets should also be counted towards the congestion window, // consider them as retransmittable for the purposes of congestion control. HasRetransmittableData has_congestion_controlled_data = - serialized_packet->packet->is_fec_packet() ? - HAS_RETRANSMITTABLE_DATA : has_retransmittable_data; + serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA + : has_retransmittable_data; const bool in_flight = send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc index e9b169b..e7733a3 100644 --- a/net/quic/quic_sent_packet_manager_test.cc +++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -176,20 +176,22 @@ SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number, bool retransmittable) { - packets_.push_back(QuicPacket::NewDataPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_6BYTE_SEQUENCE_NUMBER)); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_6BYTE_SEQUENCE_NUMBER)); return SerializedPacket( sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, packets_.back(), 0u, retransmittable ? new RetransmittableFrames() : nullptr); } SerializedPacket CreateFecPacket(QuicPacketSequenceNumber sequence_number) { - packets_.push_back(QuicPacket::NewFecPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_6BYTE_SEQUENCE_NUMBER)); - return SerializedPacket(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, - packets_.back(), 0u, nullptr); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_6BYTE_SEQUENCE_NUMBER)); + SerializedPacket serialized(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, + packets_.back(), 0u, nullptr); + serialized.is_fec_packet = true; + return serialized; } void SendDataPacket(QuicPacketSequenceNumber sequence_number) {
diff --git a/net/quic/quic_server.cc b/net/quic/quic_server.cc index 2e2d5b2..610b305f 100644 --- a/net/quic/quic_server.cc +++ b/net/quic/quic_server.cc
@@ -8,7 +8,6 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/crypto/crypto_handshake.h" #include "net/quic/crypto/quic_random.h" #include "net/quic/quic_crypto_stream.h" @@ -94,7 +93,7 @@ // because the default usage of QuicServer is as a test server with one or // two clients. Adjust higher for use with many clients. rc = socket->SetReceiveBufferSize( - static_cast<int32>(TcpReceiver::kReceiveWindowTCP)); + static_cast<int32>(kDefaultSocketReceiveBuffer)); if (rc < 0) { LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); return rc;
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index f38ae01..f2293893 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -21,7 +21,6 @@ #include "net/dns/host_resolver.h" #include "net/dns/single_request_host_resolver.h" #include "net/http/http_server_properties.h" -#include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/crypto/channel_id_chromium.h" #include "net/quic/crypto/proof_verifier_chromium.h" #include "net/quic/crypto/quic_random.h" @@ -63,9 +62,6 @@ // Set the maximum number of undecryptable packets the connection will store. const int32 kMaxUndecryptablePackets = 100; -const char kDummyHostname[] = "quic.global.props"; -const uint16 kDummyPort = 0; - void HistogramCreateSessionFailure(enum CreateSessionFailure error) { UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, CREATION_ERROR_MAX); @@ -144,7 +140,7 @@ bool is_https, bool was_alternate_protocol_recently_broken, PrivacyMode privacy_mode, - base::StringPiece method, + bool is_post, QuicServerInfo* server_info, const BoundNetLog& net_log); @@ -170,15 +166,15 @@ void OnIOComplete(int rv); + void RunAuxilaryJob(); + + void Cancel(); + void CancelWaitForDataReadyCallback(); - CompletionCallback callback() { - return callback_; - } + const QuicServerId server_id() const { return server_id_; } - const QuicServerId server_id() const { - return server_id_; - } + base::WeakPtr<Job> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } private: enum IoState { @@ -199,6 +195,7 @@ bool is_post_; bool was_alternate_protocol_recently_broken_; scoped_ptr<QuicServerInfo> server_info_; + bool started_another_job_; const BoundNetLog net_log_; QuicClientSession* session_; CompletionCallback callback_; @@ -215,20 +212,22 @@ bool is_https, bool was_alternate_protocol_recently_broken, PrivacyMode privacy_mode, - base::StringPiece method, + bool is_post, QuicServerInfo* server_info, const BoundNetLog& net_log) : io_state_(STATE_RESOLVE_HOST), factory_(factory), host_resolver_(host_resolver), server_id_(host_port_pair, is_https, privacy_mode), - is_post_(method == "POST"), + is_post_(is_post), was_alternate_protocol_recently_broken_( was_alternate_protocol_recently_broken), server_info_(server_info), + started_another_job_(false), net_log_(net_log), session_(nullptr), - weak_factory_(this) {} + weak_factory_(this) { +} QuicStreamFactory::Job::Job(QuicStreamFactory* factory, HostResolver* host_resolver, @@ -238,13 +237,18 @@ factory_(factory), host_resolver_(host_resolver), // unused server_id_(server_id), - is_post_(false), // unused + is_post_(false), // unused was_alternate_protocol_recently_broken_(false), // unused - net_log_(session->net_log()), // unused + started_another_job_(false), // unused + net_log_(session->net_log()), // unused session_(session), - weak_factory_(this) {} + weak_factory_(this) { +} QuicStreamFactory::Job::~Job() { + // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. + if (server_info_) + server_info_->CancelWaitForDataReadyCallback(); } int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { @@ -310,6 +314,19 @@ } } +void QuicStreamFactory::Job::RunAuxilaryJob() { + int rv = Run(base::Bind(&QuicStreamFactory::OnJobComplete, + base::Unretained(factory_), this)); + if (rv != ERR_IO_PENDING) + factory_->OnJobComplete(this, rv); +} + +void QuicStreamFactory::Job::Cancel() { + callback_.Reset(); + if (session_) + session_->connection()->SendConnectionClose(QUIC_CONNECTION_CANCELLED); +} + void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { // If we are waiting for WaitForDataReadyCallback, then cancel the callback. if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) @@ -332,11 +349,9 @@ io_state_ = STATE_RESOLVE_HOST_COMPLETE; dns_resolution_start_time_ = base::TimeTicks::Now(); return host_resolver_.Resolve( - HostResolver::RequestInfo(server_id_.host_port_pair()), - DEFAULT_PRIORITY, + HostResolver::RequestInfo(server_id_.host_port_pair()), DEFAULT_PRIORITY, &address_list_, - base::Bind(&QuicStreamFactory::Job::OnIOComplete, - weak_factory_.GetWeakPtr()), + base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), net_log_); } @@ -359,7 +374,10 @@ return OK; } - io_state_ = STATE_LOAD_SERVER_INFO; + if (server_info_) + io_state_ = STATE_LOAD_SERVER_INFO; + else + io_state_ = STATE_CONNECT; return OK; } @@ -371,8 +389,7 @@ io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; - if (!server_info_) - return OK; + DCHECK(server_info_); // To mitigate the effects of disk cache taking too long to load QUIC server // information, set up a timer to cancel WaitForDataReady's callback. @@ -388,14 +405,20 @@ factory_->task_runner_->PostDelayedTask( FROM_HERE, base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, - weak_factory_.GetWeakPtr()), + GetWeakPtr()), base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); } disk_cache_load_start_time_ = base::TimeTicks::Now(); - return server_info_->WaitForDataReady( - base::Bind(&QuicStreamFactory::Job::OnIOComplete, - weak_factory_.GetWeakPtr())); + int rv = server_info_->WaitForDataReady( + base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); + if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { + // If we are waiting to load server config from the disk cache, then start + // another job. + started_another_job_ = true; + factory_->CreateAuxilaryJob(server_id_, is_post_, net_log_); + } + return rv; } int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { @@ -404,13 +427,20 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); - if (server_info_) { - UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", - base::TimeTicks::Now() - disk_cache_load_start_time_); - } + UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", + base::TimeTicks::Now() - disk_cache_load_start_time_); - if (rv != OK) { + if (rv != OK) server_info_.reset(); + + if (started_another_job_ && + (!server_info_ || server_info_->state().server_config.empty() || + !factory_->CryptoConfigCacheIsEmpty(server_id_))) { + // If we have started another job and if we didn't load the server config + // from the disk cache or if we have received a new server config from the + // server, then cancel the current job. + io_state_ = STATE_NONE; + return ERR_CONNECTION_CLOSED; } io_state_ = STATE_CONNECT; @@ -457,8 +487,7 @@ rv = session_->CryptoConnect( require_confirmation, - base::Bind(&QuicStreamFactory::Job::OnIOComplete, - base::Unretained(this))); + base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); return rv; } @@ -471,8 +500,7 @@ io_state_ = STATE_CONNECT_COMPLETE; int rv = session_->ResumeCryptoConnect( - base::Bind(&QuicStreamFactory::Job::OnIOComplete, - base::Unretained(this))); + base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); return rv; } @@ -588,6 +616,7 @@ load_server_info_timeout_srtt_multiplier_( load_server_info_timeout_srtt_multiplier), enable_truncated_connection_ids_(enable_truncated_connection_ids), + enable_connection_racing_(false), port_seed_(random_generator_->RandUint64()), check_persisted_supports_quic_(true), task_runner_(nullptr), @@ -613,17 +642,18 @@ delete all_sessions_.begin()->first; all_sessions_.erase(all_sessions_.begin()); } - STLDeleteValues(&active_jobs_); + while (!active_jobs_.empty()) { + const QuicServerId server_id = active_jobs_.begin()->first; + STLDeleteElements(&(active_jobs_[server_id])); + active_jobs_.erase(server_id); + } } void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { require_confirmation_ = require_confirmation; if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { - // TODO(rtenneti): Delete host_port_pair and persist data in globals. - HostPortPair host_port_pair(kDummyHostname, kDummyPort); - http_server_properties_->SetSupportsQuic( - host_port_pair, !require_confirmation, - local_address_.ToStringWithoutPort()); + http_server_properties_->SetSupportsQuic(!require_confirmation, + local_address_.address()); } } @@ -640,12 +670,16 @@ } if (HasActiveJob(server_id)) { - Job* job = active_jobs_[server_id]; - active_requests_[request] = job; - job_requests_map_[job].insert(request); + active_requests_[request] = server_id; + job_requests_map_[server_id].insert(request); return ERR_IO_PENDING; } + // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ + // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. + if (!task_runner_) + task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); + QuicServerInfo* quic_server_info = nullptr; if (quic_server_info_factory_) { bool load_from_disk_cache = true; @@ -660,34 +694,22 @@ load_from_disk_cache = false; } } - if (load_from_disk_cache) { - QuicCryptoClientConfig::CachedState* cached = - crypto_config_.LookupOrCreate(server_id); - DCHECK(cached); - if (cached->IsEmpty()) { - quic_server_info = quic_server_info_factory_->GetForServer(server_id); - } + if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { + quic_server_info = quic_server_info_factory_->GetForServer(server_id); } } - // TODO(rtenneti): Initialize task_runner_ in the constructor after - // WebRequestActionWithThreadsTest.* tests are fixed. - if (!task_runner_) - task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); - bool was_alternate_protocol_recently_broken = - http_server_properties_ && - http_server_properties_->WasAlternateProtocolRecentlyBroken( - server_id.host_port_pair()); scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, - was_alternate_protocol_recently_broken, - privacy_mode, method, quic_server_info, net_log)); + WasAlternateProtocolRecentlyBroken(server_id), + privacy_mode, method == "POST" /* is_post */, + quic_server_info, net_log)); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); - if (rv == ERR_IO_PENDING) { - active_requests_[request] = job.get(); - job_requests_map_[job.get()].insert(request); - active_jobs_[server_id] = job.release(); + active_requests_[request] = server_id; + job_requests_map_[server_id].insert(request); + active_jobs_[server_id].insert(job.release()); + return rv; } if (rv == OK) { DCHECK(HasActiveSession(server_id)); @@ -696,6 +718,19 @@ return rv; } +void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, + bool is_post, + const BoundNetLog& net_log) { + Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), + server_id.is_https(), + WasAlternateProtocolRecentlyBroken(server_id), + server_id.privacy_mode(), is_post, nullptr, net_log); + active_jobs_[server_id].insert(aux_job); + task_runner_->PostTask(FROM_HERE, + base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, + aux_job->GetWeakPtr())); +} + bool QuicStreamFactory::OnResolution( const QuicServerId& server_id, const AddressList& address_list) { @@ -721,6 +756,19 @@ } void QuicStreamFactory::OnJobComplete(Job* job, int rv) { + QuicServerId server_id = job->server_id(); + if (rv != OK) { + JobSet* jobs = &(active_jobs_[server_id]); + if (jobs->size() > 1) { + // If there is another pending job, then we can delete this job and let + // the other job handle the request. + job->Cancel(); + jobs->erase(job); + delete job; + return; + } + } + if (rv == OK) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. tracked_objects::ScopedTracker tracking_profile1( @@ -731,11 +779,9 @@ set_require_confirmation(false); // Create all the streams, but do not notify them yet. - for (RequestSet::iterator it = job_requests_map_[job].begin(); - it != job_requests_map_[job].end() ; ++it) { - DCHECK(HasActiveSession(job->server_id())); - (*it)->set_stream(CreateIfSessionExists(job->server_id(), - (*it)->net_log())); + for (QuicStreamRequest* request : job_requests_map_[server_id]) { + DCHECK(HasActiveSession(server_id)); + request->set_stream(CreateIfSessionExists(server_id, request->net_log())); } } @@ -744,10 +790,10 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "422516 QuicStreamFactory::OnJobComplete2")); - while (!job_requests_map_[job].empty()) { - RequestSet::iterator it = job_requests_map_[job].begin(); + while (!job_requests_map_[server_id].empty()) { + RequestSet::iterator it = job_requests_map_[server_id].begin(); QuicStreamRequest* request = *it; - job_requests_map_[job].erase(it); + job_requests_map_[server_id].erase(it); active_requests_.erase(request); // Even though we're invoking callbacks here, we don't need to worry // about |this| being deleted, because the factory is owned by the @@ -760,10 +806,14 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "422516 QuicStreamFactory::OnJobComplete3")); - active_jobs_.erase(job->server_id()); - job_requests_map_.erase(job); - delete job; - return; + for (Job* other_job : active_jobs_[server_id]) { + if (other_job != job) + other_job->Cancel(); + } + + STLDeleteElements(&(active_jobs_[server_id])); + active_jobs_.erase(server_id); + job_requests_map_.erase(server_id); } // Returns a newly created QuicHttpStream owned by the caller, if a @@ -842,7 +892,7 @@ QuicServerId server_id = *aliases.begin(); session_aliases_.erase(session); Job* job = new Job(this, host_resolver_, session, server_id); - active_jobs_[server_id] = job; + active_jobs_[server_id].insert(job); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job)); DCHECK_EQ(ERR_IO_PENDING, rv); @@ -850,8 +900,8 @@ void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { DCHECK(ContainsKey(active_requests_, request)); - Job* job = active_requests_[request]; - job_requests_map_[job].erase(request); + QuicServerId server_id = active_requests_[request]; + job_requests_map_[server_id].erase(request); active_requests_.erase(request); } @@ -921,6 +971,10 @@ return ContainsKey(active_sessions_, server_id); } +bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { + return ContainsKey(active_jobs_, key); +} + int QuicStreamFactory::CreateSession( const QuicServerId& server_id, scoped_ptr<QuicServerInfo> server_info, @@ -984,7 +1038,7 @@ // does not consume "too much" memory. If we see bursty packet loss, we may // revisit this setting and test for its impact. const int32 kSocketBufferSize = - static_cast<int32>(TcpReceiver::kReceiveWindowTCP); + static_cast<int32>(kDefaultSocketReceiveBuffer); rv = socket->SetReceiveBufferSize(kSocketBufferSize); if (rv != OK) { HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); @@ -1002,11 +1056,9 @@ socket->GetLocalAddress(&local_address_); if (check_persisted_supports_quic_ && http_server_properties_) { check_persisted_supports_quic_ = false; - // TODO(rtenneti): Delete host_port_pair and persist data in globals. - HostPortPair host_port_pair(kDummyHostname, kDummyPort); - SupportsQuic supports_quic(true, local_address_.ToStringWithoutPort()); - if (http_server_properties_->GetSupportsQuic( - host_port_pair).Equals(supports_quic)) { + IPAddressNumber last_address; + if (http_server_properties_->GetSupportsQuic(&last_address) && + last_address == local_address_.address()) { require_confirmation_ = false; } } @@ -1137,10 +1189,6 @@ return OK; } -bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { - return ContainsKey(active_jobs_, key); -} - void QuicStreamFactory::ActivateSession( const QuicServerId& server_id, QuicClientSession* session) { @@ -1166,6 +1214,20 @@ return stats->srtt.InMicroseconds(); } +bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( + const QuicServerId& server_id) const { + return http_server_properties_ && + http_server_properties_->WasAlternateProtocolRecentlyBroken( + server_id.host_port_pair()); +} + +bool QuicStreamFactory::CryptoConfigCacheIsEmpty( + const QuicServerId& server_id) { + QuicCryptoClientConfig::CachedState* cached = + crypto_config_.LookupOrCreate(server_id); + return cached->IsEmpty(); +} + void QuicStreamFactory::InitializeCachedStateInCryptoConfig( const QuicServerId& server_id, const scoped_ptr<QuicServerInfo>& server_info) {
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index f13156a..9b38e0b 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h
@@ -178,6 +178,11 @@ quic_server_info_factory_ = quic_server_info_factory; } + bool enable_connection_racing() const { return enable_connection_racing_; } + void set_enable_connection_racing(bool enable_connection_racing) { + enable_connection_racing_ = enable_connection_racing; + } + private: class Job; friend class test::QuicStreamFactoryPeer; @@ -204,10 +209,17 @@ typedef std::set<QuicClientSession*> SessionSet; typedef std::map<IpAliasKey, SessionSet> IPAliasMap; typedef std::map<QuicServerId, QuicCryptoClientConfig*> CryptoConfigMap; - typedef std::map<QuicServerId, Job*> JobMap; - typedef std::map<QuicStreamRequest*, Job*> RequestMap; + typedef std::set<Job*> JobSet; + typedef std::map<QuicServerId, JobSet> JobMap; + typedef std::map<QuicStreamRequest*, QuicServerId> RequestMap; typedef std::set<QuicStreamRequest*> RequestSet; - typedef std::map<Job*, RequestSet> JobRequestsMap; + typedef std::map<QuicServerId, RequestSet> ServerIDRequestsMap; + + // Creates a job which doesn't wait for server config to be loaded from the + // disk cache. This job is started via a PostTask. + void CreateAuxilaryJob(const QuicServerId server_id, + bool is_post, + const BoundNetLog& net_log); // Returns a newly created QuicHttpStream owned by the caller, if a // matching session already exists. Returns NULL otherwise. @@ -233,6 +245,10 @@ int64 GetServerNetworkStatsSmoothedRttInMicroseconds( const QuicServerId& server_id) const; + // Helped methods. + bool WasAlternateProtocolRecentlyBroken(const QuicServerId& server_id) const; + bool CryptoConfigCacheIsEmpty(const QuicServerId& server_id); + // Initializes the cached state associated with |server_id| in // |crypto_config_| with the information in |server_info|. void InitializeCachedStateInCryptoConfig( @@ -274,7 +290,7 @@ QuicCryptoClientConfig crypto_config_; JobMap active_jobs_; - JobRequestsMap job_requests_map_; + ServerIDRequestsMap job_requests_map_; RequestMap active_requests_; QuicVersionVector supported_versions_; @@ -305,6 +321,11 @@ // Set this for setting config's BytesForConnectionIdToSend (TCID param) to 0. bool enable_truncated_connection_ids_; + // Set if we want to race connections - one connection that sends + // INCHOATE_HELLO and another connection that sends CHLO after loading server + // config from the disk cache. + bool enable_connection_racing_; + // Each profile will (probably) have a unique port_seed_ value. This value is // used to help seed a pseudo-random number generator (PortSuggester) so that // we consistently (within this profile) suggest the same ephemeral port when
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 2ce6ef4..739fa21 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -34,6 +34,7 @@ #include "testing/gtest/include/gtest/gtest.h" using base::StringPiece; +using std::ostream; using std::string; using std::vector; @@ -43,6 +44,34 @@ namespace { const char kDefaultServerHostName[] = "www.google.com"; const int kDefaultServerPort = 443; + +// Run all tests with all the combinations of versions and +// enable_connection_racing. +struct TestParams { + TestParams(const QuicVersion version, bool enable_connection_racing) + : version(version), enable_connection_racing(enable_connection_racing) {} + + friend ostream& operator<<(ostream& os, const TestParams& p) { + os << "{ version: " << QuicVersionToString(p.version); + os << " enable_connection_racing: " << p.enable_connection_racing << " }"; + return os; + } + + QuicVersion version; + bool enable_connection_racing; +}; + +// Constructs various test permutations. +vector<TestParams> GetTestParams() { + vector<TestParams> params; + QuicVersionVector all_supported_versions = QuicSupportedVersions(); + for (const QuicVersion version : all_supported_versions) { + params.push_back(TestParams(version, false)); + params.push_back(TestParams(version, true)); + } + return params; +} + } // namespace anonymous class QuicStreamFactoryPeer { @@ -100,6 +129,16 @@ size_t load_server_info_timeout) { factory->load_server_info_timeout_ms_ = load_server_info_timeout; } + + static void SetEnableConnectionRacing(QuicStreamFactory* factory, + bool enable_connection_racing) { + factory->enable_connection_racing_ = enable_connection_racing; + } + + static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory, + const QuicServerId& server_id) { + return (factory->active_jobs_[server_id]).size(); + } }; class MockQuicServerInfo : public QuicServerInfo { @@ -135,14 +174,13 @@ } }; - -class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { +class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> { protected: QuicStreamFactoryTest() : random_generator_(0), clock_(new MockClock()), runner_(new TestTaskRunner(clock_)), - maker_(GetParam(), 0, clock_), + maker_(GetParam().version, 0, clock_), cert_verifier_(CertVerifier::CreateDefault()), channel_id_service_( new ChannelIDService(new DefaultChannelIDStore(nullptr), @@ -158,7 +196,7 @@ clock_, kDefaultMaxPacketSize, std::string(), - SupportedVersions(GetParam()), + SupportedVersions(GetParam().version), /*enable_port_selection=*/true, /*always_require_handshake_confirmation=*/false, /*disable_connection_pooling=*/false, @@ -171,6 +209,8 @@ privacy_mode_(PRIVACY_MODE_DISABLED) { factory_.set_require_confirmation(false); clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); + QuicStreamFactoryPeer::SetEnableConnectionRacing( + &factory_, GetParam().enable_connection_racing); } scoped_ptr<QuicHttpStream> CreateIfSessionExists( @@ -244,7 +284,7 @@ QuicStreamId stream_id = kClientDataStreamId1; return maker_.MakeRstPacket( 1, true, stream_id, - AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam())); + AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam().version)); } MockQuicServerInfoFactory quic_server_info_factory_; @@ -266,8 +306,9 @@ TestCompletionCallback callback_; }; -INSTANTIATE_TEST_CASE_P(Version, QuicStreamFactoryTest, - ::testing::ValuesIn(QuicSupportedVersions())); +INSTANTIATE_TEST_CASE_P(Version, + QuicStreamFactoryTest, + ::testing::ValuesIn(GetTestParams())); TEST_P(QuicStreamFactoryTest, CreateIfSessionExists) { EXPECT_EQ(nullptr, CreateIfSessionExists(host_port_pair_, net_log_).get()); @@ -1562,6 +1603,10 @@ } TEST_P(QuicStreamFactoryTest, CancelWaitForDataReady) { + // Don't race quic connections when testing cancel reading of server config + // from disk cache. + if (GetParam().enable_connection_racing) + return; factory_.set_quic_server_info_factory(&quic_server_info_factory_); QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get()); const size_t kLoadServerInfoTimeoutMs = 50; @@ -1604,5 +1649,52 @@ EXPECT_TRUE(socket_data.at_write_eof()); } +TEST_P(QuicStreamFactoryTest, RacingConnections) { + if (!GetParam().enable_connection_racing) + return; + factory_.set_quic_server_info_factory(&quic_server_info_factory_); + QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get()); + const size_t kLoadServerInfoTimeoutMs = 50; + QuicStreamFactoryPeer::SetLoadServerInfoTimeout(&factory_, + kLoadServerInfoTimeoutMs); + + MockRead reads[] = { + MockRead(ASYNC, OK, 0) // EOF + }; + DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0); + socket_factory_.AddSocketDataProvider(&socket_data); + socket_data.StopAfter(1); + + MockRead reads2[] = { + MockRead(ASYNC, 0, 0) // EOF + }; + DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0); + socket_factory_.AddSocketDataProvider(&socket_data2); + socket_data2.StopAfter(1); + + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + + QuicStreamRequest request(&factory_); + QuicServerId server_id(host_port_pair_, is_https_, privacy_mode_); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, is_https_, privacy_mode_, "GET", + net_log_, callback_.callback())); + EXPECT_EQ(2u, + QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id)); + + runner_->RunNextTask(); + + scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); + EXPECT_TRUE(stream.get()); + EXPECT_TRUE(socket_data.at_read_eof()); + EXPECT_TRUE(socket_data.at_write_eof()); + EXPECT_EQ(0u, + QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id)); +} + } // namespace test } // namespace net
diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc index ceeaa94..7a9ae0d 100644 --- a/net/quic/quic_stream_sequencer.cc +++ b/net/quic/quic_stream_sequencer.cc
@@ -25,7 +25,8 @@ blocked_(false), num_bytes_buffered_(0), num_frames_received_(0), - num_duplicate_frames_received_(0) { + num_duplicate_frames_received_(0), + num_early_frames_received_(0) { } QuicStreamSequencer::~QuicStreamSequencer() { @@ -64,6 +65,10 @@ IOVector data; data.AppendIovec(frame.data.iovec(), frame.data.Size()); + if (byte_offset > num_bytes_consumed_) { + ++num_early_frames_received_; + } + // If the frame has arrived in-order then we can process it immediately, only // buffering if the stream is unable to process it. if (!blocked_ && byte_offset == num_bytes_consumed_) {
diff --git a/net/quic/quic_stream_sequencer.h b/net/quic/quic_stream_sequencer.h index f34d735..3570d3b 100644 --- a/net/quic/quic_stream_sequencer.h +++ b/net/quic/quic_stream_sequencer.h
@@ -75,6 +75,8 @@ return num_duplicate_frames_received_; } + int num_early_frames_received() const { return num_early_frames_received_; } + private: friend class test::QuicStreamSequencerPeer; @@ -122,6 +124,10 @@ // Count of the number of duplicate frames received. int num_duplicate_frames_received_; + // Count of the number of frames received before all previous frames were + // received. + int num_early_frames_received_; + DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencer); };
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc index 8a71c4c..9db0234 100644 --- a/net/quic/quic_stream_sequencer_test.cc +++ b/net/quic/quic_stream_sequencer_test.cc
@@ -226,6 +226,7 @@ EXPECT_EQ(1u, buffered_frames_->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); EXPECT_EQ("abc", buffered_frames_->find(0)->second); + EXPECT_EQ(0, sequencer_->num_early_frames_received()); } TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { @@ -233,6 +234,7 @@ EXPECT_EQ(1u, buffered_frames_->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); EXPECT_EQ("abc", buffered_frames_->find(3)->second); + EXPECT_EQ(1, sequencer_->num_early_frames_received()); } TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc index 76a31da..8d7e6bb 100644 --- a/net/quic/quic_unacked_packet_map.cc +++ b/net/quic/quic_unacked_packet_map.cc
@@ -54,7 +54,7 @@ transmission_type, sent_time); DCHECK(packet.packet != nullptr); - info.is_fec_packet = packet.packet->is_fec_packet(); + info.is_fec_packet = packet.is_fec_packet; if (old_sequence_number == 0) { if (packet.retransmittable_frames != nullptr &&
diff --git a/net/quic/quic_unacked_packet_map_test.cc b/net/quic/quic_unacked_packet_map_test.cc index 7840495..371d462 100644 --- a/net/quic/quic_unacked_packet_map_test.cc +++ b/net/quic/quic_unacked_packet_map_test.cc
@@ -30,18 +30,18 @@ SerializedPacket CreateRetransmittablePacket( QuicPacketSequenceNumber sequence_number) { - packets_.push_back(QuicPacket::NewDataPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_1BYTE_SEQUENCE_NUMBER)); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_1BYTE_SEQUENCE_NUMBER)); return SerializedPacket(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER, packets_.back(), 0, new RetransmittableFrames()); } SerializedPacket CreateNonRetransmittablePacket( QuicPacketSequenceNumber sequence_number) { - packets_.push_back(QuicPacket::NewDataPacket( - nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, - PACKET_1BYTE_SEQUENCE_NUMBER)); + packets_.push_back(new QuicPacket(nullptr, kDefaultLength, false, + PACKET_8BYTE_CONNECTION_ID, false, + PACKET_1BYTE_SEQUENCE_NUMBER)); return SerializedPacket(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER, packets_.back(), 0, nullptr); }
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc index f8b31c40..a17c5173 100644 --- a/net/quic/quic_utils.cc +++ b/net/quic/quic_utils.cc
@@ -221,6 +221,7 @@ RETURN_STRING_LITERAL(QUIC_VERSION_NEGOTIATION_MISMATCH); RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS); RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS); + RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED); RETURN_STRING_LITERAL(QUIC_LAST_ERROR); // Intentionally have no default case, so we'll break the build // if we add errors and don't put them here.
diff --git a/net/quic/test_tools/quic_config_peer.cc b/net/quic/test_tools/quic_config_peer.cc index 53ca554..05f7538 100644 --- a/net/quic/test_tools/quic_config_peer.cc +++ b/net/quic/test_tools/quic_config_peer.cc
@@ -45,10 +45,5 @@ config->bytes_for_connection_id_.SetReceivedValue(bytes); } -// static -QuicTag QuicConfigPeer::CongestionFeedback(QuicConfig* config) { - return config->congestion_feedback_.GetTag(); -} - } // namespace test } // namespace net
diff --git a/net/quic/test_tools/quic_config_peer.h b/net/quic/test_tools/quic_config_peer.h index 410c8182..ca2a3391 100644 --- a/net/quic/test_tools/quic_config_peer.h +++ b/net/quic/test_tools/quic_config_peer.h
@@ -30,8 +30,6 @@ static void SetReceivedBytesForConnectionId(QuicConfig* config, uint32 bytes); - static QuicTag CongestionFeedback(QuicConfig* config); - private: DISALLOW_COPY_AND_ASSIGN(QuicConfigPeer); };
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc index 9253e55..201d451b 100644 --- a/net/quic/test_tools/quic_connection_peer.cc +++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -5,7 +5,6 @@ #include "net/quic/test_tools/quic_connection_peer.h" #include "base/stl_util.h" -#include "net/quic/congestion_control/receive_algorithm_interface.h" #include "net/quic/congestion_control/send_algorithm_interface.h" #include "net/quic/quic_connection.h" #include "net/quic/quic_packet_writer.h" @@ -23,14 +22,6 @@ } // static -void QuicConnectionPeer::SetReceiveAlgorithm( - QuicConnection* connection, - ReceiveAlgorithmInterface* receive_algorithm) { - connection->received_packet_manager_.receive_algorithm_.reset( - receive_algorithm); -} - -// static void QuicConnectionPeer::SetSendAlgorithm( QuicConnection* connection, SendAlgorithmInterface* send_algorithm) { @@ -38,14 +29,16 @@ } // static -QuicAckFrame* QuicConnectionPeer::CreateAckFrame(QuicConnection* connection) { - return connection->CreateAckFrame(); +void QuicConnectionPeer::PopulateAckFrame(QuicConnection* connection, + QuicAckFrame* ack) { + connection->PopulateAckFrame(ack); } // static -QuicStopWaitingFrame* QuicConnectionPeer::CreateStopWaitingFrame( - QuicConnection* connection) { - return connection->CreateStopWaitingFrame(); +void QuicConnectionPeer::PopulateStopWaitingFrame( + QuicConnection* connection, + QuicStopWaitingFrame* stop_waiting) { + connection->PopulateStopWaitingFrame(stop_waiting); } // static
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h index 7cbbb1f..086e353 100644 --- a/net/quic/test_tools/quic_connection_peer.h +++ b/net/quic/test_tools/quic_connection_peer.h
@@ -26,7 +26,6 @@ class QuicPacketWriter; class QuicReceivedPacketManager; class QuicSentPacketManager; -class ReceiveAlgorithmInterface; class SendAlgorithmInterface; namespace test { @@ -36,16 +35,13 @@ public: static void SendAck(QuicConnection* connection); - static void SetReceiveAlgorithm(QuicConnection* connection, - ReceiveAlgorithmInterface* receive_algorithm); - static void SetSendAlgorithm(QuicConnection* connection, SendAlgorithmInterface* send_algorithm); - static QuicAckFrame* CreateAckFrame(QuicConnection* connection); + static void PopulateAckFrame(QuicConnection* connection, QuicAckFrame* ack); - static QuicStopWaitingFrame* CreateStopWaitingFrame( - QuicConnection* connection); + static void PopulateStopWaitingFrame(QuicConnection* connection, + QuicStopWaitingFrame* stop_waiting); static QuicConnectionVisitorInterface* GetVisitor( QuicConnection* connection);
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 4092365..40528285 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc
@@ -1126,6 +1126,10 @@ void ClientSocketPoolBaseHelper::InvokeUserCallback( ClientSocketHandle* handle) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455884 ClientSocketPoolBaseHelper::InvokeUserCallback")); PendingCallbackMap::iterator it = pending_callback_map_.find(handle); // Exit if the request has already been cancelled.
diff --git a/net/socket/socks_client_socket_pool.cc b/net/socket/socks_client_socket_pool.cc index e11b7a48..e431227 100644 --- a/net/socket/socks_client_socket_pool.cc +++ b/net/socket/socks_client_socket_pool.cc
@@ -76,6 +76,9 @@ } void SOCKSConnectJob::OnIOComplete(int result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION("455884 SOCKSConnectJob::OnIOComplete")); int rv = DoLoop(result); if (rv != ERR_IO_PENDING) NotifyDelegateOfCompletion(rv); // Deletes |this|
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 483c5e7..011474f 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc
@@ -2288,7 +2288,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile1( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "SSLClientSocketNSS::Core::DoReadCallback")); + "418183 SSLClientSocketNSS::Core::DoReadCallback")); PostOrRunCallback( FROM_HERE, base::Bind(base::ResetAndReturn(&user_read_callback_), rv));
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index 7734d64..bfc37e6 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc
@@ -247,6 +247,9 @@ } void SSLConnectJob::OnIOComplete(int result) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455884 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION("455884 SSLConnectJob::OnIOComplete")); int rv = DoLoop(result); if (rv != ERR_IO_PENDING) NotifyDelegateOfCompletion(rv); // Deletes |this|.
diff --git a/net/socket/stream_listen_socket.cc b/net/socket/stream_listen_socket.cc index abb5fbc..619070d 100644 --- a/net/socket/stream_listen_socket.cc +++ b/net/socket/stream_listen_socket.cc
@@ -249,7 +249,8 @@ void StreamListenSocket::OnObjectSignaled(HANDLE object) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("StreamListenSocket_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 StreamListenSocket::OnObjectSignaled")); WSANETWORKEVENTS ev; if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) {
diff --git a/net/socket/tcp_client_socket.cc b/net/socket/tcp_client_socket.cc index 8eda581..8e719f0 100644 --- a/net/socket/tcp_client_socket.cc +++ b/net/socket/tcp_client_socket.cc
@@ -327,7 +327,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "TCPClientSocket::DidCompleteReadWrite")); + "418183 TCPClientSocket::DidCompleteReadWrite")); callback.Run(result); }
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc index 0031c63..538c8d7 100644 --- a/net/socket/tcp_socket_win.cc +++ b/net/socket/tcp_socket_win.cc
@@ -250,7 +250,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "TCPSocketWin_Core_ReadDelegate_OnObjectSignaled")); + "418183 TCPSocketWin::Core::ReadDelegate::OnObjectSignaled")); DCHECK_EQ(object, core_->read_overlapped_.hEvent); if (core_->socket_) { @@ -268,7 +268,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "TCPSocketWin_Core_WriteDelegate_OnObjectSignaled")); + "418183 TCPSocketWin::Core::WriteDelegate::OnObjectSignaled")); DCHECK_EQ(object, core_->write_overlapped_.hEvent); if (core_->socket_) @@ -774,7 +774,8 @@ void TCPSocketWin::OnObjectSignaled(HANDLE object) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("TCPSocketWin_OnObjectSignaled")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418383 TCPSocketWin::OnObjectSignaled")); WSANETWORKEVENTS ev; if (WSAEnumNetworkEvents(socket_, accept_event_, &ev) == SOCKET_ERROR) { @@ -963,6 +964,10 @@ DCHECK(!read_callback_.is_null()); int result; + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidCompleteConnect1")); WSANETWORKEVENTS events; int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); @@ -972,6 +977,11 @@ os_error = WSAGetLastError(); result = MapSystemError(os_error); } else if (events.lNetworkEvents & FD_CONNECT) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidCompleteConnect2")); os_error = events.iErrorCode[FD_CONNECT_BIT]; result = MapConnectError(os_error); } else { @@ -979,10 +989,18 @@ result = ERR_UNEXPECTED; } + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidCompleteConnect3")); connect_os_error_ = os_error; DoConnectComplete(result); waiting_connect_ = false; + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is fixed. + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidCompleteConnect4")); DCHECK_NE(result, ERR_IO_PENDING); base::ResetAndReturn(&read_callback_).Run(result); } @@ -1030,6 +1048,9 @@ DCHECK(waiting_read_); DCHECK(!read_callback_.is_null()); + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION("418183 TCPSocketWin::DidSignalRead1")); int os_error = 0; WSANETWORKEVENTS network_events; int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, @@ -1038,6 +1059,11 @@ os_error = WSAGetLastError(); rv = MapSystemError(os_error); } else if (network_events.lNetworkEvents) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidSignalRead2")); DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); // If network_events.lNetworkEvents is FD_CLOSE and // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful @@ -1058,6 +1084,11 @@ if (rv == ERR_IO_PENDING) return; } else { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/418183 is + // fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "418183 TCPSocketWin::DidSignalRead3")); // This may happen because Read() may succeed synchronously and // consume all the received data without resetting the event object. core_->WatchForRead(); @@ -1068,10 +1099,10 @@ core_->read_iobuffer_ = NULL; core_->read_buffer_length_ = 0; - DCHECK_NE(rv, ERR_IO_PENDING); // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. - tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("TCPSocketWin::DidSignalRead")); + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION("418183 TCPSocketWin::DidSignalRead4")); + DCHECK_NE(rv, ERR_IO_PENDING); base::ResetAndReturn(&read_callback_).Run(rv); }
diff --git a/net/test/spawned_test_server/remote_test_server.h b/net/test/spawned_test_server/remote_test_server.h index de12e4eb..a8b8bb2c 100644 --- a/net/test/spawned_test_server/remote_test_server.h +++ b/net/test/spawned_test_server/remote_test_server.h
@@ -29,7 +29,7 @@ const SSLOptions& ssl_options, const base::FilePath& document_root); - virtual ~RemoteTestServer(); + ~RemoteTestServer() override; // Starts the Python test server on the host, instead of on the device, and // blocks until the server is ready.
diff --git a/net/test/spawned_test_server/spawner_communicator.cc b/net/test/spawned_test_server/spawner_communicator.cc index 53484ea..bb1b445 100644 --- a/net/test/spawned_test_server/spawner_communicator.cc +++ b/net/test/spawned_test_server/spawner_communicator.cc
@@ -47,7 +47,7 @@ data_received_->clear(); } - virtual ~SpawnerRequestData() {} + ~SpawnerRequestData() override {} bool DoesRequestIdMatch(int request_id) const { return request_id_ == request_id;
diff --git a/net/test/spawned_test_server/spawner_communicator.h b/net/test/spawned_test_server/spawner_communicator.h index 549ad915..ba8bfcab 100644 --- a/net/test/spawned_test_server/spawner_communicator.h +++ b/net/test/spawned_test_server/spawner_communicator.h
@@ -61,7 +61,7 @@ class SpawnerCommunicator : public net::URLRequest::Delegate { public: explicit SpawnerCommunicator(uint16 port); - virtual ~SpawnerCommunicator(); + ~SpawnerCommunicator() override; // Starts an instance of the Python test server on the host/ machine. // If successfully started, returns true, setting |*port| to the port @@ -100,8 +100,8 @@ std::string* data_received); // URLRequest::Delegate methods. Called on the IO thread. - virtual void OnResponseStarted(URLRequest* request) override; - virtual void OnReadCompleted(URLRequest* request, int num_bytes) override; + void OnResponseStarted(URLRequest* request) override; + void OnReadCompleted(URLRequest* request, int num_bytes) override; // Reads Result from the response. Called on the IO thread. void ReadResult(URLRequest* request);
diff --git a/net/tools/net_watcher/net_watcher.cc b/net/tools/net_watcher/net_watcher.cc index b6cf393..fb5c8e4 100644 --- a/net/tools/net_watcher/net_watcher.cc +++ b/net/tools/net_watcher/net_watcher.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/profiler/scoped_tracker.h" #include "base/values.h" #include "build/build_config.h" #include "net/base/network_change_notifier.h" @@ -114,6 +115,11 @@ void OnProxyConfigChanged( const net::ProxyConfig& config, net::ProxyConfigService::ConfigAvailability availability) override { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455942 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455942 NetWatcher::OnProxyConfigChanged")); LOG(INFO) << "OnProxyConfigChanged(" << ProxyConfigToString(config) << ", " << ConfigAvailabilityToString(availability) << ")";
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc index 29d11bc5..000a686a 100644 --- a/net/tools/quic/quic_client.cc +++ b/net/tools/quic/quic_client.cc
@@ -12,7 +12,6 @@ #include <unistd.h> #include "base/logging.h" -#include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/crypto/quic_random.h" #include "net/quic/quic_connection.h" #include "net/quic/quic_data_reader.h" @@ -138,12 +137,11 @@ } if (!QuicSocketUtils::SetReceiveBufferSize(fd_, - TcpReceiver::kReceiveWindowTCP)) { + kDefaultSocketReceiveBuffer)) { return false; } - if (!QuicSocketUtils::SetSendBufferSize(fd_, - TcpReceiver::kReceiveWindowTCP)) { + if (!QuicSocketUtils::SetSendBufferSize(fd_, kDefaultSocketReceiveBuffer)) { return false; }
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 1771026..46f672ea 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -209,6 +209,13 @@ const QuicPacketPublicHeader& header) { QuicSession* session = nullptr; + // Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC. + // Given that we can't even send a reply rejecting the packet, just black hole + // it. + if (current_client_address_.port() == 0) { + return false; + } + QuicConnectionId connection_id = header.connection_id; SessionMap::iterator it = session_map_.find(connection_id); if (it == session_map_.end()) {
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index fc1e10d..6ef1b16 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -97,12 +97,29 @@ return *session; } +class MockTimeWaitListManager : public QuicTimeWaitListManager { + public: + MockTimeWaitListManager(QuicPacketWriter* writer, + QuicServerSessionVisitor* visitor, + EpollServer* eps) + : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { + } + + MOCK_METHOD5(ProcessPacket, + void(const IPEndPoint& server_address, + const IPEndPoint& client_address, + QuicConnectionId connection_id, + QuicPacketSequenceNumber sequence_number, + const QuicEncryptedPacket& packet)); +}; + class QuicDispatcherTest : public ::testing::Test { public: QuicDispatcherTest() : crypto_config_(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance()), dispatcher_(config_, crypto_config_, &eps_), + time_wait_list_manager_(nullptr), session1_(nullptr), session2_(nullptr) { dispatcher_.Initialize(1); @@ -133,11 +150,20 @@ EXPECT_EQ(data_, packet.AsStringPiece()); } + void CreateTimeWaitListManager() { + time_wait_list_manager_ = new MockTimeWaitListManager( + QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); + // dispatcher takes the ownership of time_wait_list_manager. + QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, + time_wait_list_manager_); + } + EpollServer eps_; QuicConfig config_; QuicCryptoServerConfig crypto_config_; IPEndPoint server_address_; TestDispatcher dispatcher_; + MockTimeWaitListManager* time_wait_list_manager_; MockSession* session1_; MockSession* session2_; string data_; @@ -184,28 +210,9 @@ dispatcher_.Shutdown(); } -class MockTimeWaitListManager : public QuicTimeWaitListManager { - public: - MockTimeWaitListManager(QuicPacketWriter* writer, - QuicServerSessionVisitor* visitor, - EpollServer* eps) - : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { - } - - MOCK_METHOD5(ProcessPacket, void(const IPEndPoint& server_address, - const IPEndPoint& client_address, - QuicConnectionId connection_id, - QuicPacketSequenceNumber sequence_number, - const QuicEncryptedPacket& packet)); -}; - TEST_F(QuicDispatcherTest, TimeWaitListManager) { - MockTimeWaitListManager* time_wait_list_manager = - new MockTimeWaitListManager( - QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); - // dispatcher takes the ownership of time_wait_list_manager. - QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, - time_wait_list_manager); + CreateTimeWaitListManager(); + // Create a new session. IPEndPoint client_address(net::test::Loopback4(), 1); QuicConnectionId connection_id = 1; @@ -233,34 +240,44 @@ reinterpret_cast<MockConnection*>(session1_->connection()), &MockConnection::ReallyProcessUdpPacket)); dispatcher_.ProcessPacket(IPEndPoint(), client_address, *encrypted); - EXPECT_TRUE(time_wait_list_manager->IsConnectionIdInTimeWait(connection_id)); + EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); // Dispatcher forwards subsequent packets for this connection_id to the time // wait list manager. - EXPECT_CALL(*time_wait_list_manager, + EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id, _, _)).Times(1); ProcessPacket(client_address, connection_id, true, "foo"); } TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { - MockTimeWaitListManager* time_wait_list_manager = - new MockTimeWaitListManager( - QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); - // dispatcher takes the ownership of time_wait_list_manager. - QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, - time_wait_list_manager); + CreateTimeWaitListManager(); IPEndPoint client_address(net::test::Loopback4(), 1); QuicConnectionId connection_id = 1; // Dispatcher forwards all packets for this connection_id to the time wait // list manager. EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager, + EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id, _, _)).Times(1); string data = "foo"; ProcessPacket(client_address, connection_id, false, "foo"); } +TEST_F(QuicDispatcherTest, ProcessPacketWithBogusPort) { + CreateTimeWaitListManager(); + + IPEndPoint client_address(net::test::Loopback4(), 0); + IPAddressNumber any4; + CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); + server_address_ = IPEndPoint(any4, 5); + + EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address)).Times(0); + EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); + ProcessPacket(client_address, 1, true, "foo"); + EXPECT_EQ(client_address, dispatcher_.current_client_address()); + EXPECT_EQ(server_address_, dispatcher_.current_server_address()); +} + class BlockingWriter : public QuicPacketWriterWrapper { public: BlockingWriter() : write_blocked_(false) {}
diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc index 7635b53..341daf8 100644 --- a/net/tools/quic/quic_server.cc +++ b/net/tools/quic/quic_server.cc
@@ -12,7 +12,6 @@ #include <sys/socket.h> #include "net/base/ip_endpoint.h" -#include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/crypto/crypto_handshake.h" #include "net/quic/crypto/quic_random.h" #include "net/quic/quic_clock.h" @@ -130,12 +129,11 @@ // because the default usage of QuicServer is as a test server with one or // two clients. Adjust higher for use with many clients. if (!QuicSocketUtils::SetReceiveBufferSize(fd_, - TcpReceiver::kReceiveWindowTCP)) { + kDefaultSocketReceiveBuffer)) { return false; } - if (!QuicSocketUtils::SetSendBufferSize(fd_, - TcpReceiver::kReceiveWindowTCP)) { + if (!QuicSocketUtils::SetSendBufferSize(fd_, kDefaultSocketReceiveBuffer)) { return false; }
diff --git a/net/tools/quic/test_tools/packet_dropping_test_writer.h b/net/tools/quic/test_tools/packet_dropping_test_writer.h index 6dcb1b9..cdd8efc 100644 --- a/net/tools/quic/test_tools/packet_dropping_test_writer.h +++ b/net/tools/quic/test_tools/packet_dropping_test_writer.h
@@ -85,8 +85,7 @@ fake_packet_reorder_percentage_ = fake_packet_reorder_percentage; } - // The percent of time WritePacket will block and set WriteResult's status - // to WRITE_STATUS_BLOCKED. + // The delay before writing this packet. void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) { DCHECK(clock_); base::AutoLock locked(config_mutex_);
diff --git a/net/udp/udp_client_socket.cc b/net/udp/udp_client_socket.cc index 9cdaace..8ea024d 100644 --- a/net/udp/udp_client_socket.cc +++ b/net/udp/udp_client_socket.cc
@@ -62,4 +62,10 @@ return socket_.NetLog(); } +#if defined(OS_WIN) +void UDPClientSocket::UseNonBlockingIO() { + socket_.UseNonBlockingIO(); +} +#endif + } // namespace net
diff --git a/net/udp/udp_client_socket.h b/net/udp/udp_client_socket.h index 427db7e..7b4e1a6 100644 --- a/net/udp/udp_client_socket.h +++ b/net/udp/udp_client_socket.h
@@ -38,6 +38,12 @@ int SetSendBufferSize(int32 size) override; const BoundNetLog& NetLog() const override; +#if defined(OS_WIN) + // Switch to use non-blocking IO. Must be called right after construction and + // before other calls. + void UseNonBlockingIO(); +#endif + private: UDPSocket socket_; DISALLOW_COPY_AND_ASSIGN(UDPClientSocket);
diff --git a/net/udp/udp_server_socket.cc b/net/udp/udp_server_socket.cc index 4653f71..9fc92df0 100644 --- a/net/udp/udp_server_socket.cc +++ b/net/udp/udp_server_socket.cc
@@ -120,4 +120,10 @@ socket_.DetachFromThread(); } +#if defined(OS_WIN) +void UDPServerSocket::UseNonBlockingIO() { + socket_.UseNonBlockingIO(); +} +#endif + } // namespace net
diff --git a/net/udp/udp_server_socket.h b/net/udp/udp_server_socket.h index 0799105..dabb8f0 100644 --- a/net/udp/udp_server_socket.h +++ b/net/udp/udp_server_socket.h
@@ -47,6 +47,12 @@ int SetDiffServCodePoint(DiffServCodePoint dscp) override; void DetachFromThread() override; +#if defined(OS_WIN) + // Switch to use non-blocking IO. Must be called right after construction and + // before other calls. + void UseNonBlockingIO(); +#endif + private: UDPSocket socket_; bool allow_address_reuse_;
diff --git a/net/udp/udp_socket_perftest.cc b/net/udp/udp_socket_perftest.cc new file mode 100644 index 0000000..86f0729 --- /dev/null +++ b/net/udp/udp_socket_perftest.cc
@@ -0,0 +1,141 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/basictypes.h" +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/perf_time_logger.h" +#include "net/base/io_buffer.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_errors.h" +#include "net/base/net_log_unittest.h" +#include "net/base/net_util.h" +#include "net/base/test_completion_callback.h" +#include "net/test/net_test_suite.h" +#include "net/udp/udp_client_socket.h" +#include "net/udp/udp_server_socket.h" +#include "net/udp/udp_socket.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace { + +class UDPSocketPerfTest : public PlatformTest { + public: + UDPSocketPerfTest() + : buffer_(new net::IOBufferWithSize(kPacketSize)), weak_factory_(this) {} + + void DoneWritePacketsToSocket(net::UDPClientSocket* socket, + int num_of_packets, + base::Closure done_callback, + int error) { + WritePacketsToSocket(socket, num_of_packets, done_callback); + } + + // Send |num_of_packets| to |socket|. Invoke |done_callback| when done. + void WritePacketsToSocket(net::UDPClientSocket* socket, + int num_of_packets, + base::Closure done_callback); + + // Use non-blocking IO if |use_nonblocking_io| is true. This variable only + // has effect on Windows. + void WriteBenchmark(bool use_nonblocking_io); + + protected: + static const int kPacketSize = 1024; + scoped_refptr<net::IOBufferWithSize> buffer_; + base::WeakPtrFactory<UDPSocketPerfTest> weak_factory_; +}; + +// Creates and address from an ip/port and returns it in |address|. +void CreateUDPAddress(std::string ip_str, + uint16 port, + net::IPEndPoint* address) { + net::IPAddressNumber ip_number; + bool rv = net::ParseIPLiteralToNumber(ip_str, &ip_number); + if (!rv) + return; + *address = net::IPEndPoint(ip_number, port); +} + +void UDPSocketPerfTest::WritePacketsToSocket(net::UDPClientSocket* socket, + int num_of_packets, + base::Closure done_callback) { + scoped_refptr<net::IOBufferWithSize> io_buffer( + new net::IOBufferWithSize(kPacketSize)); + memset(io_buffer->data(), 'G', kPacketSize); + + while (num_of_packets) { + int rv = + socket->Write(io_buffer.get(), io_buffer->size(), + base::Bind(&UDPSocketPerfTest::DoneWritePacketsToSocket, + weak_factory_.GetWeakPtr(), socket, + num_of_packets - 1, done_callback)); + if (rv == net::ERR_IO_PENDING) + break; + --num_of_packets; + } + if (!num_of_packets) { + done_callback.Run(); + return; + } +} + +void UDPSocketPerfTest::WriteBenchmark(bool use_nonblocking_io) { + base::MessageLoopForIO message_loop; + const uint16 kPort = 9999; + + // Setup the server to listen. + net::IPEndPoint bind_address; + CreateUDPAddress("127.0.0.1", kPort, &bind_address); + net::CapturingNetLog server_log; + scoped_ptr<net::UDPServerSocket> server( + new net::UDPServerSocket(&server_log, net::NetLog::Source())); +#if defined(OS_WIN) + if (use_nonblocking_io) + server->UseNonBlockingIO(); +#endif + int rv = server->Listen(bind_address); + ASSERT_EQ(net::OK, rv); + + // Setup the client. + net::IPEndPoint server_address; + CreateUDPAddress("127.0.0.1", kPort, &server_address); + net::CapturingNetLog client_log; + scoped_ptr<net::UDPClientSocket> client(new net::UDPClientSocket( + net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(), &client_log, + net::NetLog::Source())); +#if defined(OS_WIN) + if (use_nonblocking_io) + client->UseNonBlockingIO(); +#endif + rv = client->Connect(server_address); + EXPECT_EQ(net::OK, rv); + + base::RunLoop run_loop; + base::TimeTicks start_ticks = base::TimeTicks::Now(); + int packets = 100000; + client->SetSendBufferSize(1024); + WritePacketsToSocket(client.get(), packets, run_loop.QuitClosure()); + run_loop.Run(); + + double elapsed = (base::TimeTicks::Now() - start_ticks).InSecondsF(); + LOG(INFO) << "Write speed: " << packets / 1024 / elapsed << " MB/s"; +} + +TEST_F(UDPSocketPerfTest, Write) { + base::PerfTimeLogger timer("UDP_socket_write"); + WriteBenchmark(false); +} + +#if defined(OS_WIN) +TEST_F(UDPSocketPerfTest, WriteNonBlocking) { + base::PerfTimeLogger timer("UDP_socket_write_nonblocking"); + WriteBenchmark(true); +} +#endif + +} // namespace
diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc index 221be01f..4f902a3 100644 --- a/net/udp/udp_socket_unittest.cc +++ b/net/udp/udp_socket_unittest.cc
@@ -9,7 +9,10 @@ #include "base/basictypes.h" #include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" +#include "base/run_loop.h" #include "base/stl_util.h" #include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" @@ -27,9 +30,7 @@ class UDPSocketTest : public PlatformTest { public: - UDPSocketTest() - : buffer_(new IOBufferWithSize(kMaxRead)) { - } + UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {} // Blocks until data is read from the socket. std::string RecvFromSocket(UDPServerSocket* socket) { @@ -112,22 +113,36 @@ return bytes_sent; } + void WriteSocketIgnoreResult(UDPClientSocket* socket, std::string msg) { + WriteSocket(socket, msg); + } + + // Creates an address from ip address and port and writes it to |*address|. + void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) { + IPAddressNumber ip_number; + bool rv = ParseIPLiteralToNumber(ip_str, &ip_number); + if (!rv) + return; + *address = IPEndPoint(ip_number, port); + } + + // Run unit test for a connection test. + // |use_nonblocking_io| is used to switch between overlapped and non-blocking + // IO on Windows. It has no effect in other ports. + void ConnectTest(bool use_nonblocking_io); + protected: static const int kMaxRead = 1024; scoped_refptr<IOBufferWithSize> buffer_; IPEndPoint recv_from_address_; }; -// Creates and address from an ip/port and returns it in |address|. -void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) { - IPAddressNumber ip_number; - bool rv = ParseIPLiteralToNumber(ip_str, &ip_number); - if (!rv) - return; - *address = IPEndPoint(ip_number, port); +void ReadCompleteCallback(int* result_out, base::Closure callback, int result) { + *result_out = result; + callback.Run(); } -TEST_F(UDPSocketTest, Connect) { +void UDPSocketTest::ConnectTest(bool use_nonblocking_io) { const uint16 kPort = 9999; std::string simple_message("hello world!"); @@ -137,6 +152,10 @@ CapturingNetLog server_log; scoped_ptr<UDPServerSocket> server( new UDPServerSocket(&server_log, NetLog::Source())); +#if defined(OS_WIN) + if (use_nonblocking_io) + server->UseNonBlockingIO(); +#endif server->AllowAddressReuse(); int rv = server->Listen(bind_address); ASSERT_EQ(OK, rv); @@ -146,10 +165,13 @@ CreateUDPAddress("127.0.0.1", kPort, &server_address); CapturingNetLog client_log; scoped_ptr<UDPClientSocket> client( - new UDPClientSocket(DatagramSocket::DEFAULT_BIND, - RandIntCallback(), - &client_log, - NetLog::Source())); + new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), + &client_log, NetLog::Source())); +#if defined(OS_WIN) + if (use_nonblocking_io) + client->UseNonBlockingIO(); +#endif + rv = client->Connect(server_address); EXPECT_EQ(OK, rv); @@ -169,6 +191,23 @@ str = ReadSocket(client.get()); DCHECK(simple_message == str); + // Test asynchronous read. Server waits for message. + base::RunLoop run_loop; + int read_result = 0; + rv = server->RecvFrom( + buffer_.get(), kMaxRead, &recv_from_address_, + base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure())); + EXPECT_EQ(ERR_IO_PENDING, rv); + + // Client sends to the server. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&UDPSocketTest::WriteSocketIgnoreResult, + base::Unretained(this), client.get(), simple_message)); + run_loop.Run(); + EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result)); + EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result)); + // Delete sockets so they log their final events. server.reset(); client.reset(); @@ -176,34 +215,48 @@ // Check the server's log. CapturingNetLog::CapturedEntryList server_entries; server_log.GetEntries(&server_entries); - EXPECT_EQ(4u, server_entries.size()); - EXPECT_TRUE(LogContainsBeginEvent( - server_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); + EXPECT_EQ(5u, server_entries.size()); + EXPECT_TRUE( + LogContainsBeginEvent(server_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); EXPECT_TRUE(LogContainsEvent( server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); + EXPECT_TRUE(LogContainsEvent(server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, + NetLog::PHASE_NONE)); EXPECT_TRUE(LogContainsEvent( - server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE)); - EXPECT_TRUE(LogContainsEndEvent( - server_entries, 3, NetLog::TYPE_SOCKET_ALIVE)); + server_entries, 3, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); + EXPECT_TRUE( + LogContainsEndEvent(server_entries, 4, NetLog::TYPE_SOCKET_ALIVE)); // Check the client's log. CapturingNetLog::CapturedEntryList client_entries; client_log.GetEntries(&client_entries); - EXPECT_EQ(6u, client_entries.size()); - EXPECT_TRUE(LogContainsBeginEvent( - client_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); - EXPECT_TRUE(LogContainsBeginEvent( - client_entries, 1, NetLog::TYPE_UDP_CONNECT)); - EXPECT_TRUE(LogContainsEndEvent( - client_entries, 2, NetLog::TYPE_UDP_CONNECT)); - EXPECT_TRUE(LogContainsEvent( - client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE)); + EXPECT_EQ(7u, client_entries.size()); + EXPECT_TRUE( + LogContainsBeginEvent(client_entries, 0, NetLog::TYPE_SOCKET_ALIVE)); + EXPECT_TRUE( + LogContainsBeginEvent(client_entries, 1, NetLog::TYPE_UDP_CONNECT)); + EXPECT_TRUE(LogContainsEndEvent(client_entries, 2, NetLog::TYPE_UDP_CONNECT)); + EXPECT_TRUE(LogContainsEvent(client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, + NetLog::PHASE_NONE)); EXPECT_TRUE(LogContainsEvent( client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE)); - EXPECT_TRUE(LogContainsEndEvent( - client_entries, 5, NetLog::TYPE_SOCKET_ALIVE)); + EXPECT_TRUE(LogContainsEvent(client_entries, 5, NetLog::TYPE_UDP_BYTES_SENT, + NetLog::PHASE_NONE)); + EXPECT_TRUE( + LogContainsEndEvent(client_entries, 6, NetLog::TYPE_SOCKET_ALIVE)); } +TEST_F(UDPSocketTest, Connect) { + // The variable |use_nonblocking_io| has no effect in non-Windows ports. + ConnectTest(false); +} + +#if defined(OS_WIN) +TEST_F(UDPSocketTest, ConnectNonBlocking) { + ConnectTest(true); +} +#endif + #if defined(OS_MACOSX) // UDPSocketPrivate_Broadcast is disabled for OSX because it requires // root permissions on OSX 10.7+.
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc index 3c121b2b..90ce661 100644 --- a/net/udp/udp_socket_win.cc +++ b/net/udp/udp_socket_win.cc
@@ -149,7 +149,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "UDPSocketWin_Core_ReadDelegate_OnObjectSignaled")); + "418183 UDPSocketWin::Core::ReadDelegate::OnObjectSignaled")); DCHECK_EQ(object, core_->read_overlapped_.hEvent); if (core_->socket_) @@ -162,7 +162,7 @@ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( - "UDPSocketWin_Core_WriteDelegate_OnObjectSignaled")); + "418183 UDPSocketWin::Core::WriteDelegate::OnObjectSignaled")); DCHECK_EQ(object, core_->write_overlapped_.hEvent); if (core_->socket_) @@ -261,6 +261,9 @@ multicast_time_to_live_(1), bind_type_(bind_type), rand_int_cb_(rand_int_cb), + use_non_blocking_io_(false), + read_iobuffer_len_(0), + write_iobuffer_len_(0), recv_from_address_(NULL), net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)), qos_handle_(NULL), @@ -285,7 +288,12 @@ socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); if (socket_ == INVALID_SOCKET) return MapSystemError(WSAGetLastError()); - core_ = new Core(this); + if (!use_non_blocking_io_) { + core_ = new Core(this); + } else { + read_write_event_.Set(WSACreateEvent()); + WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); + } return OK; } @@ -312,8 +320,13 @@ addr_family_ = 0; is_connected_ = false; - core_->Detach(); - core_ = NULL; + read_write_watcher_.StopWatching(); + read_write_event_.Close(); + + if (core_) { + core_->Detach(); + core_ = NULL; + } } int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { @@ -377,7 +390,8 @@ DCHECK(!callback.is_null()); // Synchronous operation not supported. DCHECK_GT(buf_len, 0); - int nread = InternalRecvFrom(buf, buf_len, address); + int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address) + : InternalRecvFromNonBlocking(buf, buf_len, address); if (nread != ERR_IO_PENDING) return nread; @@ -410,7 +424,8 @@ DCHECK_GT(buf_len, 0); DCHECK(!send_to_address_.get()); - int nwrite = InternalSendTo(buf, buf_len, address); + int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address) + : InternalSendToNonBlocking(buf, buf_len, address); if (nwrite != ERR_IO_PENDING) return nwrite; @@ -573,38 +588,24 @@ WSAResetEvent(core_->read_overlapped_.hEvent); int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); // Convert address. - if (recv_from_address_ && result >= 0) { - if (!ReceiveAddressToIPEndpoint(recv_from_address_)) + IPEndPoint address; + IPEndPoint* address_to_log = NULL; + if (result >= 0) { + if (address.FromSockAddr(core_->recv_addr_storage_.addr, + core_->recv_addr_storage_.addr_len)) { + if (recv_from_address_) + *recv_from_address_ = address; + address_to_log = &address; + } else { result = ERR_ADDRESS_INVALID; + } } - LogRead(result, core_->read_iobuffer_->data()); + LogRead(result, core_->read_iobuffer_->data(), address_to_log); core_->read_iobuffer_ = NULL; recv_from_address_ = NULL; DoReadCallback(result); } -void UDPSocketWin::LogRead(int result, const char* bytes) const { - if (result < 0) { - net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); - return; - } - - if (net_log_.IsLogging()) { - // Get address for logging, if |address| is NULL. - IPEndPoint address; - bool is_address_valid = ReceiveAddressToIPEndpoint(&address); - net_log_.AddEvent( - NetLog::TYPE_UDP_BYTES_RECEIVED, - CreateNetLogUDPDataTranferCallback( - result, bytes, - is_address_valid ? &address : NULL)); - } - - base::StatsCounter read_bytes("udp.read_bytes"); - read_bytes.Add(result); - NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result); -} - void UDPSocketWin::DidCompleteWrite() { DWORD num_bytes, flags; BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, @@ -618,6 +619,91 @@ DoWriteCallback(result); } +void UDPSocketWin::OnObjectSignaled(HANDLE object) { + DCHECK(object == read_write_event_.Get()); + WSANETWORKEVENTS network_events; + int os_error = 0; + int rv = + WSAEnumNetworkEvents(socket_, read_write_event_.Get(), &network_events); + if (rv == SOCKET_ERROR) { + os_error = WSAGetLastError(); + rv = MapSystemError(os_error); + if (read_iobuffer_) { + read_iobuffer_ = NULL; + read_iobuffer_len_ = 0; + recv_from_address_ = NULL; + DoReadCallback(rv); + } + if (write_iobuffer_) { + write_iobuffer_ = NULL; + write_iobuffer_len_ = 0; + send_to_address_.reset(); + DoWriteCallback(rv); + } + return; + } + if ((network_events.lNetworkEvents & FD_READ) && read_iobuffer_) { + OnReadSignaled(); + } + if ((network_events.lNetworkEvents & FD_WRITE) && write_iobuffer_) { + OnWriteSignaled(); + } + + // There's still pending read / write. Watch for further events. + if (read_iobuffer_ || write_iobuffer_) { + WatchForReadWrite(); + } +} + +void UDPSocketWin::OnReadSignaled() { + int rv = InternalRecvFromNonBlocking(read_iobuffer_.get(), read_iobuffer_len_, + recv_from_address_); + if (rv == ERR_IO_PENDING) + return; + read_iobuffer_ = NULL; + read_iobuffer_len_ = 0; + recv_from_address_ = NULL; + DoReadCallback(rv); +} + +void UDPSocketWin::OnWriteSignaled() { + int rv = InternalSendToNonBlocking(write_iobuffer_.get(), write_iobuffer_len_, + send_to_address_.get()); + if (rv == ERR_IO_PENDING) + return; + write_iobuffer_ = NULL; + write_iobuffer_len_ = 0; + send_to_address_.reset(); + DoWriteCallback(rv); +} + +void UDPSocketWin::WatchForReadWrite() { + if (read_write_watcher_.IsWatching()) + return; + bool watched = + read_write_watcher_.StartWatching(read_write_event_.Get(), this); + DCHECK(watched); +} + +void UDPSocketWin::LogRead(int result, + const char* bytes, + const IPEndPoint* address) const { + if (result < 0) { + net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); + return; + } + + if (net_log_.IsLogging()) { + net_log_.AddEvent( + NetLog::TYPE_UDP_BYTES_RECEIVED, + CreateNetLogUDPDataTranferCallback(result, bytes, address)); + } + + base::StatsCounter read_bytes("udp.read_bytes"); + read_bytes.Add(result); + NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result); +} + void UDPSocketWin::LogWrite(int result, const char* bytes, const IPEndPoint* address) const { @@ -637,8 +723,9 @@ NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); } -int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, - IPEndPoint* address) { +int UDPSocketWin::InternalRecvFromOverlapped(IOBuffer* buf, + int buf_len, + IPEndPoint* address) { DCHECK(!core_->read_iobuffer_.get()); SockaddrStorage& storage = core_->recv_addr_storage_; storage.addr_len = sizeof(storage.addr_storage); @@ -657,18 +744,26 @@ if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { int result = num; // Convert address. - if (address && result >= 0) { - if (!ReceiveAddressToIPEndpoint(address)) + IPEndPoint address_storage; + IPEndPoint* address_to_log = NULL; + if (result >= 0) { + if (address_storage.FromSockAddr(core_->recv_addr_storage_.addr, + core_->recv_addr_storage_.addr_len)) { + if (address) + *address = address_storage; + address_to_log = &address_storage; + } else { result = ERR_ADDRESS_INVALID; + } } - LogRead(result, buf->data()); + LogRead(result, buf->data(), address_to_log); return result; } } else { int os_error = WSAGetLastError(); if (os_error != WSA_IO_PENDING) { int result = MapSystemError(os_error); - LogRead(result, NULL); + LogRead(result, NULL, NULL); return result; } } @@ -677,8 +772,9 @@ return ERR_IO_PENDING; } -int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, - const IPEndPoint* address) { +int UDPSocketWin::InternalSendToOverlapped(IOBuffer* buf, + int buf_len, + const IPEndPoint* address) { DCHECK(!core_->write_iobuffer_.get()); SockaddrStorage storage; struct sockaddr* addr = storage.addr; @@ -723,6 +819,78 @@ return ERR_IO_PENDING; } +int UDPSocketWin::InternalRecvFromNonBlocking(IOBuffer* buf, + int buf_len, + IPEndPoint* address) { + DCHECK(!read_iobuffer_ || read_iobuffer_.get() == buf); + SockaddrStorage storage; + storage.addr_len = sizeof(storage.addr_storage); + + CHECK_NE(INVALID_SOCKET, socket_); + int rv = recvfrom(socket_, buf->data(), buf_len, 0, storage.addr, + &storage.addr_len); + if (rv == SOCKET_ERROR) { + int os_error = WSAGetLastError(); + if (os_error == WSAEWOULDBLOCK) { + read_iobuffer_ = buf; + read_iobuffer_len_ = buf_len; + WatchForReadWrite(); + return ERR_IO_PENDING; + } + rv = MapSystemError(os_error); + LogRead(rv, NULL, NULL); + return rv; + } + IPEndPoint address_storage; + IPEndPoint* address_to_log = NULL; + if (rv >= 0) { + if (address_storage.FromSockAddr(storage.addr, storage.addr_len)) { + if (address) + *address = address_storage; + address_to_log = &address_storage; + } else { + rv = ERR_ADDRESS_INVALID; + } + } + LogRead(rv, buf->data(), address_to_log); + return rv; +} + +int UDPSocketWin::InternalSendToNonBlocking(IOBuffer* buf, + int buf_len, + const IPEndPoint* address) { + DCHECK(!write_iobuffer_ || write_iobuffer_.get() == buf); + SockaddrStorage storage; + struct sockaddr* addr = storage.addr; + // Convert address. + if (address) { + if (!address->ToSockAddr(addr, &storage.addr_len)) { + int result = ERR_ADDRESS_INVALID; + LogWrite(result, NULL, NULL); + return result; + } + } else { + addr = NULL; + storage.addr_len = 0; + } + + int rv = sendto(socket_, buf->data(), buf_len, 0, addr, storage.addr_len); + if (rv == SOCKET_ERROR) { + int os_error = WSAGetLastError(); + if (os_error == WSAEWOULDBLOCK) { + write_iobuffer_ = buf; + write_iobuffer_len_ = buf_len; + WatchForReadWrite(); + return ERR_IO_PENDING; + } + rv = MapSystemError(os_error); + LogWrite(rv, NULL, NULL); + return rv; + } + LogWrite(rv, buf->data(), address); + return rv; +} + int UDPSocketWin::SetMulticastOptions() { if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { DWORD loop = 0; @@ -807,11 +975,6 @@ return DoBind(IPEndPoint(address, 0)); } -bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { - SockaddrStorage& storage = core_->recv_addr_storage_; - return address->FromSockAddr(storage.addr, storage.addr_len); -} - int UDPSocketWin::JoinGroup( const IPAddressNumber& group_address) const { DCHECK(CalledOnValidThread()); @@ -1016,4 +1179,9 @@ base::NonThreadSafe::DetachFromThread(); } +void UDPSocketWin::UseNonBlockingIO() { + DCHECK(!core_); + use_non_blocking_io_ = true; +} + } // namespace net
diff --git a/net/udp/udp_socket_win.h b/net/udp/udp_socket_win.h index 6f0ec2c..d994eece 100644 --- a/net/udp/udp_socket_win.h +++ b/net/udp/udp_socket_win.h
@@ -12,6 +12,7 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "base/win/object_watcher.h" +#include "base/win/scoped_handle.h" #include "net/base/address_family.h" #include "net/base/completion_callback.h" #include "net/base/net_export.h" @@ -23,7 +24,9 @@ namespace net { -class NET_EXPORT UDPSocketWin : NON_EXPORTED_BASE(public base::NonThreadSafe) { +class NET_EXPORT UDPSocketWin + : NON_EXPORTED_BASE(public base::NonThreadSafe), + NON_EXPORTED_BASE(public base::win::ObjectWatcher::Delegate) { public: UDPSocketWin(DatagramSocket::BindType bind_type, const RandIntCallback& rand_int_cb, @@ -174,6 +177,10 @@ // Resets the thread to be used for thread-safety checks. void DetachFromThread(); + // This class by default uses overlapped IO. Call this method before Open() + // to switch to non-blocking IO. + void UseNonBlockingIO(); + private: enum SocketOptions { SOCKET_OPTION_MULTICAST_LOOP = 1 << 0 @@ -183,13 +190,20 @@ void DoReadCallback(int rv); void DoWriteCallback(int rv); + void DidCompleteRead(); void DidCompleteWrite(); + // base::ObjectWatcher::Delegate implementation. + virtual void OnObjectSignaled(HANDLE object); + void OnReadSignaled(); + void OnWriteSignaled(); + + void WatchForReadWrite(); + // Handles stats and logging. |result| is the number of bytes transferred, on - // success, or the net error code on failure. LogRead retrieves the address - // from |recv_addr_storage_|, while LogWrite takes it as an optional argument. - void LogRead(int result, const char* bytes) const; + // success, or the net error code on failure. + void LogRead(int result, const char* bytes, const IPEndPoint* address) const; void LogWrite(int result, const char* bytes, const IPEndPoint* address) const; // Same as SendTo(), except that address is passed by pointer @@ -201,8 +215,22 @@ const CompletionCallback& callback); int InternalConnect(const IPEndPoint& address); - int InternalRecvFrom(IOBuffer* buf, int buf_len, IPEndPoint* address); - int InternalSendTo(IOBuffer* buf, int buf_len, const IPEndPoint* address); + + // Version for using overlapped IO. + int InternalRecvFromOverlapped(IOBuffer* buf, + int buf_len, + IPEndPoint* address); + int InternalSendToOverlapped(IOBuffer* buf, + int buf_len, + const IPEndPoint* address); + + // Version for using non-blocking IO. + int InternalRecvFromNonBlocking(IOBuffer* buf, + int buf_len, + IPEndPoint* address); + int InternalSendToNonBlocking(IOBuffer* buf, + int buf_len, + const IPEndPoint* address); // Applies |socket_options_| to |socket_|. Should be called before // Bind(). @@ -211,10 +239,6 @@ // Binds to a random port on |address|. int RandomBind(const IPAddressNumber& address); - // Attempts to convert the data in |recv_addr_storage_| and |recv_addr_len_| - // to an IPEndPoint and writes it to |address|. Returns true on success. - bool ReceiveAddressToIPEndpoint(IPEndPoint* address) const; - SOCKET socket_; int addr_family_; bool is_connected_; @@ -247,6 +271,22 @@ // they are not destroyed while the OS still references them. scoped_refptr<Core> core_; + // True if non-blocking IO is used. + bool use_non_blocking_io_; + + // Watches |read_write_event_|. + base::win::ObjectWatcher read_write_watcher_; + + // Events for read and write. + base::win::ScopedHandle read_write_event_; + + // The buffers used in Read() and Write(). + scoped_refptr<IOBuffer> read_iobuffer_; + scoped_refptr<IOBuffer> write_iobuffer_; + + int read_iobuffer_len_; + int write_iobuffer_len_; + IPEndPoint* recv_from_address_; // Cached copy of the current address we're sending to, if any. Used for
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc index 40079128..23857ad0 100644 --- a/net/url_request/url_fetcher_core.cc +++ b/net/url_request/url_fetcher_core.cc
@@ -541,6 +541,10 @@ } void URLFetcherCore::StartOnIOThread() { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456327 URLFetcherCore::StartOnIOThread")); DCHECK(network_task_runner_->BelongsToCurrentThread()); if (!response_writer_) @@ -553,6 +557,10 @@ } void URLFetcherCore::StartURLRequest() { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456327 URLFetcherCore::StartURLRequest")); DCHECK(network_task_runner_->BelongsToCurrentThread()); if (was_cancelled_) { @@ -669,8 +677,13 @@ DCHECK(request_context_getter_.get()); - int64 delay = INT64_C(0); + int64 delay = 0; if (!original_url_throttler_entry_.get()) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is + // fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456327 URLFetcherCore::StartURLRequestWhenAppropriate1")); URLRequestThrottlerManager* manager = request_context_getter_->GetURLRequestContext()->throttler_manager(); if (manager) { @@ -679,11 +692,16 @@ } } if (original_url_throttler_entry_.get()) { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "456327 URLFetcherCore::StartURLRequestWhenAppropriate2")); delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest( GetBackoffReleaseTime()); } - if (delay == INT64_C(0)) { + if (delay == 0) { StartURLRequest(); } else { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 132a67d..d7203a4 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -227,12 +227,6 @@ return upload_data_stream_.get() != NULL; } -void URLRequest::SetExtraRequestHeaderById(int id, const string& value, - bool overwrite) { - DCHECK(!is_pending_ || is_redirecting_); - NOTREACHED() << "implement me!"; -} - void URLRequest::SetExtraRequestHeaderByName(const string& name, const string& value, bool overwrite) { @@ -273,6 +267,10 @@ } LoadStateWithParam URLRequest::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION("455952 URLRequest::GetLoadState")); // The !blocked_by_.empty() check allows |this| to report it's blocked on a // delegate before it has been started. if (calling_delegate_ || !blocked_by_.empty()) { @@ -378,11 +376,6 @@ return job_->GetUploadProgress(); } -void URLRequest::GetResponseHeaderById(int id, string* value) { - DCHECK(job_.get()); - NOTREACHED() << "implement me!"; -} - void URLRequest::GetResponseHeaderByName(const string& name, string* value) { DCHECK(value); if (response_info_.headers.get()) { @@ -392,15 +385,6 @@ } } -void URLRequest::GetAllResponseHeaders(string* headers) { - DCHECK(headers); - if (response_info_.headers.get()) { - response_info_.headers->GetNormalizedHeaders(headers); - } else { - headers->clear(); - } -} - HostPortPair URLRequest::GetSocketAddress() const { DCHECK(job_.get()); return job_->GetSocketAddress();
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index af972bd2..20aab601 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -82,14 +82,6 @@ NetworkDelegate* network_delegate, const std::string& scheme); - // HTTP request/response header IDs (via some preprocessor fun) for use with - // SetRequestHeaderById and GetResponseHeaderById. - enum { -#define HTTP_ATOM(x) HTTP_ ## x, -#include "net/http/http_atom_list.h" -#undef HTTP_ATOM - }; - // Referrer policies (see set_referrer_policy): During server redirects, the // referrer header might be cleared, if the protocol changes from HTTPS to // HTTP. This is the default behavior of URLRequest, corresponding to @@ -334,11 +326,9 @@ // Returns true if the request has a non-empty message body to upload. bool has_upload() const; - // Set an extra request header by ID or name, or remove one by name. These - // methods may only be called before Start() is called, or before a new - // redirect in the request chain. - void SetExtraRequestHeaderById(int header_id, const std::string& value, - bool overwrite); + // Set or remove a extra request header. These methods may only be called + // before Start() is called, or between receiving a redirect and trying to + // follow it. void SetExtraRequestHeaderByName(const std::string& name, const std::string& value, bool overwrite); void RemoveRequestHeaderByName(const std::string& name); @@ -401,19 +391,13 @@ // chunked, size is set to zero, but position will not be. UploadProgress GetUploadProgress() const; - // Get response header(s) by ID or name. These methods may only be called + // Get response header(s) by name. This method may only be called // once the delegate's OnResponseStarted method has been called. Headers // that appear more than once in the response are coalesced, with values // separated by commas (per RFC 2616). This will not work with cookies since // comma can be used in cookie values. - // TODO(darin): add API to enumerate response headers. - void GetResponseHeaderById(int header_id, std::string* value); void GetResponseHeaderByName(const std::string& name, std::string* value); - // Get all response headers, \n-delimited and \n\0-terminated. This includes - // the response status line. Restrictions on GetResponseHeaders apply. - void GetAllResponseHeaders(std::string* headers); - // The time when |this| was constructed. base::TimeTicks creation_time() const { return creation_time_; }
diff --git a/net/url_request/url_request_ftp_job.cc b/net/url_request/url_request_ftp_job.cc index d774714..d1050e33 100644 --- a/net/url_request/url_request_ftp_job.cc +++ b/net/url_request/url_request_ftp_job.cc
@@ -285,6 +285,11 @@ } LoadState URLRequestFtpJob::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 URLRequestFtpJob::GetLoadState")); if (proxy_info_.is_direct()) { return ftp_transaction_ ? ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 68858c1..4247d83c 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/debug/alias.h" +#include "base/debug/dump_without_crashing.h" #include "base/file_version_info.h" #include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" @@ -289,6 +290,12 @@ } void URLRequestHttpJob::Kill() { + if (awaiting_callback_) { + // TODO(battre) crbug.com/289715 + // Simulate a crash to see who kills the job while it is waiting for a + // callback. This should not happen, see URLRequest::OrphanJob(). + base::debug::DumpWithoutCrashing(); + } if (!transaction_.get()) return; @@ -1020,6 +1027,11 @@ } LoadState URLRequestHttpJob::GetLoadState() const { + // TODO(pkasting): Remove ScopedTracker below once crbug.com/455952 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 URLRequestHttpJob::GetLoadState")); return transaction_.get() ? transaction_->GetLoadState() : LOAD_STATE_IDLE; }
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 2be8a74..3fae14f 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc
@@ -503,7 +503,8 @@ void URLRequestJob::NotifyReadComplete(int bytes_read) { // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION("URLRequestJob::NotifyReadComplete")); + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "423948 URLRequestJob::NotifyReadComplete")); if (!request_ || !request_->has_delegate()) return; // The request was destroyed, so there is no more work to do.
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index c3bc166..5937464a 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -5989,10 +5989,8 @@ TestDelegate d; GURL::Replacements replacements; - std::string username("user2"); - std::string password("secret"); - replacements.SetUsernameStr(username); - replacements.SetPasswordStr(password); + replacements.SetUsernameStr("user2"); + replacements.SetPasswordStr("secret"); GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements); scoped_ptr<URLRequest> r(context.CreateRequest(
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc index 4aa2f1c8..1a3df04 100644 --- a/net/websockets/websocket_end_to_end_test.cc +++ b/net/websockets/websocket_end_to_end_test.cc
@@ -338,9 +338,8 @@ // The test server doesn't have an unauthenticated proxy mode. WebSockets // cannot provide auth information that isn't already cached, so it's // necessary to preflight an HTTP request to authenticate against the proxy. - std::string scheme("http"); GURL::Replacements replacements; - replacements.SetSchemeStr(scheme); + replacements.SetSchemeStr("http"); // It doesn't matter what the URL is, as long as it is an HTTP navigation. GURL http_page = ws_server.GetURL("connect_check.html").ReplaceComponents(replacements);
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc index 002d5112..b5012bc 100644 --- a/net/websockets/websocket_stream.cc +++ b/net/websockets/websocket_stream.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram.h" #include "base/metrics/sparse_histogram.h" #include "base/profiler/scoped_tracker.h" +#include "base/strings/stringprintf.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/load_flags.h" @@ -135,6 +136,20 @@ connect_delegate_->OnSuccess(create_helper_->Upgrade()); } + std::string FailureMessageFromNetError() { + int error = url_request_->status().error(); + if (error == ERR_TUNNEL_CONNECTION_FAILED) { + // This error is common and confusing, so special-case it. + // TODO(ricea): Include the HostPortPair of the selected proxy server in + // the error message. This is not currently possible because it isn't set + // in HttpResponseInfo when a ERR_TUNNEL_CONNECTION_FAILED error happens. + return "Establishing a tunnel via proxy server failed."; + } else { + return std::string("Error in connection establishment: ") + + ErrorToString(url_request_->status().error()); + } + } + void ReportFailure() { DCHECK(timer_); timer_->Stop(); @@ -150,9 +165,7 @@ failure_message_ = "WebSocket opening handshake was canceled"; break; case URLRequestStatus::FAILED: - failure_message_ = - std::string("Error in connection establishment: ") + - ErrorToString(url_request_->status().error()); + failure_message_ = FailureMessageFromNetError(); break; } }
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc index 713af37..8cfc0f1 100644 --- a/net/websockets/websocket_stream_test.cc +++ b/net/websockets/websocket_stream_test.cc
@@ -22,6 +22,7 @@ #include "net/base/test_data_directory.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/socket_test_util.h" #include "net/test/cert_test_util.h" @@ -1412,5 +1413,33 @@ EXPECT_TRUE(has_failed()); } +TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { + static const char kConnectRequest[] = + "CONNECT localhost:80 HTTP/1.1\r\n" + "Host: localhost\r\n" + "Proxy-Connection: keep-alive\r\n" + "\r\n"; + + static const char kProxyResponse[] = + "HTTP/1.1 403 Forbidden\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 9\r\n" + "Connection: keep-alive\r\n" + "\r\n" + "Forbidden"; + + MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; + MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; + scoped_ptr<DeterministicSocketData> socket_data( + BuildSocketData(reads, writes)); + url_request_context_host_.SetProxyConfig("https=proxy:8000"); + CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), + "http://localhost", socket_data.Pass()); + RunUntilIdle(); + EXPECT_TRUE(has_failed()); + EXPECT_EQ("Establishing a tunnel via proxy server failed.", + failure_message()); +} + } // namespace } // namespace net
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc index 6091c9e..0b0b8c0 100644 --- a/net/websockets/websocket_test_util.cc +++ b/net/websockets/websocket_test_util.cc
@@ -11,6 +11,7 @@ #include "base/memory/scoped_vector.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" +#include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" namespace net { @@ -151,6 +152,13 @@ maker_.AddSSLSocketDataProvider(ssl_socket_data.Pass()); } +void WebSocketTestURLRequestContextHost::SetProxyConfig( + const std::string& proxy_rules) { + DCHECK(!url_request_context_initialized_); + proxy_service_.reset(ProxyService::CreateFixed(proxy_rules)); + url_request_context_.set_proxy_service(proxy_service_.get()); +} + TestURLRequestContext* WebSocketTestURLRequestContextHost::GetURLRequestContext() { if (!url_request_context_initialized_) {
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h index 5c7db80e..f9bf961 100644 --- a/net/websockets/websocket_test_util.h +++ b/net/websockets/websocket_test_util.h
@@ -27,6 +27,7 @@ class BoundNetLog; class DeterministicMockClientSocketFactory; class DeterministicSocketData; +class ProxyService; class URLRequestContext; class WebSocketHandshakeStreamCreateHelper; struct SSLSocketDataProvider; @@ -123,6 +124,12 @@ void AddSSLSocketDataProvider( scoped_ptr<SSLSocketDataProvider> ssl_socket_data); + // Allow a proxy to be set. Usage: + // SetProxyConfig("proxy1:8000"); + // Any syntax accepted by net::ProxyConfig::ParseFromString() will work. + // Do not call after GetURLRequestContext() has been called. + void SetProxyConfig(const std::string& proxy_rules); + // Call after calling one of SetExpections() or AddRawExpectations(). The // returned pointer remains owned by this object. TestURLRequestContext* GetURLRequestContext(); @@ -131,6 +138,7 @@ WebSocketDeterministicMockClientSocketFactoryMaker maker_; TestURLRequestContext url_request_context_; TestNetworkDelegate network_delegate_; + scoped_ptr<ProxyService> proxy_service_; bool url_request_context_initialized_; DISALLOW_COPY_AND_ASSIGN(WebSocketTestURLRequestContextHost);
diff --git a/pdf/instance.cc b/pdf/instance.cc index d3487172..93daf6f 100644 --- a/pdf/instance.cc +++ b/pdf/instance.cc
@@ -367,8 +367,6 @@ CreatePageIndicator(IsPrintPreviewUrl(url)); - engine_->SetBackgroundColor(kBackgroundColor); - if (!full_) { // For PDFs embedded in a frame, we don't get the data automatically like we // do for full-frame loads. Start loading the data manually. @@ -2643,6 +2641,10 @@ return IsPrintPreviewUrl(url_); } +uint32 Instance::GetBackgroundColor() { + return kBackgroundColor; +} + int Instance::GetPageNumberToDisplay() { int page = engine_->GetMostVisiblePage(); if (IsPrintPreview() && !print_preview_page_numbers_.empty()) {
diff --git a/pdf/instance.h b/pdf/instance.h index e5c2c5d1..bdb52430 100644 --- a/pdf/instance.h +++ b/pdf/instance.h
@@ -174,6 +174,7 @@ void DocumentLoadProgress(uint32 available, uint32 doc_size) override; void FormTextFieldFocusChange(bool in_focus) override; bool IsPrintPreview() override; + uint32 GetBackgroundColor() override; // ControlOwner implementation. void OnEvent(uint32 control_id, uint32 event_id, void* data) override;
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 1dfd925..169a4403 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -271,7 +271,8 @@ recently_sent_find_update_(false), received_viewport_message_(false), did_call_start_loading_(false), - stop_scrolling_(false) { + stop_scrolling_(false), + background_color_(kBackgroundColor) { loader_factory_.Initialize(this); timer_factory_.Initialize(this); form_factory_.Initialize(this); @@ -282,6 +283,7 @@ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_MOUSE); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); + RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_TOUCH); } OutOfProcessInstance::~OutOfProcessInstance() { @@ -347,10 +349,9 @@ } if (is_material) - engine_->SetBackgroundColor(kBackgroundColorMaterial); + background_color_ = kBackgroundColorMaterial; else - engine_->SetBackgroundColor(kBackgroundColor); - + background_color_ = kBackgroundColor; // TODO(raymes): This is a hack to ensure that if no headers are passed in // then we get the right MIME type. When the in process plugin is removed we @@ -674,7 +675,7 @@ if (first_paint_) { first_paint_ = false; pp::Rect rect = pp::Rect(pp::Point(), image_data_.size()); - FillRect(rect, engine_->GetBackgroundColor()); + FillRect(rect, background_color_); ready->push_back(PaintManager::ReadyRect(rect, image_data_, true)); } @@ -767,7 +768,7 @@ // horizontal centering. BackgroundPart part = { pp::Rect(0, 0, left_width, bottom), - engine_->GetBackgroundColor() + background_color_ }; if (!part.location.IsEmpty()) background_parts_.push_back(part); @@ -1346,6 +1347,10 @@ return IsPrintPreviewUrl(url_); } +uint32 OutOfProcessInstance::GetBackgroundColor() { + return background_color_; +} + void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url, int dst_page_index) { if (!IsPrintPreview())
diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h index eb30458..58e9b29 100644 --- a/pdf/out_of_process_instance.h +++ b/pdf/out_of_process_instance.h
@@ -136,6 +136,7 @@ void DocumentLoadProgress(uint32 available, uint32 doc_size) override; void FormTextFieldFocusChange(bool in_focus) override; bool IsPrintPreview() override; + uint32 GetBackgroundColor() override; // PreviewModeClient::Client implementation. void PreviewDocumentLoadComplete() override; @@ -283,6 +284,9 @@ // Used for printing without re-entrancy issues. pp::CompletionCallbackFactory<OutOfProcessInstance> print_callback_factory_; + // The callback for receiving the password from the page. + scoped_ptr<pp::CompletionCallbackWithOutput<pp::Var> > password_callback_; + // True if we haven't painted the plugin viewport yet. bool first_paint_; @@ -339,8 +343,8 @@ // zooming the plugin so that flickering doesn't occur while zooming. bool stop_scrolling_; - // The callback for receiving the password from the page. - scoped_ptr<pp::CompletionCallbackWithOutput<pp::Var> > password_callback_; + // The background color of the PDF viewer. + uint32 background_color_; }; } // namespace chrome_pdf
diff --git a/pdf/pdf_engine.h b/pdf/pdf_engine.h index e8434595..befb1b8 100644 --- a/pdf/pdf_engine.h +++ b/pdf/pdf_engine.h
@@ -173,6 +173,9 @@ // Returns true if the plugin has been opened within print preview. virtual bool IsPrintPreview() = 0; + + // Get the background color of the PDF. + virtual uint32 GetBackgroundColor() = 0; }; // Factory method to create an instance of the PDF Engine. @@ -246,11 +249,6 @@ // Returns number of copies to be printed. virtual int GetCopiesToPrint() = 0; - // Retrieve the background color of the PDF viewer. - virtual uint32 GetBackgroundColor() = 0; - // Set the background color of the PDF viewer. - virtual void SetBackgroundColor(uint32 background_color) = 0; - // Returns a VarArray of Bookmarks, each a VarDictionary containing the // following key/values: // - "title" - a string Var.
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 2990f40..294ab2f 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -600,7 +600,6 @@ most_visible_page_(-1), called_do_document_action_(false), render_grayscale_(false), - background_color_(0), progressive_paint_timeout_(0), getting_password_(false) { find_factory_.Initialize(this); @@ -2368,14 +2367,6 @@ return pages_.size(); } -uint32 PDFiumEngine::GetBackgroundColor() { - return background_color_; -} - -void PDFiumEngine::SetBackgroundColor(uint32 background_color) { - background_color_ = background_color; -} - pp::VarArray PDFiumEngine::GetBookmarks() { pp::VarDictionary dict = TraverseBookmarks(doc_, NULL); // The root bookmark contains no useful information. @@ -2947,7 +2938,7 @@ FPDFBitmap_FillRect(bitmap, left.x() - dirty_in_screen.x(), left.y() - dirty_in_screen.y(), left.width(), - left.height(), background_color_); + left.height(), client_->GetBackgroundColor()); } if (page_rect.right() < document_size_.width()) { @@ -2961,7 +2952,7 @@ FPDFBitmap_FillRect(bitmap, right.x() - dirty_in_screen.x(), right.y() - dirty_in_screen.y(), right.width(), - right.height(), background_color_); + right.height(), client_->GetBackgroundColor()); } // Paint separator. @@ -2973,7 +2964,7 @@ FPDFBitmap_FillRect(bitmap, bottom.x() - dirty_in_screen.x(), bottom.y() - dirty_in_screen.y(), bottom.width(), - bottom.height(), background_color_); + bottom.height(), client_->GetBackgroundColor()); } void PDFiumEngine::PaintPageShadow(int progressive_index, @@ -3425,7 +3416,8 @@ // We need to check depth only to verify our copy of shadow matrix is correct. if (!page_shadow_.get() || page_shadow_->depth() != depth) - page_shadow_.reset(new ShadowMatrix(depth, factor, background_color_)); + page_shadow_.reset(new ShadowMatrix(depth, factor, + client_->GetBackgroundColor())); DCHECK(!image_data->is_null()); DrawShadow(image_data, shadow_rect, page_rect, clip_rect, *page_shadow_);
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 331d37b..d7b4835 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -80,8 +80,6 @@ virtual bool HasPermission(DocumentPermission permission) const; virtual void SelectAll(); virtual int GetNumberOfPages(); - virtual uint32 GetBackgroundColor(); - virtual void SetBackgroundColor(uint32 backgroundColor); virtual pp::VarArray GetBookmarks(); virtual int GetNamedDestinationPage(const std::string& destination); virtual pp::VarDictionary GetNamedDestinations(); @@ -683,9 +681,6 @@ // Whether to render in grayscale or in color. bool render_grayscale_; - // Background color of the PDF. - uint32 background_color_; - // The link currently under the cursor. std::string link_under_cursor_;
diff --git a/pdf/preview_mode_client.cc b/pdf/preview_mode_client.cc index 8b9919b..a315f88 100644 --- a/pdf/preview_mode_client.cc +++ b/pdf/preview_mode_client.cc
@@ -159,4 +159,9 @@ return false; } +uint32 PreviewModeClient::GetBackgroundColor() { + NOTREACHED(); + return 0; +} + } // namespace chrome_pdf
diff --git a/pdf/preview_mode_client.h b/pdf/preview_mode_client.h index 0e766f9..a6e64679 100644 --- a/pdf/preview_mode_client.h +++ b/pdf/preview_mode_client.h
@@ -67,6 +67,7 @@ virtual void DocumentLoadProgress(uint32 available, uint32 doc_size); virtual void FormTextFieldFocusChange(bool in_focus); virtual bool IsPrintPreview(); + virtual uint32 GetBackgroundColor(); private: Client* client_;
diff --git a/ppapi/BUILD.gn b/ppapi/BUILD.gn index 3a18656..dd722c14 100644 --- a/ppapi/BUILD.gn +++ b/ppapi/BUILD.gn
@@ -332,6 +332,8 @@ "thunk/ppb_video_decoder_thunk.cc", "thunk/ppb_video_destination_private_api.h", "thunk/ppb_video_destination_private_thunk.cc", + "thunk/ppb_video_encoder_api.h", + "thunk/ppb_video_encoder_thunk.cc", "thunk/ppb_video_frame_api.h", "thunk/ppb_video_frame_thunk.cc", "thunk/ppb_video_source_private_api.h", @@ -720,6 +722,8 @@ "proxy/ppp_video_decoder_proxy.h", "proxy/video_decoder_resource.cc", "proxy/video_decoder_resource.h", + "proxy/video_encoder_resource.cc", + "proxy/video_encoder_resource.h", "proxy/talk_resource.cc", "proxy/talk_resource.h", "proxy/video_capture_resource.cc",
diff --git a/ppapi/api/pp_codecs.idl b/ppapi/api/pp_codecs.idl index 5a93ff1..3a20e985c 100644 --- a/ppapi/api/pp_codecs.idl +++ b/ppapi/api/pp_codecs.idl
@@ -115,3 +115,56 @@ */ PP_Size texture_size; }; + +/** + * Supported video profile information. See the PPB_VideoEncoder function + * GetSupportedProfiles() for more details. + */ +struct PP_VideoProfileDescription { + /** + * The codec profile. + */ + PP_VideoProfile profile; + + /** + * Dimensions of the maximum resolution of video frames, in pixels. + */ + PP_Size max_resolution; + + /** + * The numerator of the maximum frame rate. + */ + uint32_t max_framerate_numerator; + + /** + * The denominator of the maximum frame rate. + */ + uint32_t max_framerate_denominator; + + /** + * A value indicating if the profile is available in hardware, software, or + * both. + */ + PP_HardwareAcceleration acceleration; +}; + +/** + * Struct describing a bitstream buffer. + */ +struct PP_BitstreamBuffer { + /** + * The size, in bytes, of the bitstream data. + */ + uint32_t size; + + /** + * The base address of the bitstream data. + */ + mem_t buffer; + + /** + * Whether the buffer represents a key frame. + */ + PP_Bool key_frame; +}; +
diff --git a/ppapi/api/ppb_video_encoder.idl b/ppapi/api/ppb_video_encoder.idl new file mode 100644 index 0000000..1796f91 --- /dev/null +++ b/ppapi/api/ppb_video_encoder.idl
@@ -0,0 +1,230 @@ +/* Copyright 2015 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * This file defines the <code>PPB_VideoEncoder</code> interface. + */ + +[generate_thunk] + +label Chrome { + [channel=dev] M42 = 0.1 +}; + +/** + * Video encoder interface. + * + * Typical usage: + * - Call Create() to create a new video encoder resource. + * - Call GetSupportedFormats() to determine which codecs and profiles are + * available. + * - Call Initialize() to initialize the encoder for a supported profile. + * - Call GetVideoFrame() to get a blank frame and fill it in, or get a video + * frame from another resource, e.g. <code>PPB_MediaStreamVideoTrack</code>. + * - Call Encode() to push the video frame to the encoder. If an external frame + * is pushed, wait for completion to recycle the frame. + * - Call GetBitstreamBuffer() continuously (waiting for each previous call to + * complete) to pull encoded pictures from the encoder. + * - Call RecycleBitstreamBuffer() after consuming the data in the bitstream + * buffer. + * - To destroy the encoder, the plugin should release all of its references to + * it. Any pending callbacks will abort before the encoder is destroyed. + * + * Available video codecs vary by platform. + * All: theora, vorbis, vp8. + * Chrome and ChromeOS: h264. + * ChromeOS: mpeg4. + */ +interface PPB_VideoEncoder { + /** + * Creates a new video encoder resource. + * + * @param[in] instance A <code>PP_Instance</code> identifying the instance + * with the video encoder. + * + * @return A <code>PP_Resource</code> corresponding to a video encoder if + * successful or 0 otherwise. + */ + PP_Resource Create([in] PP_Instance instance); + + /** + * Determines if the given resource is a video encoder. + * + * @param[in] resource A <code>PP_Resource</code> identifying a resource. + * + * @return <code>PP_TRUE</code> if the resource is a + * <code>PPB_VideoEncoder</code>, <code>PP_FALSE</code> if the resource is + * invalid or some other type. + */ + PP_Bool IsVideoEncoder([in] PP_Resource resource); + + /** + * Gets an array of supported video encoder profiles. + * These can be used to choose a profile before calling Initialize(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] output A <code>PP_ArrayOutput</code> to receive the supported + * <code>PP_VideoProfileDescription</code> structs. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return If >= 0, the number of supported profiles returned, otherwise an + * error code from <code>pp_errors.h</code>. + */ + int32_t GetSupportedProfiles([in] PP_Resource video_encoder, + [in] PP_ArrayOutput output, + [in] PP_CompletionCallback callback); + + /** + * Initializes a video encoder resource. The plugin should call Initialize() + * successfully before calling any of the functions below. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] input_format The <code>PP_VideoFrame_Format</code> of the + * frames which will be encoded. + * @param[in] input_visible_size A <code>PP_Size</code> specifying the + * dimensions of the visible part of the input frames. + * @param[in] output_profile A <code>PP_VideoProfile</code> specifying the + * codec profile of the encoded output stream. + * @param[in] acceleration A <code>PP_HardwareAcceleration</code> specifying + * whether to use a hardware accelerated or a software implementation. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_NOTSUPPORTED if video encoding is not available, or the + * requested codec profile is not supported. + */ + int32_t Initialize([in] PP_Resource video_encoder, + [in] PP_VideoFrame_Format input_format, + [in] PP_Size input_visible_size, + [in] PP_VideoProfile output_profile, + [in] uint32_t initial_bitrate, + [in] PP_HardwareAcceleration acceleration, + [in] PP_CompletionCallback callback); + + /** + * Gets the number of input video frames that the encoder may hold while + * encoding. If the plugin is providing the video frames, it should have at + * least this many available. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @return An int32_t containing the number of frames required, or an error + * code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t GetFramesRequired([in] PP_Resource video_encoder); + + /** + * Gets the coded size of the video frames required by the encoder. Coded + * size is the logical size of the input frames, in pixels. The encoder may + * have hardware alignment requirements that make this different from + * |input_visible_size|, as requested in the call to Initialize(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] coded_size A <code>PP_Size</code> to hold the coded size. + * @return An int32_t containing a result code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t GetFrameCodedSize([in] PP_Resource video_encoder, + [out] PP_Size coded_size); + + /** + * Gets a blank video frame which can be filled with video data and passed + * to the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[out] video_frame A blank <code>PPB_VideoFrame</code> resource. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t GetVideoFrame([in] PP_Resource video_encoder, + [out] PP_Resource video_frame, + [in] PP_CompletionCallback callback); + + /** + * Encodes a video frame. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] video_frame The <code>PPB_VideoFrame</code> to be encoded. + * @param[in] force_keyframe A <code>PP_Bool> specifying whether the encoder + * should emit a key frame for this video frame. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. Plugins that pass <code>PPB_VideoFrame</code> resources owned + * by other resources should wait for completion before reusing them. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t Encode([in] PP_Resource video_encoder, + [in] PP_Resource video_frame, + [in] PP_Bool force_keyframe, + [in] PP_CompletionCallback callback); + + /** + * Gets the next encoded bitstream buffer from the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[out] bitstream_buffer A <code>PP_BitstreamBuffer</code> containing + * encoded video data. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. The plugin can call GetBitstreamBuffer from the callback in + * order to continuously "pull" bitstream buffers from the encoder. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + * Returns PP_ERROR_INPROGRESS if a prior call to GetBitstreamBuffer() has + * not completed. + */ + int32_t GetBitstreamBuffer([in] PP_Resource video_encoder, + [out] PP_BitstreamBuffer bitstream_buffer, + [in] PP_CompletionCallback callback); + + /** + * Recycles a bitstream buffer back to the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] bitstream_buffer A <code>PP_BitstreamBuffer</code> that is no + * longer needed by the plugin. + */ + void RecycleBitstreamBuffer([in] PP_Resource video_encoder, + [in] PP_BitstreamBuffer bitstream_buffer); + + /** + * Requests a change to encoding parameters. This is only a request, + * fulfilled on a best-effort basis. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] bitrate The requested new bitrate, in bits per second. + * @param[in] framerate The requested new framerate, in frames per second. + */ + void RequestEncodingParametersChange([in] PP_Resource video_encoder, + [in] uint32_t bitrate, + [in] uint32_t framerate); + + /** + * Closes the video encoder, and cancels any pending encodes. Any pending + * callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> . It is + * not valid to call any encoder functions after a call to this method. + * <strong>Note:</strong> Destroying the video encoder closes it implicitly, + * so you are not required to call Close(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + */ + void Close([in] PP_Resource video_encoder); +};
diff --git a/ppapi/api/private/ppb_image_capture_config_private.idl b/ppapi/api/private/ppb_image_capture_config_private.idl deleted file mode 100644 index 95bded3..0000000 --- a/ppapi/api/private/ppb_image_capture_config_private.idl +++ /dev/null
@@ -1,101 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file defines the PPB_ImageCaptureConfig_Private interface for - * establishing an image capture configuration resource within the browser. - */ - -[generate_thunk] - -label Chrome { - M39 = 0.1 -}; - -/** - * The <code>PPB_ImageCaptureConfig_Private</code> interface contains pointers - * to several functions for establishing image capture configuration within the - * browser. The new configuration will take effect after <code> - * PPB_ImageCapture_Private.SetConfig</code> is called. - */ -[version=0.1] -interface PPB_ImageCaptureConfig_Private { - /** - * Creates a PPB_ImageCaptureConfig_Private resource. - * - * @param[in] instance A <code>PP_Instance</code> identifying one instance of - * a module. - * - * @return A <code>PP_Resource</code> corresponding to a - * PPB_ImageCaptureConfig_Private resource if successful, 0 if failed. - */ - PP_Resource Create([in] PP_Instance instance); - - /** - * IsImageCaptureConfig() determines if the given resource is a - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] resource A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * - * @return A <code>PP_Bool</code> containing <code>PP_TRUE</code> if the given - * resource is an <code>ImageCaptureConfig_Private</code> resource, otherwise - * <code>PP_FALSE</code>. - */ - PP_Bool IsImageCaptureConfig( - [in] PP_Resource resource); - - /** - * GetPreviewSize() returns the preview image size in pixels for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * @param[out] preview_size A <code>PP_Size</code> that indicates the - * requested preview image size. - */ - void GetPreviewSize( - [in] PP_Resource config, - [out] PP_Size preview_size); - - /** - * SetPreviewSize() sets the preview image size for the given <code> - * PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to a - * <code>PPB_ImageCaptureConfig_Private</code>. - * @param[in] preview_size A <code>PP_Size</code> that indicates the requested - * preview image size. - */ - void SetPreviewSize( - [in] PP_Resource config, - [in] PP_Size preview_size); - - /** - * GetJpegSize() returns the JPEG image size in pixels for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * @param[out] jpeg_size A <code>PP_Size</code> that indicates the current - * JPEG image size. - */ - void GetJpegSize( - [in] PP_Resource config, - [out] PP_Size jpeg_size); - - /** - * SetJpegSize() sets the JPEG image size for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to a - * <code>PPB_ImageCaptureConfig_Private</code>. - * @param[in] jpeg_size A <code>PP_Size</code> that indicates the requested - * JPEG image size. - */ - void SetJpegSize( - [in] PP_Resource config, - [in] PP_Size jpeg_size); -};
diff --git a/ppapi/api/private/ppb_image_capture_private.idl b/ppapi/api/private/ppb_image_capture_private.idl index 28432af..36c410f 100644 --- a/ppapi/api/private/ppb_image_capture_private.idl +++ b/ppapi/api/private/ppb_image_capture_private.idl
@@ -15,86 +15,12 @@ }; /** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to indicate the image has been captured from the sensor. This is a - * good opportunity to play a shutter sound or give other feedback of camera - * operation. This will occur after the image was captured, but before the - * actual data is available. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - */ -typedef void PPB_ImageCapture_Private_ShutterCallback( - [inout] mem_t user_data, - [in] int64_t sequence_id); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to deliver a preview image. The client can use this to show the - * captured image. See <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> for more information. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |preview| A <code>PP_Resource</code> corresponding to a VideoFrame - * resource used to store the preview image. - */ -typedef void PPB_ImageCapture_Private_PreviewCallback( - [inout] mem_t user_data, - [in] int64_t sequence_id, - [in] PP_Resource preview); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to deliver a still JPEG image. See <code> - * PPB_ImageCapture_Private.CaptureStillImage</code> for more information. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |jpeg| A <code>PP_Resource</code> corresponding to a VideoFrame - * resource used to store the JPEG image. - */ -typedef void PPB_ImageCapture_Private_JpegCallback( - [inout] mem_t user_data, - [in] int64_t sequence_id, - [in] PP_Resource jpeg); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to indicate the image capture has failed. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |int32_t| An error code from <code>pp_errors.h</code>. - */ -typedef void PPB_ImageCapture_Private_ErrorCallback( - [inout] mem_t user_data, - [in] int64_t sequence_id, - [in] int32_t pp_error); - -/** - * To capture a still image with this class, use the following steps. + * To query camera capabilities: * 1. Get a PPB_ImageCapture_Private object by Create(). - * 2. Call GetCameraCapabilities to get the supported preview sizes. - * 3. For optimal performance, set one of the supported preview size as the - * constraints of getUserMedia. Use the created MediaStreamVideoTrack for - * camera previews. - * 4. Set the same preview size and other settings by SetConfig. - * 5. Call CaptureStillImage to capture a still image. Play the shutter sound in - * the shutter callback. The image from the preview callback can be used for - * display. JPEG image will be returned to the JPEG callback. + * 2. Open() camera device with track id of MediaStream video track. + * 3. Call GetCameraCapabilities() to get a + * <code>PPB_CameraCapabilities_Private</code> object, which can be used to + * query camera capabilities. */ interface PPB_ImageCapture_Private { /** @@ -117,7 +43,6 @@ */ PP_Resource Create([in] PP_Instance instance, [in] PP_Var camera_source_id, - [in] PPB_ImageCapture_Private_ErrorCallback error_callback, [inout] mem_t user_data); /** @@ -149,42 +74,6 @@ [in] PP_CompletionCallback callback); /** - * Sets the configuration of the image capture. - * If <code>SetConfig()</code> is not called, default settings will be used. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[in] config A <code>PP_ImageCaptureConfig_Private</code> object. - * @param[in] callback <code>PP_CompletionCallback</code> to be called upon - * completion of <code>SetConfig()</code>. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - * Returns <code>PP_ERROR_INPROGRESS</code> if there is a pending call of - * <code>SetConfig()</code> or <code>CaptureStillImage()</code>. - * If an error is returned, the configuration will not be changed. - */ - int32_t SetConfig([in] PP_Resource image_capture, - [in] PP_Resource config, - [in] PP_CompletionCallback callback); - - /** - * Gets the configuration of the image capture. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[out] config A <code>PP_ImageCaptureConfig_Private</code> for storing - * the current image capture config on success. Otherwise, the values will not - * be changed. - * @param[in] callback <code>PP_CompletionCallback</code> to be called upon - * completion of <code>GetConfig()</code>. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - */ - int32_t GetConfig([in] PP_Resource image_capture, - [out] PP_Resource config, - [in] PP_CompletionCallback callback); - - /** * Gets the camera capabilities. * * The camera capabilities do not change for a given camera source. @@ -202,58 +91,4 @@ int32_t GetCameraCapabilities([in] PP_Resource image_capture, [out] PP_Resource capabilities, [in] PP_CompletionCallback callback); - - /** - * Captures a still JPEG image from the camera. - * - * Triggers an asynchronous image capture. The camera will initiate a series - * of callbacks to the application as the image capture progresses. The - * callbacks will be invoked in the order of shutter callback, preview - * callback, and JPEG callback. The shutter callback occurs after the image is - * captured. This can be used to trigger a sound to let the user know that - * image has been captured. The preview callback occurs when a scaled, fully - * processed preview image is available. The JPEG callback occurs when the - * compressed image is available. If there is an error after the capture is in - * progress, the error callback passed to <code> - * PPB_ImageCapture_Private.Create()</code> will be invoked. All the callbacks - * are invoked by the thread that calls this function. - * - * The size of the preview image in preview callback is determined by - * <code>PPB_ImageCaptureConfig_Private.SetPreviewSize</code>. The format is - * decided by the camera and can be got from <code>PPB_VideoFrame.GetFormat - * </code>. The size of the JPEG image is determined by <code> - * PPB_ImageCaptureConfig_Private.SetJpegSize</code>. - * - * The camera may need to stop and re-start streaming during image capture. If - * some MediaStreamVideoTrack are associated with the camera source, they will - * receive mute and unmute events. The mute event will be received before all - * the callbacks. The unmute event will be received after all the callbacks. - * The preview image will not be sent to the video tracks associated with the - * camera. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[in] shutter_callback A <code> - * PPB_ImageCapture_Private_ShutterCallback</code> callback to indicate the - * image has been taken. - * @param[in] preview_callback A <code> - * PPB_ImageCapture_Private_PreviewCallback</code> callback to return a - * preview of the captured image. - * @param[in] jpeg_callback A <code> - * PPB_ImageCapture_Private_JpegCallback</code> callback to return captured - * JPEG image. - * @param[out] sequence_id The sequence ID is a unique monotonically - * increasing value starting from 0, incremented every time a new request like - * image capture is submitted. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - * PP_OK means the callbacks will be triggered. Other values mean the - * callbacks will not be triggered. - */ - int32_t CaptureStillImage( - [in] PP_Resource image_capture, - [in] PPB_ImageCapture_Private_ShutterCallback shutter_callback, - [in] PPB_ImageCapture_Private_PreviewCallback preview_callback, - [in] PPB_ImageCapture_Private_JpegCallback jpeg_callback, - [out] int64_t sequence_id); };
diff --git a/ppapi/c/pp_codecs.h b/ppapi/c/pp_codecs.h index 86d8fb5..9f32a72 100644 --- a/ppapi/c/pp_codecs.h +++ b/ppapi/c/pp_codecs.h
@@ -3,11 +3,12 @@ * found in the LICENSE file. */ -/* From pp_codecs.idl modified Wed Nov 5 13:38:52 2014. */ +/* From pp_codecs.idl modified Wed Feb 4 05:24:21 2015. */ #ifndef PPAPI_C_PP_CODECS_H_ #define PPAPI_C_PP_CODECS_H_ +#include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_macros.h" #include "ppapi/c/pp_point.h" #include "ppapi/c/pp_rect.h" @@ -130,6 +131,52 @@ */ struct PP_Size texture_size; }; + +/** + * Supported video profile information. See the PPB_VideoEncoder function + * GetSupportedProfiles() for more details. + */ +struct PP_VideoProfileDescription { + /** + * The codec profile. + */ + PP_VideoProfile profile; + /** + * Dimensions of the maximum resolution of video frames, in pixels. + */ + struct PP_Size max_resolution; + /** + * The numerator of the maximum frame rate. + */ + uint32_t max_framerate_numerator; + /** + * The denominator of the maximum frame rate. + */ + uint32_t max_framerate_denominator; + /** + * A value indicating if the profile is available in hardware, software, or + * both. + */ + PP_HardwareAcceleration acceleration; +}; + +/** + * Struct describing a bitstream buffer. + */ +struct PP_BitstreamBuffer { + /** + * The size, in bytes, of the bitstream data. + */ + uint32_t size; + /** + * The base address of the bitstream data. + */ + void* buffer; + /** + * Whether the buffer represents a key frame. + */ + PP_Bool key_frame; +}; /** * @} */
diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h index 91f7a90..63571a7 100644 --- a/ppapi/c/pp_macros.h +++ b/ppapi/c/pp_macros.h
@@ -3,13 +3,13 @@ * found in the LICENSE file. */ -/* From pp_macros.idl modified Thu Jun 26 10:08:35 2014. */ +/* From pp_macros.idl modified Fri Jun 6 18:08:58 2014. */ #ifndef PPAPI_C_PP_MACROS_H_ #define PPAPI_C_PP_MACROS_H_ -#define PPAPI_RELEASE 41 +#define PPAPI_RELEASE 42 /** * @file
diff --git a/ppapi/c/ppb_video_encoder.h b/ppapi/c/ppb_video_encoder.h new file mode 100644 index 0000000..744c3d3 --- /dev/null +++ b/ppapi/c/ppb_video_encoder.h
@@ -0,0 +1,243 @@ +/* Copyright 2015 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* From ppb_video_encoder.idl modified Thu Feb 5 10:33:32 2015. */ + +#ifndef PPAPI_C_PPB_VIDEO_ENCODER_H_ +#define PPAPI_C_PPB_VIDEO_ENCODER_H_ + +#include "ppapi/c/pp_array_output.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_codecs.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/ppb_video_frame.h" + +#define PPB_VIDEOENCODER_INTERFACE_0_1 "PPB_VideoEncoder;0.1" /* dev */ +/** + * @file + * This file defines the <code>PPB_VideoEncoder</code> interface. + */ + + +/** + * @addtogroup Interfaces + * @{ + */ +/** + * Video encoder interface. + * + * Typical usage: + * - Call Create() to create a new video encoder resource. + * - Call GetSupportedFormats() to determine which codecs and profiles are + * available. + * - Call Initialize() to initialize the encoder for a supported profile. + * - Call GetVideoFrame() to get a blank frame and fill it in, or get a video + * frame from another resource, e.g. <code>PPB_MediaStreamVideoTrack</code>. + * - Call Encode() to push the video frame to the encoder. If an external frame + * is pushed, wait for completion to recycle the frame. + * - Call GetBitstreamBuffer() continuously (waiting for each previous call to + * complete) to pull encoded pictures from the encoder. + * - Call RecycleBitstreamBuffer() after consuming the data in the bitstream + * buffer. + * - To destroy the encoder, the plugin should release all of its references to + * it. Any pending callbacks will abort before the encoder is destroyed. + * + * Available video codecs vary by platform. + * All: theora, vorbis, vp8. + * Chrome and ChromeOS: h264. + * ChromeOS: mpeg4. + */ +struct PPB_VideoEncoder_0_1 { /* dev */ + /** + * Creates a new video encoder resource. + * + * @param[in] instance A <code>PP_Instance</code> identifying the instance + * with the video encoder. + * + * @return A <code>PP_Resource</code> corresponding to a video encoder if + * successful or 0 otherwise. + */ + PP_Resource (*Create)(PP_Instance instance); + /** + * Determines if the given resource is a video encoder. + * + * @param[in] resource A <code>PP_Resource</code> identifying a resource. + * + * @return <code>PP_TRUE</code> if the resource is a + * <code>PPB_VideoEncoder</code>, <code>PP_FALSE</code> if the resource is + * invalid or some other type. + */ + PP_Bool (*IsVideoEncoder)(PP_Resource resource); + /** + * Gets an array of supported video encoder profiles. + * These can be used to choose a profile before calling Initialize(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] output A <code>PP_ArrayOutput</code> to receive the supported + * <code>PP_VideoProfileDescription</code> structs. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return If >= 0, the number of supported profiles returned, otherwise an + * error code from <code>pp_errors.h</code>. + */ + int32_t (*GetSupportedProfiles)(PP_Resource video_encoder, + struct PP_ArrayOutput output, + struct PP_CompletionCallback callback); + /** + * Initializes a video encoder resource. The plugin should call Initialize() + * successfully before calling any of the functions below. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] input_format The <code>PP_VideoFrame_Format</code> of the + * frames which will be encoded. + * @param[in] input_visible_size A <code>PP_Size</code> specifying the + * dimensions of the visible part of the input frames. + * @param[in] output_profile A <code>PP_VideoProfile</code> specifying the + * codec profile of the encoded output stream. + * @param[in] acceleration A <code>PP_HardwareAcceleration</code> specifying + * whether to use a hardware accelerated or a software implementation. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_NOTSUPPORTED if video encoding is not available, or the + * requested codec profile is not supported. + */ + int32_t (*Initialize)(PP_Resource video_encoder, + PP_VideoFrame_Format input_format, + const struct PP_Size* input_visible_size, + PP_VideoProfile output_profile, + uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + struct PP_CompletionCallback callback); + /** + * Gets the number of input video frames that the encoder may hold while + * encoding. If the plugin is providing the video frames, it should have at + * least this many available. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @return An int32_t containing the number of frames required, or an error + * code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t (*GetFramesRequired)(PP_Resource video_encoder); + /** + * Gets the coded size of the video frames required by the encoder. Coded + * size is the logical size of the input frames, in pixels. The encoder may + * have hardware alignment requirements that make this different from + * |input_visible_size|, as requested in the call to Initialize(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] coded_size A <code>PP_Size</code> to hold the coded size. + * @return An int32_t containing a result code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t (*GetFrameCodedSize)(PP_Resource video_encoder, + struct PP_Size* coded_size); + /** + * Gets a blank video frame which can be filled with video data and passed + * to the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[out] video_frame A blank <code>PPB_VideoFrame</code> resource. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t (*GetVideoFrame)(PP_Resource video_encoder, + PP_Resource* video_frame, + struct PP_CompletionCallback callback); + /** + * Encodes a video frame. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] video_frame The <code>PPB_VideoFrame</code> to be encoded. + * @param[in] force_keyframe A <code>PP_Bool> specifying whether the encoder + * should emit a key frame for this video frame. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. Plugins that pass <code>PPB_VideoFrame</code> resources owned + * by other resources should wait for completion before reusing them. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + */ + int32_t (*Encode)(PP_Resource video_encoder, + PP_Resource video_frame, + PP_Bool force_keyframe, + struct PP_CompletionCallback callback); + /** + * Gets the next encoded bitstream buffer from the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[out] bitstream_buffer A <code>PP_BitstreamBuffer</code> containing + * encoded video data. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon + * completion. The plugin can call GetBitstreamBuffer from the callback in + * order to continuously "pull" bitstream buffers from the encoder. + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + * Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + * Returns PP_ERROR_INPROGRESS if a prior call to GetBitstreamBuffer() has + * not completed. + */ + int32_t (*GetBitstreamBuffer)(PP_Resource video_encoder, + struct PP_BitstreamBuffer* bitstream_buffer, + struct PP_CompletionCallback callback); + /** + * Recycles a bitstream buffer back to the encoder. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] bitstream_buffer A <code>PP_BitstreamBuffer</code> that is no + * longer needed by the plugin. + */ + void (*RecycleBitstreamBuffer)( + PP_Resource video_encoder, + const struct PP_BitstreamBuffer* bitstream_buffer); + /** + * Requests a change to encoding parameters. This is only a request, + * fulfilled on a best-effort basis. + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + * @param[in] bitrate The requested new bitrate, in bits per second. + * @param[in] framerate The requested new framerate, in frames per second. + */ + void (*RequestEncodingParametersChange)(PP_Resource video_encoder, + uint32_t bitrate, + uint32_t framerate); + /** + * Closes the video encoder, and cancels any pending encodes. Any pending + * callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> . It is + * not valid to call any encoder functions after a call to this method. + * <strong>Note:</strong> Destroying the video encoder closes it implicitly, + * so you are not required to call Close(). + * + * @param[in] video_encoder A <code>PP_Resource</code> identifying the video + * encoder. + */ + void (*Close)(PP_Resource video_encoder); +}; +/** + * @} + */ + +#endif /* PPAPI_C_PPB_VIDEO_ENCODER_H_ */ +
diff --git a/ppapi/c/private/ppb_image_capture_config_private.h b/ppapi/c/private/ppb_image_capture_config_private.h deleted file mode 100644 index 3788b67..0000000 --- a/ppapi/c/private/ppb_image_capture_config_private.h +++ /dev/null
@@ -1,115 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From private/ppb_image_capture_config_private.idl, - * modified Wed Aug 13 17:43:55 2014. - */ - -#ifndef PPAPI_C_PRIVATE_PPB_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ -#define PPAPI_C_PRIVATE_PPB_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ - -#include "ppapi/c/pp_bool.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_macros.h" -#include "ppapi/c/pp_resource.h" -#include "ppapi/c/pp_size.h" -#include "ppapi/c/pp_stdint.h" - -#define PPB_IMAGECAPTURECONFIG_PRIVATE_INTERFACE_0_1 \ - "PPB_ImageCaptureConfig_Private;0.1" -#define PPB_IMAGECAPTURECONFIG_PRIVATE_INTERFACE \ - PPB_IMAGECAPTURECONFIG_PRIVATE_INTERFACE_0_1 - -/** - * @file - * This file defines the PPB_ImageCaptureConfig_Private interface for - * establishing an image capture configuration resource within the browser. - */ - - -/** - * @addtogroup Interfaces - * @{ - */ -/** - * The <code>PPB_ImageCaptureConfig_Private</code> interface contains pointers - * to several functions for establishing image capture configuration within the - * browser. The new configuration will take effect after <code> - * PPB_ImageCapture_Private.SetConfig</code> is called. - */ -struct PPB_ImageCaptureConfig_Private_0_1 { - /** - * Creates a PPB_ImageCaptureConfig_Private resource. - * - * @param[in] instance A <code>PP_Instance</code> identifying one instance of - * a module. - * - * @return A <code>PP_Resource</code> corresponding to a - * PPB_ImageCaptureConfig_Private resource if successful, 0 if failed. - */ - PP_Resource (*Create)(PP_Instance instance); - /** - * IsImageCaptureConfig() determines if the given resource is a - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] resource A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * - * @return A <code>PP_Bool</code> containing <code>PP_TRUE</code> if the given - * resource is an <code>ImageCaptureConfig_Private</code> resource, otherwise - * <code>PP_FALSE</code>. - */ - PP_Bool (*IsImageCaptureConfig)(PP_Resource resource); - /** - * GetPreviewSize() returns the preview image size in pixels for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * @param[out] preview_size A <code>PP_Size</code> that indicates the - * requested preview image size. - */ - void (*GetPreviewSize)(PP_Resource config, struct PP_Size* preview_size); - /** - * SetPreviewSize() sets the preview image size for the given <code> - * PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to a - * <code>PPB_ImageCaptureConfig_Private</code>. - * @param[in] preview_size A <code>PP_Size</code> that indicates the requested - * preview image size. - */ - void (*SetPreviewSize)(PP_Resource config, - const struct PP_Size* preview_size); - /** - * GetJpegSize() returns the JPEG image size in pixels for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to an image - * capture config resource. - * @param[out] jpeg_size A <code>PP_Size</code> that indicates the current - * JPEG image size. - */ - void (*GetJpegSize)(PP_Resource config, struct PP_Size* jpeg_size); - /** - * SetJpegSize() sets the JPEG image size for the given - * <code>PPB_ImageCaptureConfig_Private</code>. - * - * @param[in] config A <code>PP_Resource</code> corresponding to a - * <code>PPB_ImageCaptureConfig_Private</code>. - * @param[in] jpeg_size A <code>PP_Size</code> that indicates the requested - * JPEG image size. - */ - void (*SetJpegSize)(PP_Resource config, const struct PP_Size* jpeg_size); -}; - -typedef struct PPB_ImageCaptureConfig_Private_0_1 - PPB_ImageCaptureConfig_Private; -/** - * @} - */ - -#endif /* PPAPI_C_PRIVATE_PPB_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ */ -
diff --git a/ppapi/c/private/ppb_image_capture_private.h b/ppapi/c/private/ppb_image_capture_private.h index 190c9a65..0c04c05 100644 --- a/ppapi/c/private/ppb_image_capture_private.h +++ b/ppapi/c/private/ppb_image_capture_private.h
@@ -4,7 +4,7 @@ */ /* From private/ppb_image_capture_private.idl, - * modified Wed Aug 13 17:26:13 2014. + * modified Thu Feb 5 22:47:43 2015. */ #ifndef PPAPI_C_PRIVATE_PPB_IMAGE_CAPTURE_PRIVATE_H_ @@ -30,93 +30,16 @@ /** - * @addtogroup Typedefs - * @{ - */ -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to indicate the image has been captured from the sensor. This is a - * good opportunity to play a shutter sound or give other feedback of camera - * operation. This will occur after the image was captured, but before the - * actual data is available. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - */ -typedef void (*PPB_ImageCapture_Private_ShutterCallback)(void* user_data, - int64_t sequence_id); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to deliver a preview image. The client can use this to show the - * captured image. See <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> for more information. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |preview| A <code>PP_Resource</code> corresponding to a VideoFrame - * resource used to store the preview image. - */ -typedef void (*PPB_ImageCapture_Private_PreviewCallback)(void* user_data, - int64_t sequence_id, - PP_Resource preview); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to deliver a still JPEG image. See <code> - * PPB_ImageCapture_Private.CaptureStillImage</code> for more information. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |jpeg| A <code>PP_Resource</code> corresponding to a VideoFrame - * resource used to store the JPEG image. - */ -typedef void (*PPB_ImageCapture_Private_JpegCallback)(void* user_data, - int64_t sequence_id, - PP_Resource jpeg); - -/** - * Callback function for <code>PPB_ImageCapture_Private.CaptureStillImage - * </code> to indicate the image capture has failed. - * - * Parameters: - * |user_data| The same pointer that was passed into <code> - * PPB_ImageCapture_Private.Create()</code>. - * |sequence_id| The sequence ID of the image capture, same as the one from - * CaptureStillImage. - * |int32_t| An error code from <code>pp_errors.h</code>. - */ -typedef void (*PPB_ImageCapture_Private_ErrorCallback)(void* user_data, - int64_t sequence_id, - int32_t pp_error); -/** - * @} - */ - -/** * @addtogroup Interfaces * @{ */ /** - * To capture a still image with this class, use the following steps. + * To query camera capabilities: * 1. Get a PPB_ImageCapture_Private object by Create(). - * 2. Call GetCameraCapabilities to get the supported preview sizes. - * 3. For optimal performance, set one of the supported preview size as the - * constraints of getUserMedia. Use the created MediaStreamVideoTrack for - * camera previews. - * 4. Set the same preview size and other settings by SetConfig. - * 5. Call CaptureStillImage to capture a still image. Play the shutter sound in - * the shutter callback. The image from the preview callback can be used for - * display. JPEG image will be returned to the JPEG callback. + * 2. Open() camera device with track id of MediaStream video track. + * 3. Call GetCameraCapabilities() to get a + * <code>PPB_CameraCapabilities_Private</code> object, which can be used to + * query camera capabilities. */ struct PPB_ImageCapture_Private_0_1 { /** @@ -139,7 +62,6 @@ */ PP_Resource (*Create)(PP_Instance instance, struct PP_Var camera_source_id, - PPB_ImageCapture_Private_ErrorCallback error_callback, void* user_data); /** * Determines if a resource is an image capture resource. @@ -167,40 +89,6 @@ */ int32_t (*Close)(PP_Resource resource, struct PP_CompletionCallback callback); /** - * Sets the configuration of the image capture. - * If <code>SetConfig()</code> is not called, default settings will be used. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[in] config A <code>PP_ImageCaptureConfig_Private</code> object. - * @param[in] callback <code>PP_CompletionCallback</code> to be called upon - * completion of <code>SetConfig()</code>. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - * Returns <code>PP_ERROR_INPROGRESS</code> if there is a pending call of - * <code>SetConfig()</code> or <code>CaptureStillImage()</code>. - * If an error is returned, the configuration will not be changed. - */ - int32_t (*SetConfig)(PP_Resource image_capture, - PP_Resource config, - struct PP_CompletionCallback callback); - /** - * Gets the configuration of the image capture. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[out] config A <code>PP_ImageCaptureConfig_Private</code> for storing - * the current image capture config on success. Otherwise, the values will not - * be changed. - * @param[in] callback <code>PP_CompletionCallback</code> to be called upon - * completion of <code>GetConfig()</code>. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - */ - int32_t (*GetConfig)(PP_Resource image_capture, - PP_Resource* config, - struct PP_CompletionCallback callback); - /** * Gets the camera capabilities. * * The camera capabilities do not change for a given camera source. @@ -218,59 +106,6 @@ int32_t (*GetCameraCapabilities)(PP_Resource image_capture, PP_Resource* capabilities, struct PP_CompletionCallback callback); - /** - * Captures a still JPEG image from the camera. - * - * Triggers an asynchronous image capture. The camera will initiate a series - * of callbacks to the application as the image capture progresses. The - * callbacks will be invoked in the order of shutter callback, preview - * callback, and JPEG callback. The shutter callback occurs after the image is - * captured. This can be used to trigger a sound to let the user know that - * image has been captured. The preview callback occurs when a scaled, fully - * processed preview image is available. The JPEG callback occurs when the - * compressed image is available. If there is an error after the capture is in - * progress, the error callback passed to <code> - * PPB_ImageCapture_Private.Create()</code> will be invoked. All the callbacks - * are invoked by the thread that calls this function. - * - * The size of the preview image in preview callback is determined by - * <code>PPB_ImageCaptureConfig_Private.SetPreviewSize</code>. The format is - * decided by the camera and can be got from <code>PPB_VideoFrame.GetFormat - * </code>. The size of the JPEG image is determined by <code> - * PPB_ImageCaptureConfig_Private.SetJpegSize</code>. - * - * The camera may need to stop and re-start streaming during image capture. If - * some MediaStreamVideoTrack are associated with the camera source, they will - * receive mute and unmute events. The mute event will be received before all - * the callbacks. The unmute event will be received after all the callbacks. - * The preview image will not be sent to the video tracks associated with the - * camera. - * - * @param[in] image_capture A <code>PP_Resource</code> corresponding to an - * image capture resource. - * @param[in] shutter_callback A <code> - * PPB_ImageCapture_Private_ShutterCallback</code> callback to indicate the - * image has been taken. - * @param[in] preview_callback A <code> - * PPB_ImageCapture_Private_PreviewCallback</code> callback to return a - * preview of the captured image. - * @param[in] jpeg_callback A <code> - * PPB_ImageCapture_Private_JpegCallback</code> callback to return captured - * JPEG image. - * @param[out] sequence_id The sequence ID is a unique monotonically - * increasing value starting from 0, incremented every time a new request like - * image capture is submitted. - * - * @return An int32_t containing a result code from <code>pp_errors.h</code>. - * PP_OK means the callbacks will be triggered. Other values mean the - * callbacks will not be triggered. - */ - int32_t (*CaptureStillImage)( - PP_Resource image_capture, - PPB_ImageCapture_Private_ShutterCallback shutter_callback, - PPB_ImageCapture_Private_PreviewCallback preview_callback, - PPB_ImageCapture_Private_JpegCallback jpeg_callback, - int64_t* sequence_id); }; typedef struct PPB_ImageCapture_Private_0_1 PPB_ImageCapture_Private;
diff --git a/ppapi/cpp/private/image_capture_config_private.h b/ppapi/cpp/private/image_capture_config_private.h deleted file mode 100644 index a4847fb3..0000000 --- a/ppapi/cpp/private/image_capture_config_private.h +++ /dev/null
@@ -1,99 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef PPAPI_CPP_PRIVATE_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ -#define PPAPI_CPP_PRIVATE_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ - -#include "ppapi/c/private/ppb_image_capture_config_private.h" -#include "ppapi/cpp/resource.h" -#include "ppapi/cpp/size.h" - -/// @file -/// This file defines the ImageCaptureConfig_Private interface for -/// establishing an image capture configuration resource within the browser. -namespace pp { - -/// The <code>ImageCaptureConfig_Private</code> interface contains methods for -/// establishing image capture configuration within the browser. The new -/// configuration will take effect after <code> -/// ImageCaptureConfig_Private.SetConfig</code> is called. -class ImageCaptureConfig_Private { - public: - /// Default constructor for creating an is_null() - /// <code>ImageCaptureConfig_Private</code> object. - ImageCaptureConfig_Private(); - - /// The copy constructor for <code>ImageCaptureConfig_Private</code>. - /// - /// @param[in] other A reference to a <code>ImageCaptureConfig_Private - /// </code>. - ImageCaptureConfig_Private(const ImageCaptureConfig_Private& other); - - /// Constructs a <code>ImageCaptureConfig_Private</code> from a <code> - /// Resource</code>. - /// - /// @param[in] resource A <code>PPB_ImageCaptureConfig_Private</code> - /// resource. - explicit ImageCaptureConfig_Private(const Resource& resource); - - /// Constructs a <code>ImageCaptureConfig_Private</code> object. - /// - /// @param[in] instance The instance with which this resource will be - /// associated. - explicit ImageCaptureConfig_Private(const InstanceHandle& instance); - - /// A constructor used when you have received a <code>PP_Resource</code> as a - /// return value that has had 1 ref added for you. - /// - /// @param[in] resource A <code>PPB_ImageCaptureConfig_Private</code> - /// resource. - ImageCaptureConfig_Private(PassRef, PP_Resource resource); - - // Destructor. - ~ImageCaptureConfig_Private(); - - /// GetPreviewSize() returns the preview image size in pixels for the given - /// <code>ImageCaptureConfig_Private</code>. - /// - /// @param[out] preview_size A <code>Size</code> that indicates the - /// requested preview image size. - void GetPreviewSize(Size* preview_size); - - /// SetPreviewSize() sets the preview image size for the given <code> - /// ImageCaptureConfig_Private</code>. - /// - /// @param[in] preview_size A <code>Size</code> that indicates the - /// requested preview image size. - void SetPreviewSize(const Size& preview_size); - - /// GetJpegSize() returns the JPEG image size in pixels for the given - /// <code>ImageCaptureConfig_Private</code>. - /// - /// @param[out] jpeg_size A <code>Size</code> that indicates the current - /// JPEG image size. - void GetJpegSize(Size* jpeg_size); - - /// SetJpegSize() sets the JPEG image size for the given <code> - /// ImageCaptureConfig_Private</code>. - /// - /// @param[in] jpeg_size A <code>Size</code> that indicates the requested - /// JPEG image size. - void SetJpegSize(const Size& jpeg_size); - - /// IsImageCaptureConfig() determines if the given resource is a - /// <code>ImageCaptureConfig_Private</code>. - /// - /// @param[in] resource A <code>Resource</code> corresponding to an image - /// capture config resource. - /// - /// @return true if the given resource is an <code> - /// ImageCaptureConfig_Private</code> resource, otherwise false. - static bool IsImageCaptureConfig(const Resource& resource); -}; - -} // namespace pp - -#endif /* PPAPI_CPP_PRIVATE_IMAGE_CAPTURE_CONFIG_PRIVATE_H_ */ -
diff --git a/ppapi/cpp/private/image_capture_private.h b/ppapi/cpp/private/image_capture_private.h index ab4afbb..eede24a 100644 --- a/ppapi/cpp/private/image_capture_private.h +++ b/ppapi/cpp/private/image_capture_private.h
@@ -9,7 +9,6 @@ #include "ppapi/c/private/ppb_image_capture_private.h" #include "ppapi/cpp/completion_callback.h" #include "ppapi/cpp/private/camera_capabilities_private.h" -#include "ppapi/cpp/private/image_capture_config_private.h" #include "ppapi/cpp/resource.h" #include "ppapi/cpp/var.h" @@ -18,16 +17,12 @@ /// acquiring a single still image from a camera source. namespace pp { -/// To capture a still image with this class, use the following steps. -/// 1. Create an ImageCapture_Private object by the constructor. -/// 2. Call GetCameraCapabilities to get the supported preview sizes. -/// 3. For optimal performance, set one of the supported preview size as the -/// constraints of getUserMedia. Use the created MediaStreamVideoTrack for -/// camera previews. -/// 4. Set the same preview size and other settings by SetConfig. -/// 5. Call CaptureStillImage to capture a still image. Play the shutter sound -/// in the shutter callback. The image from the preview callback can be used -/// for display. JPEG image will be returned to the JPEG callback. +/// To query camera capabilities: +/// 1. Get a PPB_ImageCapture_Private object by Create(). +/// 2. Open() camera device with track id of MediaStream video track. +/// 3. Call GetCameraCapabilities() to get a +/// <code>PPB_CameraCapabilities_Private</code> object, which can be used to +/// query camera capabilities. class ImageCapture_Private { public: /// Default constructor for creating an is_null() @@ -49,7 +44,6 @@ /// callbacks of ImageCapture_Private. ImageCapture_Private(const InstanceHandle& instance, const Var& camera_source_id, - PPB_ImageCapture_Private_ErrorCallback error_callback, void* user_data); /// Constructs a <code>ImageCapture_Private</code> from a <code> @@ -81,29 +75,6 @@ /// @return An int32_t containing a result code from <code>pp_errors.h</code>. int32_t Close(const CompletionCallback& callback); - /// Sets the configuration of the image capture. - /// If <code>SetConfig()</code> is not called, default settings will be used. - /// - /// @param[in] config A <code>ImageCaptureConfig_Private</code> object. - /// @param[in] callback <code>CompletionCallback</code> to be called upon - /// completion of <code>SetConfig()</code>. - /// - /// @return An int32_t containing a result code from <code>pp_errors.h</code>. - /// Returns <code>PP_ERROR_INPROGRESS</code> if there is a pending call of - /// <code>SetConfig()</code> or <code>CaptureStillImage()</code>. - /// If an error is returned, the configuration will not be changed. - int32_t SetConfig(const ImageCaptureConfig_Private& config, - const CompletionCallback& callback); - - /// Gets the configuration of the image capture. - /// - /// @param[in] callback A <code>CompletionCallbackWithOutput</code> - /// to be called upon completion. - /// - /// @return An int32_t containing a result code from <code>pp_errors.h</code>. - int32_t GetConfig( - const CompletionCallbackWithOutput<ImageCaptureConfig_Private>& callback); - /// Gets the camera capabilities. /// /// The camera capabilities do not change for a given camera source. @@ -115,55 +86,6 @@ int32_t GetCameraCapabilities( const CompletionCallbackWithOutput<CameraCapabilities_Private>& callback); - /// Captures a still JPEG image from the camera. - /// - /// Triggers an asynchronous image capture. The camera will initiate a series - /// of callbacks to the application as the image capture progresses. The - /// callbacks will be invoked in the order of shutter callback, preview - /// callback, and JPEG callback. The shutter callback occurs after the image - /// is captured. This can be used to trigger a sound to let the user know that - /// image has been captured. The preview callback occurs when a scaled, fully - /// processed preview image is available. The JPEG callback occurs when the - /// compressed image is available. If there is an error after the capture is - /// in progress, the error callback passed to <code> - /// ImageCapture_Private.Create()</code> will be invoked. All the callbacks - /// are invoked by the thread that calls this function. - /// - /// The size of the preview image in preview callback is determined by - /// <code>ImageCaptureConfig_Private.SetPreviewSize</code>. The format is - /// decided by the camera and can be got from <code>VideoFrame.GetFormat - /// </code>. The size of the JPEG image is determined by <code> - /// ImageCaptureConfig_Private.SetJpegSize</code>. - /// - /// The camera may need to stop and re-start streaming during image capture. - /// If some MediaStreamVideoTrack are associated with the camera source, they - /// will receive mute and unmute events. The mute event will be received - /// before all the callbacks. The unmute event will be received after all the - /// callbacks. The preview image will not be sent to the video tracks - /// associated with the camera. - /// - /// @param[in] shutter_callback A <code> - /// ImageCapture_Private_ShutterCallback</code> callback to indicate the - /// image has been taken. - /// @param[in] preview_callback A <code> - /// ImageCapture_Private_PreviewCallback</code> callback to return a - /// preview of the captured image. - /// @param[in] jpeg_callback A <code> - /// ImageCapture_Private_JpegCallback</code> callback to return captured - /// JPEG image. - /// @param[out] sequence_id The sequence ID is a unique monotonically - /// increasing value starting from 0, incremented every time a new request - /// like image capture is submitted. - /// - /// @return An int32_t containing a result code from <code>pp_errors.h</code>. - /// PP_OK means the callbacks will be triggered. Other values mean the - /// callbacks will not be triggered. - int32_t CaptureStillImage( - PPB_ImageCapture_Private_ShutterCallback shutter_callback, - PPB_ImageCapture_Private_PreviewCallback preview_callback, - PPB_ImageCapture_Private_JpegCallback jpeg_callback, - int64_t* sequence_id); - /// Determines if a resource is an image capture resource. /// /// @param[in] resource The <code>Resource</code> to test.
diff --git a/ppapi/cpp/video_encoder.cc b/ppapi/cpp/video_encoder.cc new file mode 100644 index 0000000..a8c03f2 --- /dev/null +++ b/ppapi/cpp/video_encoder.cc
@@ -0,0 +1,129 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/video_encoder.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_video_encoder.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> +const char* interface_name<PPB_VideoEncoder_0_1>() { + return PPB_VIDEOENCODER_INTERFACE_0_1; +} + +} // namespace + +VideoEncoder::VideoEncoder() { +} + +VideoEncoder::VideoEncoder(const InstanceHandle& instance) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + PassRefFromConstructor( + get_interface<PPB_VideoEncoder_0_1>()->Create(instance.pp_instance())); + } +} + +VideoEncoder::VideoEncoder(const VideoEncoder& other) : Resource(other) { +} + +int32_t VideoEncoder::GetSupportedProfiles(const CompletionCallbackWithOutput< + std::vector<PP_VideoProfileDescription> >& cc) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->GetSupportedProfiles( + pp_resource(), cc.output(), cc.pp_completion_callback()); + } + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t VideoEncoder::Initialize(const PP_VideoFrame_Format& input_format, + const Size& input_visible_size, + const PP_VideoProfile& output_profile, + const uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + const CompletionCallback& cc) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->Initialize( + pp_resource(), input_format, &input_visible_size.pp_size(), + output_profile, initial_bitrate, acceleration, + cc.pp_completion_callback()); + } + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t VideoEncoder::GetFramesRequired() { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->GetFramesRequired( + pp_resource()); + } + return PP_ERROR_NOINTERFACE; +} + +int32_t VideoEncoder::GetFrameCodedSize(Size* coded_size) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->GetFrameCodedSize( + pp_resource(), &coded_size->pp_size()); + } + return PP_ERROR_NOINTERFACE; +} + +int32_t VideoEncoder::GetVideoFrame( + const CompletionCallbackWithOutput<VideoFrame>& cc) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->GetVideoFrame( + pp_resource(), cc.output(), cc.pp_completion_callback()); + } + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t VideoEncoder::Encode(const VideoFrame& video_frame, + bool force_keyframe, + const CompletionCallback& cc) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->Encode( + pp_resource(), video_frame.pp_resource(), PP_FromBool(force_keyframe), + cc.pp_completion_callback()); + } + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t VideoEncoder::GetBitstreamBuffer( + const CompletionCallbackWithOutput<PP_BitstreamBuffer>& cc) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + return get_interface<PPB_VideoEncoder_0_1>()->GetBitstreamBuffer( + pp_resource(), cc.output(), cc.pp_completion_callback()); + } + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +void VideoEncoder::RecycleBitstreamBuffer( + const PP_BitstreamBuffer& bitstream_buffer) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + get_interface<PPB_VideoEncoder_0_1>()->RecycleBitstreamBuffer( + pp_resource(), &bitstream_buffer); + } +} + +void VideoEncoder::RequestEncodingParametersChange(uint32_t bitrate, + uint32_t framerate) { + if (has_interface<PPB_VideoEncoder_0_1>()) { + get_interface<PPB_VideoEncoder_0_1>()->RequestEncodingParametersChange( + pp_resource(), bitrate, framerate); + } +} + +void VideoEncoder::Close() { + if (has_interface<PPB_VideoEncoder_0_1>()) { + get_interface<PPB_VideoEncoder_0_1>()->Close(pp_resource()); + } +} + +} // namespace pp
diff --git a/ppapi/cpp/video_encoder.h b/ppapi/cpp/video_encoder.h new file mode 100644 index 0000000..44160d90 --- /dev/null +++ b/ppapi/cpp/video_encoder.h
@@ -0,0 +1,179 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_CPP_VIDEO_ENCODER_H_ +#define PPAPI_CPP_VIDEO_ENCODER_H_ + +#include "ppapi/c/pp_codecs.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/resource.h" +#include "ppapi/cpp/size.h" +#include "ppapi/cpp/video_frame.h" + +/// @file +/// This file defines the API to create and use a VideoEncoder resource. + +namespace pp { + +class InstanceHandle; + +/// Video encoder interface. +/// +/// Typical usage: +/// - Call Create() to create a new video encoder resource. +/// - Call GetSupportedFormats() to determine which codecs and profiles are +/// available. +/// - Call Initialize() to initialize the encoder for a supported profile. +/// - Call GetVideoFrame() to get a blank frame and fill it in, or get a video +/// frame from another resource, e.g. <code>PPB_MediaStreamVideoTrack</code>. +/// - Call Encode() to push the video frame to the encoder. If an external frame +/// is pushed, wait for completion to recycle the frame. +/// - Call GetBitstreamBuffer() continuously (waiting for each previous call to +/// complete) to pull encoded pictures from the encoder. +/// - Call RecycleBitstreamBuffer() after consuming the data in the bitstream +/// buffer. +/// - To destroy the encoder, the plugin should release all of its references to +/// it. Any pending callbacks will abort before the encoder is destroyed. +/// +/// Available video codecs vary by platform. +/// All: theora, vorbis, vp8. +/// Chrome and ChromeOS: h264. +/// ChromeOS: mpeg4. +class VideoEncoder : public Resource { + public: + /// Default constructor for creating an is_null() <code>VideoEncoder</code> + /// object. + VideoEncoder(); + + /// A constructor used to create a <code>VideoEncoder</code> and associate it + /// with the provided <code>Instance</code>. + /// @param[in] instance The instance with which this resource will be + /// associated. + explicit VideoEncoder(const InstanceHandle& instance); + + /// The copy constructor for <code>VideoEncoder</code>. + /// @param[in] other A reference to a <code>VideoEncoder</code>. + VideoEncoder(const VideoEncoder& other); + + /// Gets an array of supported video encoder profiles. + /// These can be used to choose a profile before calling Initialize(). + /// + /// @param[in] callback A <code>CompletionCallbackWithOutput</code> to be + /// called upon completion with the PP_VideoProfileDescription structs. + /// + /// @return If >= 0, the number of supported profiles returned, otherwise an + /// error code from <code>pp_errors.h</code>. + int32_t GetSupportedProfiles(const CompletionCallbackWithOutput< + std::vector<PP_VideoProfileDescription> >& cc); + + /// Initializes a video encoder resource. This should be called after + /// GetSupportedProfiles() and before any functions below. + /// + /// @param[in] input_format The <code>PP_VideoFrame_Format</code> of the + /// frames which will be encoded. + /// @param[in] input_visible_size A <code>Size</code> specifying the + /// dimensions of the visible part of the input frames. + /// @param[in] output_profile A <code>PP_VideoProfile</code> specifying the + /// codec profile of the encoded output stream. + /// @param[in] acceleration A <code>PP_HardwareAcceleration</code> specifying + /// whether to use a hardware accelerated or a software implementation. + /// @param[in] callback A <code>CompletionCallback</code> to be called upon + /// completion. + /// + /// @return An int32_t containing an error code from <code>pp_errors.h</code>. + /// Returns PP_ERROR_NOTSUPPORTED if video encoding is not available, or the + /// requested codec profile is not supported. + /// Returns PP_ERROR_NOMEMORY if frame and bitstream buffers can't be created. + int32_t Initialize(const PP_VideoFrame_Format& input_format, + const Size& input_visible_size, + const PP_VideoProfile& output_profile, + const uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + const CompletionCallback& cc); + + /// Gets the number of input video frames that the encoder may hold while + /// encoding. If the plugin is providing the video frames, it should have at + /// least this many available. + /// + /// @return An int32_t containing the number of frames required, or an error + /// code from <code>pp_errors.h</code>. + /// Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + int32_t GetFramesRequired(); + + /// Gets the coded size of the video frames required by the encoder. Coded + /// size is the logical size of the input frames, in pixels. The encoder may + /// have hardware alignment requirements that make this different from + /// |input_visible_size|, as requested in the call to Initialize(). + /// + /// @param[in] coded_size A <code>Size</code> to hold the coded size. + /// + /// @return An int32_t containing a result code from <code>pp_errors.h</code>. + /// Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + int32_t GetFrameCodedSize(Size* coded_size); + + /// Gets a blank video frame which can be filled with video data and passed + /// to the encoder. + /// + /// @param[in] callback A <code>CompletionCallbackWithOutput</code> to be + /// called upon completion with the blank <code>VideoFrame</code> resource. + /// + /// @return An int32_t containing an error code from <code>pp_errors.h</code>. + int32_t GetVideoFrame(const CompletionCallbackWithOutput<VideoFrame>& cc); + + /// Encodes a video frame. + /// + /// @param[in] video_frame The <code>VideoFrame</code> to be encoded. + /// @param[in] force_keyframe A <code>PP_Bool> specifying whether the encoder + /// should emit a key frame for this video frame. + /// @param[in] callback A <code>CompletionCallback</code> to be called upon + /// completion. Plugins that pass <code>VideoFrame</code> resources owned + /// by other resources should wait for completion before reusing them. + /// + /// @return An int32_t containing an error code from <code>pp_errors.h</code>. + /// Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + int32_t Encode(const VideoFrame& video_frame, + bool force_keyframe, + const CompletionCallback& cc); + + /// Gets the next encoded bitstream buffer from the encoder. + /// + /// @param[out] bitstream_buffer A <code>PP_BitstreamBuffer</code> containing + /// encoded video data. + /// @param[in] callback A <code>CompletionCallbackWithOutput</code> to be + /// called upon completion with the next bitstream buffer. The plugin can call + /// GetBitstreamBuffer from the callback in order to continuously "pull" + /// bitstream buffers from the encoder. + /// + /// @return An int32_t containing an error code from <code>pp_errors.h</code>. + /// Returns PP_ERROR_FAILED if Initialize() has not successfully completed. + /// Returns PP_ERROR_INPROGRESS if a prior call to GetBitstreamBuffer() has + /// not completed. + int32_t GetBitstreamBuffer( + const CompletionCallbackWithOutput<PP_BitstreamBuffer>& cc); + + /// Recycles a bitstream buffer back to the encoder. + /// + /// @param[in] bitstream_buffer A <code>PP_BitstreamBuffer</code> that is no + /// longer needed by the plugin. + void RecycleBitstreamBuffer(const PP_BitstreamBuffer& bitstream_buffer); + + /// Requests a change to encoding parameters. This is only a request, + /// fulfilled on a best-effort basis. + /// + /// @param[in] bitrate The requested new bitrate, in bits per second. + /// @param[in] framerate The requested new framerate, in frames per second. + void RequestEncodingParametersChange(uint32_t bitrate, uint32_t framerate); + + /// Closes the video encoder, and cancels any pending encodes. Any pending + /// callbacks will still run, reporting <code>PP_ERROR_ABORTED</code> . It is + /// not valid to call any encoder functions after a call to this method. + /// <strong>Note:</strong> Destroying the video encoder closes it implicitly, + /// so you are not required to call Close(). + void Close(); +}; + +} // namespace pp + +#endif // PPAPI_CPP_VIDEO_ENCODER_H_
diff --git a/ppapi/native_client/native_client.gyp b/ppapi/native_client/native_client.gyp index 24d220ae..0735558d 100644 --- a/ppapi/native_client/native_client.gyp +++ b/ppapi/native_client/native_client.gyp
@@ -139,6 +139,7 @@ '-lipc_nacl', '-lbase_nacl', '-lshared_memory_support_nacl', + '-lsrpc', '-limc_syscalls', '-lplatform', '-lgio', @@ -180,6 +181,7 @@ '>(tc_lib_dir_irt64)/libirt_browser.a', '>(tc_lib_dir_irt64)/libpnacl_irt_shim_for_irt.a', '>(tc_lib_dir_irt64)/libshared_memory_support_nacl.a', + '>(tc_lib_dir_irt64)/libsrpc.a', '>(tc_lib_dir_irt64)/libplatform.a', '>(tc_lib_dir_irt64)/libimc_syscalls.a', '>(tc_lib_dir_irt64)/libgio.a', @@ -200,6 +202,7 @@ '>(tc_lib_dir_irt32)/libirt_browser.a', '>(tc_lib_dir_irt32)/libpnacl_irt_shim_for_irt.a', '>(tc_lib_dir_irt32)/libshared_memory_support_nacl.a', + '>(tc_lib_dir_irt32)/libsrpc.a', '>(tc_lib_dir_irt32)/libplatform.a', '>(tc_lib_dir_irt32)/libimc_syscalls.a', '>(tc_lib_dir_irt32)/libgio.a', @@ -222,6 +225,7 @@ '>(tc_lib_dir_irt_arm)/libirt_browser.a', '>(tc_lib_dir_irt_arm)/libpnacl_irt_shim_for_irt.a', '>(tc_lib_dir_irt_arm)/libshared_memory_support_nacl.a', + '>(tc_lib_dir_irt_arm)/libsrpc.a', '>(tc_lib_dir_irt_arm)/libplatform.a', '>(tc_lib_dir_irt_arm)/libimc_syscalls.a', '>(tc_lib_dir_irt_arm)/libgio.a', @@ -244,6 +248,7 @@ '>(tc_lib_dir_irt_mips)/libirt_browser.a', '>(tc_lib_dir_irt_mips)/libpnacl_irt_shim_for_irt.a', '>(tc_lib_dir_irt_mips)/libshared_memory_support_nacl.a', + '>(tc_lib_dir_irt_mips)/libsrpc.a', '>(tc_lib_dir_irt_mips)/libplatform.a', '>(tc_lib_dir_irt_mips)/libimc_syscalls.a', '>(tc_lib_dir_irt_mips)/libgio.a', @@ -267,6 +272,7 @@ '../../base/base_nacl.gyp:base_nacl', '../../media/media_nacl.gyp:shared_memory_support_nacl', '../../native_client/src/untrusted/irt/irt.gyp:irt_browser_lib', + '../../native_client/src/shared/srpc/srpc.gyp:srpc_lib', '../../native_client/src/shared/platform/platform.gyp:platform_lib', '../../native_client/src/tools/tls_edit/tls_edit.gyp:tls_edit#host', '../../native_client/src/untrusted/nacl/nacl.gyp:imc_syscalls_lib',
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 6d42f33..f77366e 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -50,6 +50,7 @@ #include "ppapi/c/ppb_var_array_buffer.h" #include "ppapi/c/ppb_var_dictionary.h" #include "ppapi/c/ppb_video_decoder.h" +#include "ppapi/c/ppb_video_encoder.h" #include "ppapi/c/ppb_websocket.h" #include "ppapi/c/ppp_messaging.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" @@ -148,6 +149,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_0_2; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_1_0; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoEncoder_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_WebSocket_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Messaging_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_AudioInput_Dev_0_3; @@ -2186,6 +2188,70 @@ /* End wrapper methods for PPB_VideoDecoder_1_0 */ +/* Begin wrapper methods for PPB_VideoEncoder_0_1 */ + +static PP_Resource Pnacl_M42_PPB_VideoEncoder_Create(PP_Instance instance) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->Create(instance); +} + +static PP_Bool Pnacl_M42_PPB_VideoEncoder_IsVideoEncoder(PP_Resource resource) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->IsVideoEncoder(resource); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_GetSupportedProfiles(PP_Resource video_encoder, struct PP_ArrayOutput* output, struct PP_CompletionCallback* callback) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->GetSupportedProfiles(video_encoder, *output, *callback); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_Initialize(PP_Resource video_encoder, PP_VideoFrame_Format input_format, const struct PP_Size* input_visible_size, PP_VideoProfile output_profile, uint32_t initial_bitrate, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback* callback) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->Initialize(video_encoder, input_format, input_visible_size, output_profile, initial_bitrate, acceleration, *callback); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_GetFramesRequired(PP_Resource video_encoder) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->GetFramesRequired(video_encoder); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_GetFrameCodedSize(PP_Resource video_encoder, struct PP_Size* coded_size) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->GetFrameCodedSize(video_encoder, coded_size); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_GetVideoFrame(PP_Resource video_encoder, PP_Resource* video_frame, struct PP_CompletionCallback* callback) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->GetVideoFrame(video_encoder, video_frame, *callback); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_Encode(PP_Resource video_encoder, PP_Resource video_frame, PP_Bool force_keyframe, struct PP_CompletionCallback* callback) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->Encode(video_encoder, video_frame, force_keyframe, *callback); +} + +static int32_t Pnacl_M42_PPB_VideoEncoder_GetBitstreamBuffer(PP_Resource video_encoder, struct PP_BitstreamBuffer* bitstream_buffer, struct PP_CompletionCallback* callback) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + return iface->GetBitstreamBuffer(video_encoder, bitstream_buffer, *callback); +} + +static void Pnacl_M42_PPB_VideoEncoder_RecycleBitstreamBuffer(PP_Resource video_encoder, const struct PP_BitstreamBuffer* bitstream_buffer) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + iface->RecycleBitstreamBuffer(video_encoder, bitstream_buffer); +} + +static void Pnacl_M42_PPB_VideoEncoder_RequestEncodingParametersChange(PP_Resource video_encoder, uint32_t bitrate, uint32_t framerate) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + iface->RequestEncodingParametersChange(video_encoder, bitrate, framerate); +} + +static void Pnacl_M42_PPB_VideoEncoder_Close(PP_Resource video_encoder) { + const struct PPB_VideoEncoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoEncoder_0_1.real_iface; + iface->Close(video_encoder); +} + +/* End wrapper methods for PPB_VideoEncoder_0_1 */ + /* Not generating wrapper methods for PPB_VideoFrame_0_1 */ /* Not generating wrapper methods for PPB_View_1_0 */ @@ -3527,13 +3593,11 @@ /* End wrapper methods for PPB_HostResolver_Private_0_1 */ -/* Not generating wrapper methods for PPB_ImageCaptureConfig_Private_0_1 */ - /* Begin wrapper methods for PPB_ImageCapture_Private_0_1 */ -static PP_Resource Pnacl_M39_PPB_ImageCapture_Private_Create(PP_Instance instance, struct PP_Var* camera_source_id, PPB_ImageCapture_Private_ErrorCallback error_callback, void* user_data) { +static PP_Resource Pnacl_M39_PPB_ImageCapture_Private_Create(PP_Instance instance, struct PP_Var* camera_source_id, void* user_data) { const struct PPB_ImageCapture_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_ImageCapture_Private_0_1.real_iface; - return iface->Create(instance, *camera_source_id, error_callback, user_data); + return iface->Create(instance, *camera_source_id, user_data); } static PP_Bool Pnacl_M39_PPB_ImageCapture_Private_IsImageCapture(PP_Resource resource) { @@ -3546,26 +3610,11 @@ return iface->Close(resource, *callback); } -static int32_t Pnacl_M39_PPB_ImageCapture_Private_SetConfig(PP_Resource image_capture, PP_Resource config, struct PP_CompletionCallback* callback) { - const struct PPB_ImageCapture_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_ImageCapture_Private_0_1.real_iface; - return iface->SetConfig(image_capture, config, *callback); -} - -static int32_t Pnacl_M39_PPB_ImageCapture_Private_GetConfig(PP_Resource image_capture, PP_Resource* config, struct PP_CompletionCallback* callback) { - const struct PPB_ImageCapture_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_ImageCapture_Private_0_1.real_iface; - return iface->GetConfig(image_capture, config, *callback); -} - static int32_t Pnacl_M39_PPB_ImageCapture_Private_GetCameraCapabilities(PP_Resource image_capture, PP_Resource* capabilities, struct PP_CompletionCallback* callback) { const struct PPB_ImageCapture_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_ImageCapture_Private_0_1.real_iface; return iface->GetCameraCapabilities(image_capture, capabilities, *callback); } -static int32_t Pnacl_M39_PPB_ImageCapture_Private_CaptureStillImage(PP_Resource image_capture, PPB_ImageCapture_Private_ShutterCallback shutter_callback, PPB_ImageCapture_Private_PreviewCallback preview_callback, PPB_ImageCapture_Private_JpegCallback jpeg_callback, int64_t* sequence_id) { - const struct PPB_ImageCapture_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_ImageCapture_Private_0_1.real_iface; - return iface->CaptureStillImage(image_capture, shutter_callback, preview_callback, jpeg_callback, sequence_id); -} - /* End wrapper methods for PPB_ImageCapture_Private_0_1 */ /* Not generating wrapper methods for PPB_InputEvent_Private_0_1 */ @@ -5140,6 +5189,21 @@ .Reset = (int32_t (*)(PP_Resource video_decoder, struct PP_CompletionCallback callback))&Pnacl_M40_PPB_VideoDecoder_Reset }; +static const struct PPB_VideoEncoder_0_1 Pnacl_Wrappers_PPB_VideoEncoder_0_1 = { + .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M42_PPB_VideoEncoder_Create, + .IsVideoEncoder = (PP_Bool (*)(PP_Resource resource))&Pnacl_M42_PPB_VideoEncoder_IsVideoEncoder, + .GetSupportedProfiles = (int32_t (*)(PP_Resource video_encoder, struct PP_ArrayOutput output, struct PP_CompletionCallback callback))&Pnacl_M42_PPB_VideoEncoder_GetSupportedProfiles, + .Initialize = (int32_t (*)(PP_Resource video_encoder, PP_VideoFrame_Format input_format, const struct PP_Size* input_visible_size, PP_VideoProfile output_profile, uint32_t initial_bitrate, PP_HardwareAcceleration acceleration, struct PP_CompletionCallback callback))&Pnacl_M42_PPB_VideoEncoder_Initialize, + .GetFramesRequired = (int32_t (*)(PP_Resource video_encoder))&Pnacl_M42_PPB_VideoEncoder_GetFramesRequired, + .GetFrameCodedSize = (int32_t (*)(PP_Resource video_encoder, struct PP_Size* coded_size))&Pnacl_M42_PPB_VideoEncoder_GetFrameCodedSize, + .GetVideoFrame = (int32_t (*)(PP_Resource video_encoder, PP_Resource* video_frame, struct PP_CompletionCallback callback))&Pnacl_M42_PPB_VideoEncoder_GetVideoFrame, + .Encode = (int32_t (*)(PP_Resource video_encoder, PP_Resource video_frame, PP_Bool force_keyframe, struct PP_CompletionCallback callback))&Pnacl_M42_PPB_VideoEncoder_Encode, + .GetBitstreamBuffer = (int32_t (*)(PP_Resource video_encoder, struct PP_BitstreamBuffer* bitstream_buffer, struct PP_CompletionCallback callback))&Pnacl_M42_PPB_VideoEncoder_GetBitstreamBuffer, + .RecycleBitstreamBuffer = (void (*)(PP_Resource video_encoder, const struct PP_BitstreamBuffer* bitstream_buffer))&Pnacl_M42_PPB_VideoEncoder_RecycleBitstreamBuffer, + .RequestEncodingParametersChange = (void (*)(PP_Resource video_encoder, uint32_t bitrate, uint32_t framerate))&Pnacl_M42_PPB_VideoEncoder_RequestEncodingParametersChange, + .Close = (void (*)(PP_Resource video_encoder))&Pnacl_M42_PPB_VideoEncoder_Close +}; + /* Not generating wrapper interface for PPB_VideoFrame_0_1 */ /* Not generating wrapper interface for PPB_View_1_0 */ @@ -5557,16 +5621,11 @@ .GetNetAddress = (PP_Bool (*)(PP_Resource host_resolver, uint32_t index, struct PP_NetAddress_Private* addr))&Pnacl_M19_PPB_HostResolver_Private_GetNetAddress }; -/* Not generating wrapper interface for PPB_ImageCaptureConfig_Private_0_1 */ - static const struct PPB_ImageCapture_Private_0_1 Pnacl_Wrappers_PPB_ImageCapture_Private_0_1 = { - .Create = (PP_Resource (*)(PP_Instance instance, struct PP_Var camera_source_id, PPB_ImageCapture_Private_ErrorCallback error_callback, void* user_data))&Pnacl_M39_PPB_ImageCapture_Private_Create, + .Create = (PP_Resource (*)(PP_Instance instance, struct PP_Var camera_source_id, void* user_data))&Pnacl_M39_PPB_ImageCapture_Private_Create, .IsImageCapture = (PP_Bool (*)(PP_Resource resource))&Pnacl_M39_PPB_ImageCapture_Private_IsImageCapture, .Close = (int32_t (*)(PP_Resource resource, struct PP_CompletionCallback callback))&Pnacl_M39_PPB_ImageCapture_Private_Close, - .SetConfig = (int32_t (*)(PP_Resource image_capture, PP_Resource config, struct PP_CompletionCallback callback))&Pnacl_M39_PPB_ImageCapture_Private_SetConfig, - .GetConfig = (int32_t (*)(PP_Resource image_capture, PP_Resource* config, struct PP_CompletionCallback callback))&Pnacl_M39_PPB_ImageCapture_Private_GetConfig, - .GetCameraCapabilities = (int32_t (*)(PP_Resource image_capture, PP_Resource* capabilities, struct PP_CompletionCallback callback))&Pnacl_M39_PPB_ImageCapture_Private_GetCameraCapabilities, - .CaptureStillImage = (int32_t (*)(PP_Resource image_capture, PPB_ImageCapture_Private_ShutterCallback shutter_callback, PPB_ImageCapture_Private_PreviewCallback preview_callback, PPB_ImageCapture_Private_JpegCallback jpeg_callback, int64_t* sequence_id))&Pnacl_M39_PPB_ImageCapture_Private_CaptureStillImage + .GetCameraCapabilities = (int32_t (*)(PP_Resource image_capture, PP_Resource* capabilities, struct PP_CompletionCallback callback))&Pnacl_M39_PPB_ImageCapture_Private_GetCameraCapabilities }; /* Not generating wrapper interface for PPB_InputEvent_Private_0_1 */ @@ -6146,6 +6205,12 @@ .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoEncoder_0_1 = { + .iface_macro = PPB_VIDEOENCODER_INTERFACE_0_1, + .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_VideoEncoder_0_1, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_WebSocket_1_0 = { .iface_macro = PPB_WEBSOCKET_INTERFACE_1_0, .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_WebSocket_1_0, @@ -6559,6 +6624,7 @@ &Pnacl_WrapperInfo_PPB_VideoDecoder_0_1, &Pnacl_WrapperInfo_PPB_VideoDecoder_0_2, &Pnacl_WrapperInfo_PPB_VideoDecoder_1_0, + &Pnacl_WrapperInfo_PPB_VideoEncoder_0_1, &Pnacl_WrapperInfo_PPB_WebSocket_1_0, &Pnacl_WrapperInfo_PPB_AudioInput_Dev_0_3, &Pnacl_WrapperInfo_PPB_AudioInput_Dev_0_4,
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index c775386e..97b7a09 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi
@@ -234,6 +234,8 @@ 'proxy/video_decoder_resource.h', 'proxy/video_destination_resource.cc', 'proxy/video_destination_resource.h', + 'proxy/video_encoder_resource.cc', + 'proxy/video_encoder_resource.h', 'proxy/video_frame_resource.cc', 'proxy/video_frame_resource.h', 'proxy/video_source_resource.cc',
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 9fe13752..43d8895 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi
@@ -280,6 +280,8 @@ 'thunk/ppb_video_decoder_thunk.cc', 'thunk/ppb_video_destination_private_api.h', 'thunk/ppb_video_destination_private_thunk.cc', + 'thunk/ppb_video_encoder_api.h', + 'thunk/ppb_video_encoder_thunk.cc', 'thunk/ppb_video_frame_api.h', 'thunk/ppb_video_frame_thunk.cc', 'thunk/ppb_video_source_private_api.h',
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 4407da7..1f2b018 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi
@@ -245,6 +245,8 @@ 'cpp/var_dictionary.h', 'cpp/video_decoder.cc', 'cpp/video_decoder.h', + 'cpp/video_encoder.cc', + 'cpp/video_encoder.h', 'cpp/video_frame.cc', 'cpp/video_frame.h', 'cpp/view.cc',
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 0d2b870..413b7cf 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc
@@ -68,6 +68,7 @@ #include "ppapi/c/ppb_var_array_buffer.h" #include "ppapi/c/ppb_var_dictionary.h" #include "ppapi/c/ppb_video_decoder.h" +#include "ppapi/c/ppb_video_encoder.h" #include "ppapi/c/ppb_video_frame.h" #include "ppapi/c/ppb_view.h" #include "ppapi/c/pp_errors.h"
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index 95500b4..edee224 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -60,6 +60,10 @@ Send(message); } +void PpapiCommandBufferProxy::OrderingBarrier(int32 put_offset) { + Flush(put_offset); +} + void PpapiCommandBufferProxy::WaitForTokenInRange(int32 start, int32 end) { TryUpdateState(); if (!InRange(start, end, last_state_.token) &&
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h index b277baf..469dbca 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.h +++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -38,6 +38,7 @@ virtual State GetLastState() override; virtual int32 GetLastToken() override; virtual void Flush(int32 put_offset) override; + virtual void OrderingBarrier(int32 put_offset) override; virtual void WaitForTokenInRange(int32 start, int32 end) override; virtual void WaitForGetOffsetInRange(int32 start, int32 end) override; virtual void SetGetBuffer(int32 transfer_buffer_id) override;
diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 99e890b1..b00f05c 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc
@@ -50,6 +50,7 @@ #include "ppapi/proxy/video_capture_resource.h" #include "ppapi/proxy/video_decoder_resource.h" #include "ppapi/proxy/video_destination_resource.h" +#include "ppapi/proxy/video_encoder_resource.h" #include "ppapi/proxy/video_source_resource.h" #include "ppapi/proxy/websocket_resource.h" #include "ppapi/shared_impl/api_id.h" @@ -387,6 +388,10 @@ instance))->GetReference(); } +PP_Resource ResourceCreationProxy::CreateVideoEncoder(PP_Instance instance) { + return (new VideoEncoderResource(GetConnection(), instance))->GetReference(); +} + PP_Resource ResourceCreationProxy::CreateVideoSource( PP_Instance instance) { return (new VideoSourceResource(GetConnection(), instance))->GetReference();
diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index a3e633e..89aadbc 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h
@@ -156,6 +156,7 @@ virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instance) override; virtual PP_Resource CreateVideoDecoder(PP_Instance instance) override; virtual PP_Resource CreateVideoDestination(PP_Instance instance) override; + virtual PP_Resource CreateVideoEncoder(PP_Instance instance) override; virtual PP_Resource CreateVideoSource(PP_Instance instance) override; virtual PP_Resource CreateWebSocket(PP_Instance instance) override; virtual PP_Resource CreateX509CertificatePrivate(
diff --git a/ppapi/proxy/video_encoder_resource.cc b/ppapi/proxy/video_encoder_resource.cc new file mode 100644 index 0000000..5d7913d --- /dev/null +++ b/ppapi/proxy/video_encoder_resource.cc
@@ -0,0 +1,79 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/video_encoder_resource.h" + +using ppapi::thunk::PPB_VideoEncoder_API; + +namespace ppapi { +namespace proxy { + +VideoEncoderResource::VideoEncoderResource(Connection connection, + PP_Instance instance) + : PluginResource(connection, instance) { +} + +VideoEncoderResource::~VideoEncoderResource() { +} + +PPB_VideoEncoder_API* VideoEncoderResource::AsPPB_VideoEncoder_API() { + return this; +} + +int32_t VideoEncoderResource::GetSupportedProfiles( + const PP_ArrayOutput& output, + const scoped_refptr<TrackedCallback>& callback) { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::Initialize( + PP_VideoFrame_Format input_format, + const PP_Size* input_visible_size, + PP_VideoProfile output_profile, + uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + const scoped_refptr<TrackedCallback>& callback) { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::GetFramesRequired() { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::GetFrameCodedSize(PP_Size* size) { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::GetVideoFrame( + PP_Resource* video_frame, + const scoped_refptr<TrackedCallback>& callback) { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::Encode( + PP_Resource video_frame, + PP_Bool force_keyframe, + const scoped_refptr<TrackedCallback>& callback) { + return PP_ERROR_FAILED; +} + +int32_t VideoEncoderResource::GetBitstreamBuffer( + PP_BitstreamBuffer* picture, + const scoped_refptr<TrackedCallback>& callback) { + return PP_ERROR_FAILED; +} + +void VideoEncoderResource::RecycleBitstreamBuffer( + const PP_BitstreamBuffer* picture) { +} + +void VideoEncoderResource::RequestEncodingParametersChange(uint32_t bitrate, + uint32_t framerate) { +} + +void VideoEncoderResource::Close() { +} + +} // namespace proxy +} // namespace ppapi
diff --git a/ppapi/proxy/video_encoder_resource.h b/ppapi/proxy/video_encoder_resource.h new file mode 100644 index 0000000..585d5c145 --- /dev/null +++ b/ppapi/proxy/video_encoder_resource.h
@@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_VIDEO_ENCODER_RESOURCE_H_ +#define PPAPI_PROXY_VIDEO_ENCODER_RESOURCE_H_ + +#include "base/memory/ref_counted.h" +#include "ppapi/proxy/connection.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_video_encoder_api.h" + +namespace ppapi { + +class TrackedCallback; + +namespace proxy { + +class PPAPI_PROXY_EXPORT VideoEncoderResource + : public PluginResource, + public thunk::PPB_VideoEncoder_API { + public: + VideoEncoderResource(Connection connection, PP_Instance instance); + ~VideoEncoderResource() override; + + thunk::PPB_VideoEncoder_API* AsPPB_VideoEncoder_API() override; + + private: + // PPB_VideoEncoder_API implementation. + int32_t GetSupportedProfiles( + const PP_ArrayOutput& output, + const scoped_refptr<TrackedCallback>& callback) override; + int32_t Initialize(PP_VideoFrame_Format input_format, + const PP_Size* input_visible_size, + PP_VideoProfile output_profile, + uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + const scoped_refptr<TrackedCallback>& callback) override; + int32_t GetFramesRequired() override; + int32_t GetFrameCodedSize(PP_Size* size) override; + int32_t GetVideoFrame( + PP_Resource* video_frame, + const scoped_refptr<TrackedCallback>& callback) override; + int32_t Encode(PP_Resource video_frame, + PP_Bool force_keyframe, + const scoped_refptr<TrackedCallback>& callback) override; + int32_t GetBitstreamBuffer( + PP_BitstreamBuffer* picture, + const scoped_refptr<TrackedCallback>& callback) override; + void RecycleBitstreamBuffer(const PP_BitstreamBuffer* picture) override; + void RequestEncodingParametersChange(uint32_t bitrate, + uint32_t framerate) override; + void Close() override; + + DISALLOW_COPY_AND_ASSIGN(VideoEncoderResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_VIDEO_ENCODER_RESOURCE_H_
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index fdcf4fc..97a5b4eb 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h
@@ -83,6 +83,7 @@ F(PPB_VideoDecoder_API) \ F(PPB_VideoDecoder_Dev_API) \ F(PPB_VideoDestination_Private_API) \ + F(PPB_VideoEncoder_API) \ F(PPB_VideoFrame_API) \ F(PPB_VideoLayer_API) \ F(PPB_VideoSource_Private_API) \
diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index 07b6b43..0d7b047 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h
@@ -117,7 +117,6 @@ #include "ppapi/c/private/ppb_flash_menu.h" #include "ppapi/c/private/ppb_flash_message_loop.h" #include "ppapi/c/private/ppb_host_resolver_private.h" -#include "ppapi/c/private/ppb_image_capture_config_private.h" #include "ppapi/c/private/ppb_image_capture_private.h" #include "ppapi/c/private/ppb_input_event_private.h" #include "ppapi/c/private/ppb_instance_private.h"
diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h index f0d5006..130ed67 100644 --- a/ppapi/tests/all_cpp_includes.h +++ b/ppapi/tests/all_cpp_includes.h
@@ -57,7 +57,6 @@ #include "ppapi/cpp/private/find_private.h" #include "ppapi/cpp/private/flash_font_file.h" #include "ppapi/cpp/private/flash_fullscreen.h" -#include "ppapi/cpp/private/image_capture_config_private.h" #include "ppapi/cpp/private/image_capture_private.h" #include "ppapi/cpp/private/instance_private.h" #include "ppapi/cpp/private/instance_private.h"
diff --git a/ppapi/tests/mojo/test_mojo.cc b/ppapi/tests/mojo/test_mojo.cc index 2743d06..3d1af46 100644 --- a/ppapi/tests/mojo/test_mojo.cc +++ b/ppapi/tests/mojo/test_mojo.cc
@@ -18,6 +18,8 @@ } std::string TestMojo::TestCreateMessagePipe() { - mojo::MessagePipe pipe; + MojoHandle h0; + MojoHandle h1; + ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(NULL, &h0, &h1)); PASS(); }
diff --git a/ppapi/thunk/interfaces_ppb_public_dev_channel.h b/ppapi/thunk/interfaces_ppb_public_dev_channel.h index a91d112..8899206 100644 --- a/ppapi/thunk/interfaces_ppb_public_dev_channel.h +++ b/ppapi/thunk/interfaces_ppb_public_dev_channel.h
@@ -14,6 +14,7 @@ PROXIED_IFACE(PPB_MESSAGING_INTERFACE_1_1_DEPRECATED, PPB_Messaging_1_1_Deprecated) PROXIED_IFACE(PPB_VIDEODECODER_INTERFACE_0_1, PPB_VideoDecoder_0_1) +PROXIED_IFACE(PPB_VIDEOENCODER_INTERFACE_0_1, PPB_VideoEncoder_0_1) // Note, PPB_TraceEvent is special. We don't want to actually make it stable, // but we want developers to be able to leverage it when running Chrome Dev or
diff --git a/ppapi/thunk/ppb_image_capture_config_private_thunk.cc b/ppapi/thunk/ppb_image_capture_config_private_thunk.cc deleted file mode 100644 index 98f2900c..0000000 --- a/ppapi/thunk/ppb_image_capture_config_private_thunk.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// From private/ppb_image_capture_config_private.idl modified Wed Nov 5 -// 14:29:15 2014. - -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/private/ppb_image_capture_config_private.h" -#include "ppapi/shared_impl/tracked_callback.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppapi_thunk_export.h" -#include "ppapi/thunk/ppb_image_capture_config_api.h" - -namespace ppapi { -namespace thunk { - -namespace { - -PP_Resource Create(PP_Instance instance) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::Create()"; - EnterResourceCreation enter(instance); - if (enter.failed()) - return 0; - return enter.functions()->CreateImageCaptureConfigPrivate(instance); -} - -PP_Bool IsImageCaptureConfig(PP_Resource resource) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::IsImageCaptureConfig()"; - EnterResource<PPB_ImageCaptureConfig_API> enter(resource, false); - return PP_FromBool(enter.succeeded()); -} - -void GetPreviewSize(PP_Resource config, struct PP_Size* preview_size) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::GetPreviewSize()"; - EnterResource<PPB_ImageCaptureConfig_API> enter(config, true); - if (enter.failed()) - return; - enter.object()->GetPreviewSize(preview_size); -} - -void SetPreviewSize(PP_Resource config, const struct PP_Size* preview_size) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::SetPreviewSize()"; - EnterResource<PPB_ImageCaptureConfig_API> enter(config, true); - if (enter.failed()) - return; - enter.object()->SetPreviewSize(preview_size); -} - -void GetJpegSize(PP_Resource config, struct PP_Size* jpeg_size) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::GetJpegSize()"; - EnterResource<PPB_ImageCaptureConfig_API> enter(config, true); - if (enter.failed()) - return; - enter.object()->GetJpegSize(jpeg_size); -} - -void SetJpegSize(PP_Resource config, const struct PP_Size* jpeg_size) { - VLOG(4) << "PPB_ImageCaptureConfig_Private::SetJpegSize()"; - EnterResource<PPB_ImageCaptureConfig_API> enter(config, true); - if (enter.failed()) - return; - enter.object()->SetJpegSize(jpeg_size); -} - -const PPB_ImageCaptureConfig_Private_0_1 - g_ppb_imagecaptureconfig_private_thunk_0_1 = {&Create, - &IsImageCaptureConfig, - &GetPreviewSize, - &SetPreviewSize, - &GetJpegSize, - &SetJpegSize}; - -} // namespace - -PPAPI_THUNK_EXPORT const PPB_ImageCaptureConfig_Private_0_1* -GetPPB_ImageCaptureConfig_Private_0_1_Thunk() { - return &g_ppb_imagecaptureconfig_private_thunk_0_1; -} - -} // namespace thunk -} // namespace ppapi
diff --git a/ppapi/thunk/ppb_image_capture_private_thunk.cc b/ppapi/thunk/ppb_image_capture_private_thunk.cc index ae88783c..47db157 100644 --- a/ppapi/thunk/ppb_image_capture_private_thunk.cc +++ b/ppapi/thunk/ppb_image_capture_private_thunk.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// From private/ppb_image_capture_private.idl modified Wed Nov 5 14:29:15 2014. +// From private/ppb_image_capture_private.idl modified Thu Feb 5 22:47:43 2015. #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" @@ -19,14 +19,13 @@ PP_Resource Create(PP_Instance instance, struct PP_Var camera_source_id, - PPB_ImageCapture_Private_ErrorCallback error_callback, void* user_data) { VLOG(4) << "PPB_ImageCapture_Private::Create()"; EnterResourceCreation enter(instance); if (enter.failed()) return 0; return enter.functions()->CreateImageCapturePrivate( - instance, camera_source_id, error_callback, user_data); + instance, camera_source_id, user_data); } PP_Bool IsImageCapture(PP_Resource resource) { @@ -43,26 +42,6 @@ return enter.SetResult(enter.object()->Close(enter.callback())); } -int32_t SetConfig(PP_Resource image_capture, - PP_Resource config, - struct PP_CompletionCallback callback) { - VLOG(4) << "PPB_ImageCapture_Private::SetConfig()"; - EnterResource<PPB_ImageCapture_API> enter(image_capture, callback, true); - if (enter.failed()) - return enter.retval(); - return enter.SetResult(enter.object()->SetConfig(config, enter.callback())); -} - -int32_t GetConfig(PP_Resource image_capture, - PP_Resource* config, - struct PP_CompletionCallback callback) { - VLOG(4) << "PPB_ImageCapture_Private::GetConfig()"; - EnterResource<PPB_ImageCapture_API> enter(image_capture, callback, true); - if (enter.failed()) - return enter.retval(); - return enter.SetResult(enter.object()->GetConfig(config, enter.callback())); -} - int32_t GetCameraCapabilities(PP_Resource image_capture, PP_Resource* capabilities, struct PP_CompletionCallback callback) { @@ -74,28 +53,8 @@ enter.object()->GetCameraCapabilities(capabilities, enter.callback())); } -int32_t CaptureStillImage( - PP_Resource image_capture, - PPB_ImageCapture_Private_ShutterCallback shutter_callback, - PPB_ImageCapture_Private_PreviewCallback preview_callback, - PPB_ImageCapture_Private_JpegCallback jpeg_callback, - int64_t* sequence_id) { - VLOG(4) << "PPB_ImageCapture_Private::CaptureStillImage()"; - EnterResource<PPB_ImageCapture_API> enter(image_capture, true); - if (enter.failed()) - return enter.retval(); - return enter.object()->CaptureStillImage(shutter_callback, preview_callback, - jpeg_callback, sequence_id); -} - -const PPB_ImageCapture_Private_0_1 g_ppb_imagecapture_private_thunk_0_1 = { - &Create, - &IsImageCapture, - &Close, - &SetConfig, - &GetConfig, - &GetCameraCapabilities, - &CaptureStillImage}; +const PPB_ImageCapture_Private_0_1 g_ppb_imagecapture_private_thunk_0_1 = + {&Create, &IsImageCapture, &Close, &GetCameraCapabilities}; } // namespace
diff --git a/ppapi/thunk/ppb_video_encoder_api.h b/ppapi/thunk/ppb_video_encoder_api.h new file mode 100644 index 0000000..7050d6a --- /dev/null +++ b/ppapi/thunk/ppb_video_encoder_api.h
@@ -0,0 +1,53 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_PPB_VIDEO_ENCODER_API_H_ +#define PPAPI_THUNK_PPB_VIDEO_ENCODER_API_H_ + +#include "ppapi/c/pp_codecs.h" +#include "ppapi/c/ppb_video_encoder.h" +#include "ppapi/thunk/ppapi_thunk_export.h" + +namespace ppapi { + +class TrackedCallback; + +namespace thunk { + +class PPAPI_THUNK_EXPORT PPB_VideoEncoder_API { + public: + virtual ~PPB_VideoEncoder_API() {} + + virtual int32_t GetSupportedProfiles( + const PP_ArrayOutput& output, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual int32_t Initialize( + PP_VideoFrame_Format input_format, + const PP_Size* input_visible_size, + PP_VideoProfile output_profile, + uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual int32_t GetFramesRequired() = 0; + virtual int32_t GetFrameCodedSize(PP_Size* size) = 0; + virtual int32_t GetVideoFrame( + PP_Resource* video_frame, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual int32_t Encode(PP_Resource video_frame, + PP_Bool force_keyframe, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual int32_t GetBitstreamBuffer( + PP_BitstreamBuffer* bitstream_buffer, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual void RecycleBitstreamBuffer( + const PP_BitstreamBuffer* bitstream_buffer) = 0; + virtual void RequestEncodingParametersChange(uint32_t bitrate, + uint32_t framerate) = 0; + virtual void Close() = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_PPB_VIDEO_ENCODER_API_H_
diff --git a/ppapi/thunk/ppb_video_encoder_thunk.cc b/ppapi/thunk/ppb_video_encoder_thunk.cc new file mode 100644 index 0000000..b6981e5 --- /dev/null +++ b/ppapi/thunk/ppb_video_encoder_thunk.cc
@@ -0,0 +1,160 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// From ppb_video_encoder.idl modified Thu Feb 5 10:33:32 2015. + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_video_encoder.h" +#include "ppapi/shared_impl/tracked_callback.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppapi_thunk_export.h" +#include "ppapi/thunk/ppb_video_encoder_api.h" + +namespace ppapi { +namespace thunk { + +namespace { + +PP_Resource Create(PP_Instance instance) { + VLOG(4) << "PPB_VideoEncoder::Create()"; + EnterResourceCreation enter(instance); + if (enter.failed()) + return 0; + return enter.functions()->CreateVideoEncoder(instance); +} + +PP_Bool IsVideoEncoder(PP_Resource resource) { + VLOG(4) << "PPB_VideoEncoder::IsVideoEncoder()"; + EnterResource<PPB_VideoEncoder_API> enter(resource, false); + return PP_FromBool(enter.succeeded()); +} + +int32_t GetSupportedProfiles(PP_Resource video_encoder, + struct PP_ArrayOutput output, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_VideoEncoder::GetSupportedProfiles()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult( + enter.object()->GetSupportedProfiles(output, enter.callback())); +} + +int32_t Initialize(PP_Resource video_encoder, + PP_VideoFrame_Format input_format, + const struct PP_Size* input_visible_size, + PP_VideoProfile output_profile, + uint32_t initial_bitrate, + PP_HardwareAcceleration acceleration, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_VideoEncoder::Initialize()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult(enter.object()->Initialize( + input_format, input_visible_size, output_profile, initial_bitrate, + acceleration, enter.callback())); +} + +int32_t GetFramesRequired(PP_Resource video_encoder) { + VLOG(4) << "PPB_VideoEncoder::GetFramesRequired()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, true); + if (enter.failed()) + return enter.retval(); + return enter.object()->GetFramesRequired(); +} + +int32_t GetFrameCodedSize(PP_Resource video_encoder, + struct PP_Size* coded_size) { + VLOG(4) << "PPB_VideoEncoder::GetFrameCodedSize()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, true); + if (enter.failed()) + return enter.retval(); + return enter.object()->GetFrameCodedSize(coded_size); +} + +int32_t GetVideoFrame(PP_Resource video_encoder, + PP_Resource* video_frame, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_VideoEncoder::GetVideoFrame()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult( + enter.object()->GetVideoFrame(video_frame, enter.callback())); +} + +int32_t Encode(PP_Resource video_encoder, + PP_Resource video_frame, + PP_Bool force_keyframe, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_VideoEncoder::Encode()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult( + enter.object()->Encode(video_frame, force_keyframe, enter.callback())); +} + +int32_t GetBitstreamBuffer(PP_Resource video_encoder, + struct PP_BitstreamBuffer* bitstream_buffer, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_VideoEncoder::GetBitstreamBuffer()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult( + enter.object()->GetBitstreamBuffer(bitstream_buffer, enter.callback())); +} + +void RecycleBitstreamBuffer(PP_Resource video_encoder, + const struct PP_BitstreamBuffer* bitstream_buffer) { + VLOG(4) << "PPB_VideoEncoder::RecycleBitstreamBuffer()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, true); + if (enter.failed()) + return; + enter.object()->RecycleBitstreamBuffer(bitstream_buffer); +} + +void RequestEncodingParametersChange(PP_Resource video_encoder, + uint32_t bitrate, + uint32_t framerate) { + VLOG(4) << "PPB_VideoEncoder::RequestEncodingParametersChange()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, true); + if (enter.failed()) + return; + enter.object()->RequestEncodingParametersChange(bitrate, framerate); +} + +void Close(PP_Resource video_encoder) { + VLOG(4) << "PPB_VideoEncoder::Close()"; + EnterResource<PPB_VideoEncoder_API> enter(video_encoder, true); + if (enter.failed()) + return; + enter.object()->Close(); +} + +const PPB_VideoEncoder_0_1 g_ppb_videoencoder_thunk_0_1 = { + &Create, + &IsVideoEncoder, + &GetSupportedProfiles, + &Initialize, + &GetFramesRequired, + &GetFrameCodedSize, + &GetVideoFrame, + &Encode, + &GetBitstreamBuffer, + &RecycleBitstreamBuffer, + &RequestEncodingParametersChange, + &Close}; + +} // namespace + +PPAPI_THUNK_EXPORT const PPB_VideoEncoder_0_1* GetPPB_VideoEncoder_0_1_Thunk() { + return &g_ppb_videoencoder_thunk_0_1; +} + +} // namespace thunk +} // namespace ppapi
diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 11dcc82d..fa2a781 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h
@@ -171,6 +171,7 @@ virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instace) = 0; virtual PP_Resource CreateVideoDecoder(PP_Instance instance) = 0; virtual PP_Resource CreateVideoDestination(PP_Instance instance) = 0; + virtual PP_Resource CreateVideoEncoder(PP_Instance instance) = 0; virtual PP_Resource CreateVideoSource(PP_Instance instance) = 0; virtual PP_Resource CreateWebSocket(PP_Instance instance) = 0; virtual PP_Resource CreateX509CertificatePrivate(PP_Instance instance) = 0;
diff --git a/printing/backend/print_backend_dummy.cc b/printing/backend/print_backend_dummy.cc index db269a75..917078b 100644 --- a/printing/backend/print_backend_dummy.cc +++ b/printing/backend/print_backend_dummy.cc
@@ -48,7 +48,7 @@ } private: - ~DummyPrintBackend() {} + ~DummyPrintBackend() override {} DISALLOW_COPY_AND_ASSIGN(DummyPrintBackend); };
diff --git a/printing/emf_win.cc b/printing/emf_win.cc index 55b8786..030d520 100644 --- a/printing/emf_win.cc +++ b/printing/emf_win.cc
@@ -11,7 +11,7 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/scoped_hdc.h" #include "base/win/scoped_select_object.h" -#include "skia/ext/vector_platform_device_emf_win.h" +#include "skia/ext/platform_device.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/codec/png_codec.h"
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc index ae402ab..ef8e375 100644 --- a/printing/pdf_metafile_skia.cc +++ b/printing/pdf_metafile_skia.cc
@@ -10,7 +10,6 @@ #include "base/numerics/safe_conversions.h" #include "base/posix/eintr_wrapper.h" #include "skia/ext/refptr.h" -#include "skia/ext/vector_canvas.h" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkDocument.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -104,7 +103,7 @@ return true; } -skia::VectorCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( +skia::PlatformCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( const gfx::Size& page_size, const gfx::Rect& content_area, const float& scale_factor) {
diff --git a/printing/pdf_metafile_skia.h b/printing/pdf_metafile_skia.h index 58e928b..edd12db 100644 --- a/printing/pdf_metafile_skia.h +++ b/printing/pdf_metafile_skia.h
@@ -10,7 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "build/build_config.h" #include "printing/metafile.h" -#include "skia/ext/vector_canvas.h" +#include "skia/ext/platform_canvas.h" #if defined(OS_WIN) #include <windows.h> @@ -74,14 +74,14 @@ scoped_ptr<PdfMetafileSkia> GetMetafileForCurrentPage(); // This method calls StartPage and then returns an appropriate - // VectorCanvas implementation bound to the context created by - // StartPage or NULL on error. The skia::VectorCanvas pointer that + // PlatformCanvas implementation bound to the context created by + // StartPage or NULL on error. The skia::PlatformCanvas pointer that // is returned is owned by this PdfMetafileSkia object and does not // need to be ref()ed or unref()ed. The canvas will remain valid // until FinishPage() or FinishDocument() is called. - skia::VectorCanvas* GetVectorCanvasForNewPage(const gfx::Size& page_size, - const gfx::Rect& content_area, - const float& scale_factor); + skia::PlatformCanvas* GetVectorCanvasForNewPage(const gfx::Size& page_size, + const gfx::Rect& content_area, + const float& scale_factor); private: scoped_ptr<PdfMetafileSkiaData> data_;
diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h index 3823b28..6962c099 100644 --- a/printing/printing_context_android.h +++ b/printing/printing_context_android.h
@@ -19,7 +19,7 @@ class PRINTING_EXPORT PrintingContextAndroid : public PrintingContext { public: explicit PrintingContextAndroid(Delegate* delegate); - virtual ~PrintingContextAndroid(); + ~PrintingContextAndroid() override; // Called when the page is successfully written to a PDF using the file // descriptor specified, or when the printing operation failed. @@ -33,23 +33,22 @@ void ShowSystemDialogDone(JNIEnv* env, jobject obj); // PrintingContext implementation. - virtual void AskUserForSettings( - int max_pages, - bool has_selection, - bool is_scripted, - const PrintSettingsCallback& callback) override; - virtual Result UseDefaultSettings() override; - virtual gfx::Size GetPdfPaperSizeDeviceUnits() override; - virtual Result UpdatePrinterSettings(bool external_preview, - bool show_system_dialog) override; - virtual Result InitWithSettings(const PrintSettings& settings) override; - virtual Result NewDocument(const base::string16& document_name) override; - virtual Result NewPage() override; - virtual Result PageDone() override; - virtual Result DocumentDone() override; - virtual void Cancel() override; - virtual void ReleaseContext() override; - virtual gfx::NativeDrawingContext context() const override; + void AskUserForSettings(int max_pages, + bool has_selection, + bool is_scripted, + const PrintSettingsCallback& callback) override; + Result UseDefaultSettings() override; + gfx::Size GetPdfPaperSizeDeviceUnits() override; + Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) override; + Result InitWithSettings(const PrintSettings& settings) override; + Result NewDocument(const base::string16& document_name) override; + Result NewPage() override; + Result PageDone() override; + Result DocumentDone() override; + void Cancel() override; + void ReleaseContext() override; + gfx::NativeDrawingContext context() const override; // Registers JNI bindings for RegisterContext. static bool RegisterPrintingContext(JNIEnv* env);
diff --git a/remoting/app_remoting_test.gyp b/remoting/app_remoting_test.gyp new file mode 100644 index 0000000..87ef886 --- /dev/null +++ b/remoting/app_remoting_test.gyp
@@ -0,0 +1,51 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'includes': [ + 'remoting_version.gypi', + ], + + 'target_defaults': { + 'type': 'none', + }, # target_defaults + + 'targets': [ + { + 'target_name': 'ar_test_driver_common', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + '../base/base.gyp:test_support_base', + '../google_apis/google_apis.gyp:google_apis', + '../net/net.gyp:net', + '../remoting/remoting.gyp:remoting_base', + '../remoting/remoting.gyp:remoting_client', + '../remoting/remoting.gyp:remoting_protocol', + '../remoting/proto/chromotocol.gyp:chromotocol_proto_lib', + '../testing/gtest.gyp:gtest', + ], + 'defines': [ + 'VERSION=<(version_full)', + ], + }, # end of target 'ar_test_driver_common' + { + # An external version of the test driver tool which includes minimal tests + 'target_name': 'ar_sample_test_driver', + 'type': '<(gtest_target_type)', + 'dependencies': [ + 'ar_test_driver_common', + ], + 'defines': [ + 'VERSION=<(version_full)', + ], + 'sources': [ + 'test/app_remoting_test_driver.cc', + ], + 'include_dirs': [ + '../testing/gtest/include', + ], + }, # end of target 'ar_sample_test_driver' + ], # end of targets +}
diff --git a/remoting/app_remoting_webapp_build.gypi b/remoting/app_remoting_webapp_build.gypi index d5da9eb..9e739f7 100644 --- a/remoting/app_remoting_webapp_build.gypi +++ b/remoting/app_remoting_webapp_build.gypi
@@ -71,6 +71,8 @@ 'remoting_app_name': '>(_app_name)', 'remoting_app_description': '>(_app_description)', + 'ar_webapp_locales_listfile': '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)_locales.txt', + 'conditions': [ ['ar_internal != 1', { 'ar_app_name': 'sample_app', @@ -88,6 +90,23 @@ 'actions': [ { + 'action_name': 'Build ">(ar_app_name)" locales listfile', + 'inputs': [ + '<(remoting_localize_path)', + ], + 'outputs': [ + '<(ar_webapp_locales_listfile)', + ], + 'action': [ + 'python', '<(remoting_localize_path)', + '--locale_output', + '"<(webapp_locale_dir)/@{json_suffix}/messages.json"', + '--locales_listfile', + '<(ar_webapp_locales_listfile)', + '<@(remoting_locales)', + ], + }, + { 'action_name': 'Build ">(ar_app_name)" application stub', 'inputs': [ '<(DEPTH)/remoting/webapp/build-webapp.py', @@ -98,6 +117,7 @@ '<@(ar_generated_html_files)', '<(ar_app_manifest_app)', '<(DEPTH)/remoting/<(ar_app_manifest_common)', + '<(ar_webapp_locales_listfile)', ], 'outputs': [ '<(output_dir)', @@ -113,8 +133,8 @@ 'app_remoting', # Web app type '<@(ar_webapp_files)', '<@(ar_generated_html_files)', - '--locales', - '<@(remoting_webapp_locale_files)', + '--locales_listfile', + '<(ar_webapp_locales_listfile)', '--jinja_paths', '<(DEPTH)/remoting/webapp/app_remoting', '<@(remoting_app_id)',
diff --git a/remoting/client/jni/chromoting_jni_instance.h b/remoting/client/jni/chromoting_jni_instance.h index 204525f..75cbb91 100644 --- a/remoting/client/jni/chromoting_jni_instance.h +++ b/remoting/client/jni/chromoting_jni_instance.h
@@ -94,30 +94,26 @@ void RecordPaintTime(int64 paint_time_ms); // ClientUserInterface implementation. - virtual void OnConnectionState( - protocol::ConnectionToHost::State state, - protocol::ErrorCode error) override; - virtual void OnConnectionReady(bool ready) override; - virtual void OnRouteChanged(const std::string& channel_name, - const protocol::TransportRoute& route) override; - virtual void SetCapabilities(const std::string& capabilities) override; - virtual void SetPairingResponse( - const protocol::PairingResponse& response) override; - virtual void DeliverHostMessage( - const protocol::ExtensionMessage& message) override; - virtual protocol::ClipboardStub* GetClipboardStub() override; - virtual protocol::CursorShapeStub* GetCursorShapeStub() override; + void OnConnectionState(protocol::ConnectionToHost::State state, + protocol::ErrorCode error) override; + void OnConnectionReady(bool ready) override; + void OnRouteChanged(const std::string& channel_name, + const protocol::TransportRoute& route) override; + void SetCapabilities(const std::string& capabilities) override; + void SetPairingResponse(const protocol::PairingResponse& response) override; + void DeliverHostMessage(const protocol::ExtensionMessage& message) override; + protocol::ClipboardStub* GetClipboardStub() override; + protocol::CursorShapeStub* GetCursorShapeStub() override; // CursorShapeStub implementation. - virtual void InjectClipboardEvent( - const protocol::ClipboardEvent& event) override; + void InjectClipboardEvent(const protocol::ClipboardEvent& event) override; // ClipboardStub implementation. - virtual void SetCursorShape(const protocol::CursorShapeInfo& shape) override; + void SetCursorShape(const protocol::CursorShapeInfo& shape) override; private: // This object is ref-counted, so it cleans itself up. - virtual ~ChromotingJniInstance(); + ~ChromotingJniInstance() override; void ConnectToHostOnDisplayThread(); void ConnectToHostOnNetworkThread();
diff --git a/remoting/client/jni/jni_frame_consumer.h b/remoting/client/jni/jni_frame_consumer.h index 3368a98f..e69501cf 100644 --- a/remoting/client/jni/jni_frame_consumer.h +++ b/remoting/client/jni/jni_frame_consumer.h
@@ -34,21 +34,21 @@ explicit JniFrameConsumer(ChromotingJniRuntime* jni_runtime, scoped_refptr<ChromotingJniInstance> jni_instance); - virtual ~JniFrameConsumer(); + ~JniFrameConsumer() override; // This must be called once before the producer's source size is set. void set_frame_producer(FrameProducer* producer); // FrameConsumer implementation. - virtual void ApplyBuffer(const webrtc::DesktopSize& view_size, - const webrtc::DesktopRect& clip_area, - webrtc::DesktopFrame* buffer, - const webrtc::DesktopRegion& region, - const webrtc::DesktopRegion& shape) override; - virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) override; - virtual void SetSourceSize(const webrtc::DesktopSize& source_size, - const webrtc::DesktopVector& dpi) override; - virtual PixelFormat GetPixelFormat() override; + void ApplyBuffer(const webrtc::DesktopSize& view_size, + const webrtc::DesktopRect& clip_area, + webrtc::DesktopFrame* buffer, + const webrtc::DesktopRegion& region, + const webrtc::DesktopRegion& shape) override; + void ReturnBuffer(webrtc::DesktopFrame* buffer) override; + void SetSourceSize(const webrtc::DesktopSize& source_size, + const webrtc::DesktopVector& dpi) override; + PixelFormat GetPixelFormat() override; private: // Allocates a new buffer of |source_size|, informs Java about it, and tells
diff --git a/remoting/host/capture_scheduler.cc b/remoting/host/capture_scheduler.cc index c6b3be0..ccd141d 100644 --- a/remoting/host/capture_scheduler.cc +++ b/remoting/host/capture_scheduler.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/sys_info.h" +#include "base/time/default_tick_clock.h" #include "base/time/time.h" namespace { @@ -24,46 +25,125 @@ // available while 1 means using 100% of all CPUs available. const double kRecordingCpuConsumption = 0.5; +// Maximum number of frames that can be processed simultaneously. +static const int kMaxPendingFrames = 2; + } // namespace namespace remoting { // We assume that the number of available cores is constant. -CaptureScheduler::CaptureScheduler() - : minimum_interval_( +CaptureScheduler::CaptureScheduler(const base::Closure& capture_closure) + : capture_closure_(capture_closure), + tick_clock_(new base::DefaultTickClock()), + capture_timer_(new base::Timer(false, false)), + minimum_interval_( base::TimeDelta::FromMilliseconds(kDefaultMinimumIntervalMs)), num_of_processors_(base::SysInfo::NumberOfProcessors()), capture_time_(kStatisticsWindow), - encode_time_(kStatisticsWindow) { + encode_time_(kStatisticsWindow), + pending_frames_(0), + capture_pending_(false), + is_paused_(false) { DCHECK(num_of_processors_); } CaptureScheduler::~CaptureScheduler() { } -base::TimeDelta CaptureScheduler::NextCaptureDelay() { +void CaptureScheduler::Start() { + DCHECK(CalledOnValidThread()); + + ScheduleNextCapture(); +} + +void CaptureScheduler::Pause(bool pause) { + DCHECK(CalledOnValidThread()); + + if (is_paused_ != pause) { + is_paused_ = pause; + + if (is_paused_) { + capture_timer_->Stop(); + } else { + ScheduleNextCapture(); + } + } +} + +void CaptureScheduler::OnCaptureCompleted() { + DCHECK(CalledOnValidThread()); + + capture_pending_ = false; + capture_time_.Record( + (tick_clock_->NowTicks() - last_capture_started_time_).InMilliseconds()); + + ScheduleNextCapture(); +} + +void CaptureScheduler::OnFrameSent() { + DCHECK(CalledOnValidThread()); + + // Decrement the pending capture count. + pending_frames_--; + DCHECK_GE(pending_frames_, 0); + + ScheduleNextCapture(); +} + +void CaptureScheduler::OnFrameEncoded(base::TimeDelta encode_time) { + DCHECK(CalledOnValidThread()); + + encode_time_.Record(encode_time.InMilliseconds()); + ScheduleNextCapture(); +} + +void CaptureScheduler::SetTickClockForTest( + scoped_ptr<base::TickClock> tick_clock) { + tick_clock_ = tick_clock.Pass(); +} +void CaptureScheduler::SetTimerForTest(scoped_ptr<base::Timer> timer) { + capture_timer_ = timer.Pass(); +} +void CaptureScheduler::SetNumOfProcessorsForTest(int num_of_processors) { + num_of_processors_ = num_of_processors; +} + +void CaptureScheduler::ScheduleNextCapture() { + DCHECK(CalledOnValidThread()); + + if (is_paused_ || pending_frames_ >= kMaxPendingFrames || capture_pending_) + return; + // Delay by an amount chosen such that if capture and encode times // continue to follow the averages, then we'll consume the target // fraction of CPU across all cores. - base::TimeDelta delay = base::TimeDelta::FromMilliseconds( - (capture_time_.Average() + encode_time_.Average()) / - (kRecordingCpuConsumption * num_of_processors_)); + base::TimeDelta delay = + std::max(minimum_interval_, + base::TimeDelta::FromMilliseconds( + (capture_time_.Average() + encode_time_.Average()) / + (kRecordingCpuConsumption * num_of_processors_))); - if (delay < minimum_interval_) - return minimum_interval_; - return delay; + // Account for the time that has passed since the last capture. + delay = std::max(base::TimeDelta(), delay - (tick_clock_->NowTicks() - + last_capture_started_time_)); + + capture_timer_->Start( + FROM_HERE, delay, + base::Bind(&CaptureScheduler::CaptureNextFrame, base::Unretained(this))); } -void CaptureScheduler::RecordCaptureTime(base::TimeDelta capture_time) { - capture_time_.Record(capture_time.InMilliseconds()); -} +void CaptureScheduler::CaptureNextFrame() { + DCHECK(CalledOnValidThread()); + DCHECK(!is_paused_); + DCHECK(!capture_pending_); -void CaptureScheduler::RecordEncodeTime(base::TimeDelta encode_time) { - encode_time_.Record(encode_time.InMilliseconds()); -} + pending_frames_++; + DCHECK_LE(pending_frames_, kMaxPendingFrames); -void CaptureScheduler::SetNumOfProcessorsForTest(int num_of_processors) { - num_of_processors_ = num_of_processors; + capture_pending_ = true; + last_capture_started_time_ = tick_clock_->NowTicks(); + capture_closure_.Run(); } } // namespace remoting
diff --git a/remoting/host/capture_scheduler.h b/remoting/host/capture_scheduler.h index 9dbecdad..b3136e7 100644 --- a/remoting/host/capture_scheduler.h +++ b/remoting/host/capture_scheduler.h
@@ -9,38 +9,84 @@ #ifndef REMOTING_HOST_CAPTURE_SCHEDULER_H_ #define REMOTING_HOST_CAPTURE_SCHEDULER_H_ +#include "base/callback.h" +#include "base/threading/non_thread_safe.h" +#include "base/time/tick_clock.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "remoting/base/running_average.h" namespace remoting { -class CaptureScheduler { +// CaptureScheduler is used by the VideoFramePump to schedule frame capturer, +// taking into account capture delay, encoder delay, network bandwidth, etc. +class CaptureScheduler : public base::NonThreadSafe { public: - CaptureScheduler(); + // |capture_closure| is called every time a new frame needs to be captured. + explicit CaptureScheduler(const base::Closure& capture_closure); ~CaptureScheduler(); - // Returns the time to wait after initiating a capture before triggering - // the next. - base::TimeDelta NextCaptureDelay(); + // Starts the scheduler. + void Start(); - // Records time spent on capturing and encoding. - void RecordCaptureTime(base::TimeDelta capture_time); - void RecordEncodeTime(base::TimeDelta encode_time); + // Pauses or unpauses the stream. + void Pause(bool pause); + + // Notifies the scheduler that a capture has been completed. + void OnCaptureCompleted(); + + // Notifies the scheduler that a frame has been encoded. + void OnFrameEncoded(base::TimeDelta encode_time); + + // Notifies the scheduler that a frame has been sent. + void OnFrameSent(); // Sets minimum interval between frames. void set_minimum_interval(base::TimeDelta minimum_interval) { minimum_interval_ = minimum_interval; } - // Overrides the number of processors for testing. + // Helper functions for tests. + void SetTickClockForTest(scoped_ptr<base::TickClock> tick_clock); + void SetTimerForTest(scoped_ptr<base::Timer> timer); void SetNumOfProcessorsForTest(int num_of_processors); private: + // Schedules |capture_timer_| to call CaptureNextFrame() at appropriate time. + // Doesn't do anything if next frame cannot be captured yet (e.g. because + // there are too many frames being processed). + void ScheduleNextCapture(); + + // Called by |capture_timer_|. Calls |capture_closure_| to start capturing a + // new frame. + void CaptureNextFrame(); + + base::Closure capture_closure_; + + scoped_ptr<base::TickClock> tick_clock_; + + // Timer used to schedule CaptureNextFrame(). + scoped_ptr<base::Timer> capture_timer_; + + // Minimum interval between frames that determines maximum possible framerate. base::TimeDelta minimum_interval_; + int num_of_processors_; + RunningAverage capture_time_; RunningAverage encode_time_; + // Total number of pending frames that are being captured, encoded or sent. + int pending_frames_; + + // Set to true when capture is pending. + bool capture_pending_; + + // Time at which the last capture started. Used to schedule |capture_timer_|. + base::TimeTicks last_capture_started_time_; + + bool is_paused_; + DISALLOW_COPY_AND_ASSIGN(CaptureScheduler); };
diff --git a/remoting/host/capture_scheduler_unittest.cc b/remoting/host/capture_scheduler_unittest.cc index a6ca0e6..b07fc6da 100644 --- a/remoting/host/capture_scheduler_unittest.cc +++ b/remoting/host/capture_scheduler_unittest.cc
@@ -3,6 +3,10 @@ // found in the LICENSE file. #include "remoting/host/capture_scheduler.h" + +#include "base/message_loop/message_loop.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/timer/mock_timer.h" #include "testing/gtest/include/gtest/gtest.h" namespace remoting { @@ -10,7 +14,61 @@ static const int kTestInputs[] = { 100, 50, 30, 20, 10, 30, 60, 80 }; static const int kMinumumFrameIntervalMs = 50; -TEST(CaptureSchedulerTest, SingleSampleSameTimes) { +class CaptureSchedulerTest : public testing::Test { + public: + CaptureSchedulerTest() : capture_called_(false) {} + + void InitScheduler() { + scheduler_.reset(new CaptureScheduler( + base::Bind(&CaptureSchedulerTest::DoCapture, base::Unretained(this)))); + scheduler_->set_minimum_interval( + base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); + tick_clock_ = new base::SimpleTestTickClock(); + scheduler_->SetTickClockForTest(make_scoped_ptr(tick_clock_)); + capture_timer_ = new base::MockTimer(false, false); + scheduler_->SetTimerForTest(make_scoped_ptr(capture_timer_)); + scheduler_->Start(); + } + + void DoCapture() { + capture_called_ = true; + } + + void CheckCaptureCalled() { + EXPECT_TRUE(capture_called_); + capture_called_ = false; + } + + void SimulateSingleFrameCapture( + base::TimeDelta capture_delay, + base::TimeDelta encode_delay, + base::TimeDelta expected_delay_between_frames) { + capture_timer_->Fire(); + CheckCaptureCalled(); + tick_clock_->Advance(capture_delay); + scheduler_->OnCaptureCompleted(); + scheduler_->OnFrameEncoded(encode_delay); + scheduler_->OnFrameSent(); + + EXPECT_TRUE(capture_timer_->IsRunning()); + EXPECT_EQ(std::max(base::TimeDelta(), + expected_delay_between_frames - capture_delay), + capture_timer_->GetCurrentDelay()); + } + + protected: + base::MessageLoop message_loop_; + + scoped_ptr<CaptureScheduler> scheduler_; + + // Owned by |scheduler_|. + base::SimpleTestTickClock* tick_clock_; + base::MockTimer* capture_timer_; + + bool capture_called_; +}; + +TEST_F(CaptureSchedulerTest, SingleSampleSameTimes) { const int kTestResults[][arraysize(kTestInputs)] = { { 400, 200, 120, 80, 50, 120, 240, 320 }, // One core. { 200, 100, 60, 50, 50, 60, 120, 160 }, // Two cores. @@ -20,21 +78,18 @@ for (size_t i = 0; i < arraysize(kTestResults); ++i) { for (size_t j = 0; j < arraysize(kTestInputs); ++j) { - CaptureScheduler scheduler; - scheduler.SetNumOfProcessorsForTest(1 << i); - scheduler.set_minimum_interval( - base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); - scheduler.RecordCaptureTime( - base::TimeDelta::FromMilliseconds(kTestInputs[j])); - scheduler.RecordEncodeTime( - base::TimeDelta::FromMilliseconds(kTestInputs[j])); - EXPECT_EQ(kTestResults[i][j], - scheduler.NextCaptureDelay().InMilliseconds()) << i << " "<< j; + InitScheduler(); + scheduler_->SetNumOfProcessorsForTest(1 << i); + + SimulateSingleFrameCapture( + base::TimeDelta::FromMilliseconds(kTestInputs[j]), + base::TimeDelta::FromMilliseconds(kTestInputs[j]), + base::TimeDelta::FromMilliseconds(kTestResults[i][j])); } } } -TEST(CaptureSchedulerTest, SingleSampleDifferentTimes) { +TEST_F(CaptureSchedulerTest, SingleSampleDifferentTimes) { const int kTestResults[][arraysize(kTestInputs)] = { { 360, 220, 120, 60, 60, 120, 220, 360 }, // One core. { 180, 110, 60, 50, 50, 60, 110, 180 }, // Two cores. @@ -44,22 +99,19 @@ for (size_t i = 0; i < arraysize(kTestResults); ++i) { for (size_t j = 0; j < arraysize(kTestInputs); ++j) { - CaptureScheduler scheduler; - scheduler.SetNumOfProcessorsForTest(1 << i); - scheduler.set_minimum_interval( - base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); - scheduler.RecordCaptureTime( - base::TimeDelta::FromMilliseconds(kTestInputs[j])); - scheduler.RecordEncodeTime( + InitScheduler(); + scheduler_->SetNumOfProcessorsForTest(1 << i); + + SimulateSingleFrameCapture( + base::TimeDelta::FromMilliseconds(kTestInputs[j]), base::TimeDelta::FromMilliseconds( - kTestInputs[arraysize(kTestInputs) - 1 - j])); - EXPECT_EQ(kTestResults[i][j], - scheduler.NextCaptureDelay().InMilliseconds()); + kTestInputs[arraysize(kTestInputs) - 1 - j]), + base::TimeDelta::FromMilliseconds(kTestResults[i][j])); } } } -TEST(CaptureSchedulerTest, RollingAverageDifferentTimes) { +TEST_F(CaptureSchedulerTest, RollingAverageDifferentTimes) { const int kTestResults[][arraysize(kTestInputs)] = { { 360, 290, 233, 133, 80, 80, 133, 233 }, // One core. { 180, 145, 116, 66, 50, 50, 66, 116 }, // Two cores. @@ -68,20 +120,36 @@ }; for (size_t i = 0; i < arraysize(kTestResults); ++i) { - CaptureScheduler scheduler; - scheduler.SetNumOfProcessorsForTest(1 << i); - scheduler.set_minimum_interval( - base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); + InitScheduler(); + scheduler_->SetNumOfProcessorsForTest(1 << i); for (size_t j = 0; j < arraysize(kTestInputs); ++j) { - scheduler.RecordCaptureTime( - base::TimeDelta::FromMilliseconds(kTestInputs[j])); - scheduler.RecordEncodeTime( + SimulateSingleFrameCapture( + base::TimeDelta::FromMilliseconds(kTestInputs[j]), base::TimeDelta::FromMilliseconds( - kTestInputs[arraysize(kTestInputs) - 1 - j])); - EXPECT_EQ(kTestResults[i][j], - scheduler.NextCaptureDelay().InMilliseconds()); + kTestInputs[arraysize(kTestInputs) - 1 - j]), + base::TimeDelta::FromMilliseconds(kTestResults[i][j])); } } } +// Verify that we never have more than 2 pending frames. +TEST_F(CaptureSchedulerTest, MaximumPendingFrames) { + InitScheduler(); + + capture_timer_->Fire(); + CheckCaptureCalled(); + scheduler_->OnCaptureCompleted(); + + capture_timer_->Fire(); + CheckCaptureCalled(); + scheduler_->OnCaptureCompleted(); + + EXPECT_FALSE(capture_timer_->IsRunning()); + + scheduler_->OnFrameEncoded(base::TimeDelta()); + scheduler_->OnFrameSent(); + + EXPECT_TRUE(capture_timer_->IsRunning()); +} + } // namespace remoting
diff --git a/remoting/host/chromeos/aura_desktop_capturer.cc b/remoting/host/chromeos/aura_desktop_capturer.cc index d37ae32..d996a97 100644 --- a/remoting/host/chromeos/aura_desktop_capturer.cc +++ b/remoting/host/chromeos/aura_desktop_capturer.cc
@@ -61,7 +61,7 @@ scoped_ptr<webrtc::DesktopFrame> frame( SkiaBitmapDesktopFrame::Create(bitmap.Pass())); - // |VideoScheduler| will not encode the frame if |updated_region| is empty. + // |VideoFramePump| will not encode the frame if |updated_region| is empty. const webrtc::DesktopRect& rect = webrtc::DesktopRect::MakeWH( frame->size().width(), frame->size().height());
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 878b3a8..a6b1811 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h
@@ -49,7 +49,7 @@ // // 2. We listen for incoming connection using libjingle. We will create // a ConnectionToClient object that wraps around linjingle for transport. -// A VideoScheduler is created with an Encoder and a webrtc::DesktopCapturer. +// A VideoFramePump is created with an Encoder and a webrtc::DesktopCapturer. // A ConnectionToClient is added to the ScreenRecorder for transporting // the screen captures. An InputStub is created and registered with the // ConnectionToClient to receive mouse / keyboard events from the remote
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 1b580dc..1874f242 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc
@@ -22,7 +22,7 @@ #include "remoting/host/input_injector.h" #include "remoting/host/screen_controls.h" #include "remoting/host/screen_resolution.h" -#include "remoting/host/video_scheduler.h" +#include "remoting/host/video_frame_pump.h" #include "remoting/proto/control.pb.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/client_stub.h" @@ -101,7 +101,7 @@ DCHECK(!desktop_environment_); DCHECK(!input_injector_); DCHECK(!screen_controls_); - DCHECK(!video_scheduler_.get()); + DCHECK(!video_frame_pump_.get()); connection_.reset(); } @@ -136,28 +136,28 @@ void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { DCHECK(CalledOnValidThread()); - // Note that |video_scheduler_| may be null, depending upon whether extensions - // choose to wrap or "steal" the video capturer or encoder. + // Note that |video_frame_pump_| may be null, depending upon whether + // extensions choose to wrap or "steal" the video capturer or encoder. if (video_control.has_enable()) { VLOG(1) << "Received VideoControl (enable=" << video_control.enable() << ")"; pause_video_ = !video_control.enable(); - if (video_scheduler_.get()) - video_scheduler_->Pause(pause_video_); + if (video_frame_pump_.get()) + video_frame_pump_->Pause(pause_video_); } if (video_control.has_lossless_encode()) { VLOG(1) << "Received VideoControl (lossless_encode=" << video_control.lossless_encode() << ")"; lossless_video_encode_ = video_control.lossless_encode(); - if (video_scheduler_.get()) - video_scheduler_->SetLosslessEncode(lossless_video_encode_); + if (video_frame_pump_.get()) + video_frame_pump_->SetLosslessEncode(lossless_video_encode_); } if (video_control.has_lossless_color()) { VLOG(1) << "Received VideoControl (lossless_color=" << video_control.lossless_color() << ")"; lossless_video_color_ = video_control.lossless_color(); - if (video_scheduler_.get()) - video_scheduler_->SetLosslessColor(lossless_video_color_); + if (video_frame_pump_.get()) + video_frame_pump_->SetLosslessColor(lossless_video_color_); } } @@ -250,7 +250,7 @@ DCHECK(!desktop_environment_); DCHECK(!input_injector_); DCHECK(!screen_controls_); - DCHECK(!video_scheduler_.get()); + DCHECK(!video_frame_pump_.get()); auth_input_filter_.set_enabled(true); auth_clipboard_filter_.set_enabled(true); @@ -368,9 +368,9 @@ audio_scheduler_->Stop(); audio_scheduler_ = nullptr; } - if (video_scheduler_.get()) { - video_scheduler_->Stop(); - video_scheduler_ = nullptr; + if (video_frame_pump_.get()) { + video_frame_pump_->Stop(); + video_frame_pump_ = nullptr; } client_clipboard_factory_.InvalidateWeakPtrs(); @@ -388,8 +388,8 @@ DCHECK(CalledOnValidThread()); DCHECK_EQ(connection_.get(), connection); - if (video_scheduler_.get()) - video_scheduler_->SetLatestEventTimestamp(timestamp); + if (video_frame_pump_.get()) + video_frame_pump_->SetLatestEventTimestamp(timestamp); } void ClientSession::OnRouteChange( @@ -434,9 +434,9 @@ void ClientSession::ResetVideoPipeline() { DCHECK(CalledOnValidThread()); - if (video_scheduler_.get()) { - video_scheduler_->Stop(); - video_scheduler_ = nullptr; + if (video_frame_pump_.get()) { + video_frame_pump_->Stop(); + video_frame_pump_ = nullptr; } // Create VideoEncoder and DesktopCapturer to match the session's video @@ -448,12 +448,12 @@ CreateVideoEncoder(connection_->session()->config()); extension_manager_->OnCreateVideoEncoder(&video_encoder); - // Don't start the VideoScheduler if either capturer or encoder are missing. + // Don't start the VideoFramePump if either capturer or encoder are missing. if (!video_capturer || !video_encoder) return; - // Create a VideoScheduler to pump frames from the capturer to the client. - video_scheduler_ = new VideoScheduler( + // Create a VideoFramePump to pump frames from the capturer to the client. + video_frame_pump_ = new VideoFramePump( video_capture_task_runner_, video_encode_task_runner_, network_task_runner_, @@ -464,12 +464,14 @@ &mouse_clamping_filter_); // Apply video-control parameters to the new scheduler. - video_scheduler_->Pause(pause_video_); - video_scheduler_->SetLosslessEncode(lossless_video_encode_); - video_scheduler_->SetLosslessColor(lossless_video_color_); + video_frame_pump_->SetLosslessEncode(lossless_video_encode_); + video_frame_pump_->SetLosslessColor(lossless_video_color_); // Start capturing the screen. - video_scheduler_->Start(); + video_frame_pump_->Start(); + + // Pause capturing if necessary. + video_frame_pump_->Pause(pause_video_); } void ClientSession::SetGnubbyAuthHandlerForTesting(
diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index 58c5ec0..05f8b7f 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h
@@ -42,7 +42,7 @@ class InputInjector; class ScreenControls; class VideoEncoder; -class VideoScheduler; +class VideoFramePump; // A ClientSession keeps a reference to a connection to a client, and maintains // per-client state. @@ -219,10 +219,10 @@ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; // Schedulers for audio and video capture. - // |video_scheduler_| may be nullptr if the video channel is not required - + // |video_frame_pump_| may be nullptr if the video channel is not required - // see ResetVideoPipeline(). scoped_refptr<AudioScheduler> audio_scheduler_; - scoped_refptr<VideoScheduler> video_scheduler_; + scoped_refptr<VideoFramePump> video_frame_pump_; // The set of all capabilities supported by the client. scoped_ptr<std::string> client_capabilities_;
diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 0f0898e..3138454 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc
@@ -774,7 +774,7 @@ } // Verifies that an extension can "steal" the video capture, in which case no -// VideoScheduler is instantiated. +// VideoFramePump is instantiated. TEST_F(ClientSessionTest, StealVideoCapturer) { FakeExtension extension("ext1", "cap1"); extensions_.push_back(&extension);
diff --git a/remoting/host/desktop_session_connector.h b/remoting/host/desktop_session_connector.h index f0a2d75..84fc42d4 100644 --- a/remoting/host/desktop_session_connector.h +++ b/remoting/host/desktop_session_connector.h
@@ -41,12 +41,12 @@ const ScreenResolution& resolution) = 0; // Notifies the network process that |terminal_id| is now attached to - // a desktop integration process. |desktop_process| specifies the process - // handle. |desktop_pipe| is the client end of the pipe opened by the desktop - // process. + // a desktop integration process. |desktop_process_handle| specifies the + // process handle. |desktop_pipe| is the client end of the pipe opened by the + // desktop process. virtual void OnDesktopSessionAgentAttached( int terminal_id, - base::ProcessHandle desktop_process, + base::ProcessHandle desktop_process_handle, IPC::PlatformFileForTransit desktop_pipe) = 0; // Notifies the network process that the daemon has disconnected the desktop
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index cb928dd4..b321655 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc
@@ -114,7 +114,6 @@ video_capture_task_runner_(video_capture_task_runner), client_session_control_(client_session_control), desktop_session_connector_(desktop_session_connector), - desktop_process_(base::kNullProcessHandle), pending_capture_frame_requests_(0), is_desktop_session_connected_(false), virtual_terminal_(virtual_terminal) { @@ -218,31 +217,29 @@ } bool DesktopSessionProxy::AttachToDesktop( - base::ProcessHandle desktop_process, + base::Process desktop_process, IPC::PlatformFileForTransit desktop_pipe) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); DCHECK(!desktop_channel_); - DCHECK_EQ(desktop_process_, base::kNullProcessHandle); + DCHECK(!desktop_process_.IsValid()); // Ignore the attach notification if the client session has been disconnected // already. - if (!client_session_control_.get()) { - base::CloseProcessHandle(desktop_process); + if (!client_session_control_.get()) return false; - } - desktop_process_ = desktop_process; + desktop_process_ = desktop_process.Pass(); #if defined(OS_WIN) // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs // to be duplicated from the desktop process. HANDLE temp_handle; - if (!DuplicateHandle(desktop_process_, desktop_pipe, GetCurrentProcess(), - &temp_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { + if (!DuplicateHandle(desktop_process_.Handle(), desktop_pipe, + GetCurrentProcess(), &temp_handle, 0, + FALSE, DUPLICATE_SAME_ACCESS)) { PLOG(ERROR) << "Failed to duplicate the desktop-to-network pipe handle"; - desktop_process_ = base::kNullProcessHandle; - base::CloseProcessHandle(desktop_process); + desktop_process_.Close(); return false; } base::win::ScopedHandle pipe(temp_handle); @@ -280,10 +277,8 @@ desktop_channel_.reset(); - if (desktop_process_ != base::kNullProcessHandle) { - base::CloseProcessHandle(desktop_process_); - desktop_process_ = base::kNullProcessHandle; - } + if (desktop_process_.IsValid()) + desktop_process_.Close(); shared_buffers_.clear(); @@ -432,11 +427,6 @@ if (desktop_session_connector_.get() && is_desktop_session_connected_) desktop_session_connector_->DisconnectTerminal(this); - - if (desktop_process_ != base::kNullProcessHandle) { - base::CloseProcessHandle(desktop_process_); - desktop_process_ = base::kNullProcessHandle; - } } scoped_refptr<DesktopSessionProxy::IpcSharedBufferCore> @@ -476,7 +466,7 @@ DCHECK(caller_task_runner_->BelongsToCurrentThread()); scoped_refptr<IpcSharedBufferCore> shared_buffer = - new IpcSharedBufferCore(id, handle, desktop_process_, size); + new IpcSharedBufferCore(id, handle, desktop_process_.Handle(), size); if (shared_buffer->memory() != nullptr && !shared_buffers_.insert(std::make_pair(id, shared_buffer)).second) {
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index e54e3ec9..b85847e08 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h
@@ -92,7 +92,7 @@ void OnChannelError() override; // Connects to the desktop session agent. - bool AttachToDesktop(base::ProcessHandle desktop_process, + bool AttachToDesktop(base::Process desktop_process, IPC::PlatformFileForTransit desktop_pipe); // Closes the connection to the desktop session agent and cleans up @@ -209,7 +209,7 @@ scoped_ptr<IPC::ChannelProxy> desktop_channel_; // Handle of the desktop process. - base::ProcessHandle desktop_process_; + base::Process desktop_process_; int pending_capture_frame_requests_;
diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index f1b1f75..d7b2cb6 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc
@@ -181,22 +181,22 @@ void IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached( int terminal_id, - base::ProcessHandle desktop_process, + base::ProcessHandle desktop_process_handle, IPC::PlatformFileForTransit desktop_pipe) { if (!caller_task_runner_->BelongsToCurrentThread()) { caller_task_runner_->PostTask(FROM_HERE, base::Bind( &IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached, - base::Unretained(this), terminal_id, desktop_process, desktop_pipe)); + base::Unretained(this), terminal_id, desktop_process_handle, + desktop_pipe)); return; } + base::Process desktop_process(desktop_process_handle); ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); if (i != active_connections_.end()) { i->second->DetachFromDesktop(); - i->second->AttachToDesktop(desktop_process, desktop_pipe); + i->second->AttachToDesktop(desktop_process.Pass(), desktop_pipe); } else { - base::CloseProcessHandle(desktop_process); - #if defined(OS_POSIX) DCHECK(desktop_pipe.auto_close); base::File pipe_closer(IPC::PlatformFileForTransitToFile(desktop_pipe));
diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index bc829ee..b1dd8611 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h
@@ -96,7 +96,7 @@ const ScreenResolution& resolution) override; void OnDesktopSessionAgentAttached( int terminal_id, - base::ProcessHandle desktop_process, + base::ProcessHandle desktop_process_handle, IPC::PlatformFileForTransit desktop_pipe) override; void OnTerminalDisconnected(int terminal_id) override;
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index 9174f67e..515f626 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -421,9 +421,16 @@ void IpcDesktopEnvironmentTest::OnDesktopAttached( IPC::PlatformFileForTransit desktop_pipe) { + base::ProcessHandle process_handle = base::GetCurrentProcessHandle(); +#if defined(OS_WIN) + ASSERT_NE(FALSE, ::DuplicateHandle(GetCurrentProcess(), process_handle, + GetCurrentProcess(), &process_handle, + 0, FALSE, DUPLICATE_SAME_ACCESS)); +#endif + // Instruct DesktopSessionProxy to connect to the network-to-desktop pipe. desktop_environment_factory_->OnDesktopSessionAgentAttached( - terminal_id_, base::GetCurrentProcessHandle(), desktop_pipe); + terminal_id_, process_handle, desktop_pipe); } // Runs until the desktop is attached and exits immediately after that.
diff --git a/remoting/host/ipc_util_win.cc b/remoting/host/ipc_util_win.cc index dbc5c54..22ac15a0 100644 --- a/remoting/host/ipc_util_win.cc +++ b/remoting/host/ipc_util_win.cc
@@ -39,8 +39,10 @@ // between CreateNamedPipe() and CreateFile() calls before it will be passed // to the network process. It gives full access to the account that // the calling code is running under and denies access by anyone else. - std::string security_descriptor = base::StringPrintf( - "O:%1$sG:%1$sD:(A;;GA;;;%1$s)", base::WideToUTF8(user_sid).c_str()); + std::string user_sid_utf8 = base::WideToUTF8(user_sid); + std::string security_descriptor = + base::StringPrintf("O:%sG:%sD:(A;;GA;;;%s)", user_sid_utf8.c_str(), + user_sid_utf8.c_str(), user_sid_utf8.c_str()); // Generate a unique name for the channel. std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID();
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 291aba6..b66f8376 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc
@@ -629,8 +629,9 @@ scoped_ptr<PairingRegistry::Delegate> delegate = CreatePairingRegistryDelegate(); - pairing_registry_ = new PairingRegistry(context_->file_task_runner(), - delegate.Pass()); + if (delegate) + pairing_registry_ = new PairingRegistry(context_->file_task_runner(), + delegate.Pass()); } #endif // defined(OS_WIN) @@ -1514,9 +1515,6 @@ // Ensures runtime specific CPU features are initialized. media::InitializeCPUSpecificMediaFeatures(); - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier( - net::NetworkChangeNotifier::Create()); - // Create the main message loop and start helper threads. base::MessageLoopForUI message_loop; scoped_ptr<ChromotingHostContext> context = @@ -1525,6 +1523,10 @@ if (!context) return kInitializationFailed; + // NetworkChangeNotifier must be initialized after MessageLoop. + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier( + net::NetworkChangeNotifier::Create()); + // BasicURLRequestContext holds references to threads, so it needs to be // dereferences on UI threads. Store the reference to the URLRequestGetter to // make sure it's not destroyed on other threads.
diff --git a/remoting/host/setup/daemon_controller_delegate_win.cc b/remoting/host/setup/daemon_controller_delegate_win.cc index e174328..c771b15 100644 --- a/remoting/host/setup/daemon_controller_delegate_win.cc +++ b/remoting/host/setup/daemon_controller_delegate_win.cc
@@ -5,60 +5,211 @@ #include "remoting/host/setup/daemon_controller_delegate_win.h" #include "base/basictypes.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/logging.h" -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" #include "base/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "base/timer/timer.h" #include "base/values.h" #include "base/win/scoped_bstr.h" -#include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "remoting/base/scoped_sc_handle_win.h" #include "remoting/host/branding.h" -// chromoting_lib.h contains MIDL-generated declarations. -#include "remoting/host/chromoting_lib.h" +#include "remoting/host/host_config.h" #include "remoting/host/usage_stats_consent.h" - -using base::win::ScopedBstr; -using base::win::ScopedComPtr; +#include "remoting/host/win/security_descriptor.h" namespace remoting { namespace { -// ProgID of the daemon controller. -const wchar_t kDaemonController[] = - L"ChromotingElevatedController.ElevatedController"; +// The maximum size of the configuration file. "1MB ought to be enough" for any +// reasonable configuration we will ever need. 1MB is low enough to make +// the probability of out of memory situation fairly low. OOM is still possible +// and we will crash if it occurs. +const size_t kMaxConfigFileSize = 1024 * 1024; -// The COM elevation moniker for the Elevated Controller. -const wchar_t kDaemonControllerElevationMoniker[] = - L"Elevation:Administrator!new:" - L"ChromotingElevatedController.ElevatedController"; +// The host configuration file name. +const base::FilePath::CharType kConfigFileName[] = + FILE_PATH_LITERAL("host.json"); -// The maximum duration of keeping a reference to a privileged instance of -// the Daemon Controller. This effectively reduces number of UAC prompts a user -// sees. -const int kPrivilegedTimeoutSec = 5 * 60; +// The unprivileged configuration file name. +const base::FilePath::CharType kUnprivilegedConfigFileName[] = + FILE_PATH_LITERAL("host_unprivileged.json"); -// The maximum duration of keeping a reference to an unprivileged instance of -// the Daemon Controller. This interval should not be too long. If upgrade -// happens while there is a live reference to a Daemon Controller instance -// the old binary still can be used. So dropping the references often makes sure -// that the old binary will go away sooner. -const int kUnprivilegedTimeoutSec = 60; +// The extension for the temporary file. +const base::FilePath::CharType kTempFileExtension[] = + FILE_PATH_LITERAL("json~"); -void ConfigToString(const base::DictionaryValue& config, ScopedBstr* out) { - std::string config_str; - base::JSONWriter::Write(&config, &config_str); - ScopedBstr config_scoped_bstr(base::UTF8ToUTF16(config_str).c_str()); - out->Swap(config_scoped_bstr); +// The host configuration file security descriptor that enables full access to +// Local System and built-in administrators only. +const char kConfigFileSecurityDescriptor[] = + "O:BAG:BAD:(A;;GA;;;SY)(A;;GA;;;BA)"; + +const char kUnprivilegedConfigFileSecurityDescriptor[] = + "O:BAG:BAD:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;AU)"; + +// Configuration keys. + +// The configuration keys that cannot be specified in UpdateConfig(). +const char* const kReadonlyKeys[] = { + kHostIdConfigPath, kHostOwnerConfigPath, kHostOwnerEmailConfigPath, + kXmppLoginConfigPath }; + +// The configuration keys whose values may be read by GetConfig(). +const char* const kUnprivilegedConfigKeys[] = { + kHostIdConfigPath, kXmppLoginConfigPath }; + +// Reads and parses the configuration file up to |kMaxConfigFileSize| in +// size. +bool ReadConfig(const base::FilePath& filename, + scoped_ptr<base::DictionaryValue>* config_out) { + std::string file_content; + if (!base::ReadFileToString(filename, &file_content, kMaxConfigFileSize)) { + PLOG(ERROR) << "Failed to read '" << filename.value() << "'."; + return false; + } + + // Parse the JSON configuration, expecting it to contain a dictionary. + scoped_ptr<base::Value> value( + base::JSONReader::Read(file_content, base::JSON_ALLOW_TRAILING_COMMAS)); + + base::DictionaryValue* dictionary; + if (!value || !value->GetAsDictionary(&dictionary)) { + LOG(ERROR) << "Failed to parse '" << filename.value() << "'."; + return false; + } + + value.release(); + config_out->reset(dictionary); + return true; +} + +base::FilePath GetTempLocationFor(const base::FilePath& filename) { + return filename.ReplaceExtension(kTempFileExtension); +} + +// Writes a config file to a temporary location. +bool WriteConfigFileToTemp(const base::FilePath& filename, + const char* security_descriptor, + const std::string& content) { + // Create the security descriptor for the configuration file. + ScopedSd sd = ConvertSddlToSd(security_descriptor); + if (!sd) { + PLOG(ERROR) + << "Failed to create a security descriptor for the configuration file"; + return false; + } + + SECURITY_ATTRIBUTES security_attributes = {0}; + security_attributes.nLength = sizeof(security_attributes); + security_attributes.lpSecurityDescriptor = sd.get(); + security_attributes.bInheritHandle = FALSE; + + // Create a temporary file and write configuration to it. + base::FilePath tempname = GetTempLocationFor(filename); + base::win::ScopedHandle file( + CreateFileW(tempname.value().c_str(), + GENERIC_WRITE, + 0, + &security_attributes, + CREATE_ALWAYS, + FILE_FLAG_SEQUENTIAL_SCAN, + nullptr)); + + if (!file.IsValid()) { + PLOG(ERROR) << "Failed to create '" << filename.value() << "'"; + return false; + } + + DWORD written; + if (!::WriteFile(file.Get(), content.c_str(), content.length(), + &written, nullptr)) { + PLOG(ERROR) << "Failed to write to '" << filename.value() << "'"; + return false; + } + + return true; +} + +// Moves a config file from its temporary location to its permanent location. +bool MoveConfigFileFromTemp(const base::FilePath& filename) { + // Now that the configuration is stored successfully replace the actual + // configuration file. + base::FilePath tempname = GetTempLocationFor(filename); + if (!MoveFileExW(tempname.value().c_str(), + filename.value().c_str(), + MOVEFILE_REPLACE_EXISTING)) { + PLOG(ERROR) << "Failed to rename '" << tempname.value() << "' to '" + << filename.value() << "'"; + return false; + } + + return true; +} + +// Writes the configuration file up to |kMaxConfigFileSize| in size. +bool WriteConfig(const std::string& content) { + if (content.length() > kMaxConfigFileSize) { + return false; + } + + // Extract the configuration data that the user will verify. + scoped_ptr<base::Value> config_value(base::JSONReader::Read(content)); + if (!config_value.get()) { + return false; + } + base::DictionaryValue* config_dict = nullptr; + if (!config_value->GetAsDictionary(&config_dict)) { + return false; + } + std::string email; + if (!config_dict->GetString(kHostOwnerEmailConfigPath, &email) && + !config_dict->GetString(kHostOwnerConfigPath, &email) && + !config_dict->GetString(kXmppLoginConfigPath, &email)) { + return false; + } + std::string host_id, host_secret_hash; + if (!config_dict->GetString(kHostIdConfigPath, &host_id) || + !config_dict->GetString(kHostSecretHashConfigPath, &host_secret_hash)) { + return false; + } + + // Extract the unprivileged fields from the configuration. + base::DictionaryValue unprivileged_config_dict; + for (int i = 0; i < arraysize(kUnprivilegedConfigKeys); ++i) { + const char* key = kUnprivilegedConfigKeys[i]; + base::string16 value; + if (config_dict->GetString(key, &value)) { + unprivileged_config_dict.SetString(key, value); + } + } + std::string unprivileged_config_str; + base::JSONWriter::Write(&unprivileged_config_dict, &unprivileged_config_str); + + // Write the full configuration file to a temporary location. + base::FilePath full_config_file_path = + remoting::GetConfigDir().Append(kConfigFileName); + if (!WriteConfigFileToTemp(full_config_file_path, + kConfigFileSecurityDescriptor, + content)) { + return false; + } + + // Write the unprivileged configuration file to a temporary location. + base::FilePath unprivileged_config_file_path = + remoting::GetConfigDir().Append(kUnprivilegedConfigFileName); + if (!WriteConfigFileToTemp(unprivileged_config_file_path, + kUnprivilegedConfigFileSecurityDescriptor, + unprivileged_config_str)) { + return false; + } + + // Move the full and unprivileged configuration files to their permanent + // locations. + return MoveConfigFileFromTemp(full_config_file_path) && + MoveConfigFileFromTemp(unprivileged_config_file_path); } DaemonController::State ConvertToDaemonState(DWORD service_state) { @@ -87,76 +238,123 @@ } } -DWORD OpenService(ScopedScHandle* service_out) { +ScopedScHandle OpenService(DWORD access) { // Open the service and query its current state. ScopedScHandle scmanager( ::OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); if (!scmanager.IsValid()) { - DWORD error = GetLastError(); PLOG(ERROR) << "Failed to connect to the service control manager"; - return error; + return ScopedScHandle(); } ScopedScHandle service(::OpenServiceW(scmanager.Get(), kWindowsServiceName, - SERVICE_QUERY_STATUS)); + access)); if (!service.IsValid()) { - DWORD error = GetLastError(); - if (error != ERROR_SERVICE_DOES_NOT_EXIST) { - PLOG(ERROR) << "Failed to open to the '" << kWindowsServiceName - << "' service"; - } - return error; + PLOG(ERROR) << "Failed to open to the '" << kWindowsServiceName + << "' service"; } - service_out->Set(service.Take()); - return ERROR_SUCCESS; -} - -DaemonController::AsyncResult HResultToAsyncResult( - HRESULT hr) { - if (SUCCEEDED(hr)) { - return DaemonController::RESULT_OK; - } else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) { - return DaemonController::RESULT_CANCELLED; - } else { - // TODO(sergeyu): Report other errors to the webapp once it knows - // how to handle them. - return DaemonController::RESULT_FAILED; - } + return service.Pass(); } void InvokeCompletionCallback( - const DaemonController::CompletionCallback& done, HRESULT hr) { - done.Run(HResultToAsyncResult(hr)); + const DaemonController::CompletionCallback& done, bool success) { + DaemonController::AsyncResult async_result = + success ? DaemonController::RESULT_OK : DaemonController::RESULT_FAILED; + done.Run(async_result); } -HWND GetTopLevelWindow(HWND window) { - if (window == nullptr) { - return nullptr; +bool SetConfig(const std::string& config) { + // Determine the config directory path and create it if necessary. + base::FilePath config_dir = remoting::GetConfigDir(); + if (!base::CreateDirectory(config_dir)) { + PLOG(ERROR) << "Failed to create the config directory."; + return false; } - for (;;) { - LONG style = GetWindowLong(window, GWL_STYLE); - if ((style & WS_OVERLAPPEDWINDOW) == WS_OVERLAPPEDWINDOW || - (style & WS_POPUP) == WS_POPUP) { - return window; - } + return WriteConfig(config); +} - HWND parent = GetAncestor(window, GA_PARENT); - if (parent == nullptr) { - return window; - } +bool StartDaemon() { + DWORD access = SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | + SERVICE_START | SERVICE_STOP; + ScopedScHandle service = OpenService(access); + if (!service.IsValid()) + return false; - window = parent; + // Change the service start type to 'auto'. + if (!::ChangeServiceConfigW(service.Get(), + SERVICE_NO_CHANGE, + SERVICE_AUTO_START, + SERVICE_NO_CHANGE, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr)) { + PLOG(ERROR) << "Failed to change the '" << kWindowsServiceName + << "'service start type to 'auto'"; + return false; } + + // Start the service. + if (!StartService(service.Get(), 0, nullptr)) { + DWORD error = GetLastError(); + if (error != ERROR_SERVICE_ALREADY_RUNNING) { + LOG(ERROR) << "Failed to start the '" << kWindowsServiceName + << "'service: " << error; + + return false; + } + } + + return true; +} + +bool StopDaemon() { + DWORD access = SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | + SERVICE_START | SERVICE_STOP; + ScopedScHandle service = OpenService(access); + if (!service.IsValid()) + return false; + + // Change the service start type to 'manual'. + if (!::ChangeServiceConfigW(service.Get(), + SERVICE_NO_CHANGE, + SERVICE_DEMAND_START, + SERVICE_NO_CHANGE, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr)) { + PLOG(ERROR) << "Failed to change the '" << kWindowsServiceName + << "'service start type to 'manual'"; + return false; + } + + // Stop the service. + SERVICE_STATUS status; + if (!ControlService(service.Get(), SERVICE_CONTROL_STOP, &status)) { + DWORD error = GetLastError(); + if (error != ERROR_SERVICE_NOT_ACTIVE) { + LOG(ERROR) << "Failed to stop the '" << kWindowsServiceName + << "'service: " << error; + return false; + } + } + + return true; } } // namespace -DaemonControllerDelegateWin::DaemonControllerDelegateWin() - : control_is_elevated_(false), - window_handle_(nullptr) { +DaemonControllerDelegateWin::DaemonControllerDelegateWin() { } DaemonControllerDelegateWin::~DaemonControllerDelegateWin() { @@ -166,111 +364,78 @@ if (base::win::GetVersion() < base::win::VERSION_XP) { return DaemonController::STATE_NOT_IMPLEMENTED; } + // TODO(alexeypa): Make the thread alertable, so we can switch to APC // notifications rather than polling. - ScopedScHandle service; - DWORD error = OpenService(&service); + ScopedScHandle service = OpenService(SERVICE_QUERY_STATUS); + if (!service.IsValid()) + return DaemonController::STATE_UNKNOWN; - switch (error) { - case ERROR_SUCCESS: { - SERVICE_STATUS status; - if (::QueryServiceStatus(service.Get(), &status)) { - return ConvertToDaemonState(status.dwCurrentState); - } else { - PLOG(ERROR) << "Failed to query the state of the '" - << kWindowsServiceName << "' service"; - return DaemonController::STATE_UNKNOWN; - } - break; - } - case ERROR_SERVICE_DOES_NOT_EXIST: - return DaemonController::STATE_NOT_INSTALLED; - default: - return DaemonController::STATE_UNKNOWN; + SERVICE_STATUS status; + if (!::QueryServiceStatus(service.Get(), &status)) { + PLOG(ERROR) << "Failed to query the state of the '" + << kWindowsServiceName << "' service"; + return DaemonController::STATE_UNKNOWN; } + + return ConvertToDaemonState(status.dwCurrentState); } scoped_ptr<base::DictionaryValue> DaemonControllerDelegateWin::GetConfig() { - // Configure and start the Daemon Controller if it is installed already. - HRESULT hr = ActivateController(); - if (FAILED(hr)) + base::FilePath config_dir = remoting::GetConfigDir(); + + // Read the unprivileged part of host configuration. + scoped_ptr<base::DictionaryValue> config; + if (!ReadConfig(config_dir.Append(kUnprivilegedConfigFileName), &config)) return nullptr; - // Get the host configuration. - ScopedBstr host_config; - hr = control_->GetConfig(host_config.Receive()); - if (FAILED(hr)) - return nullptr; - - // Parse the string into a dictionary. - base::string16 file_content( - static_cast<BSTR>(host_config), host_config.Length()); - scoped_ptr<base::Value> config( - base::JSONReader::Read(base::UTF16ToUTF8(file_content), - base::JSON_ALLOW_TRAILING_COMMAS)); - - if (!config || !config->IsType(base::Value::TYPE_DICTIONARY)) - return nullptr; - - return make_scoped_ptr(static_cast<base::DictionaryValue*>(config.release())); + return config; } void DaemonControllerDelegateWin::UpdateConfig( scoped_ptr<base::DictionaryValue> config, const DaemonController::CompletionCallback& done) { - HRESULT hr = ActivateElevatedController(); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); + // Check for bad keys. + for (int i = 0; i < arraysize(kReadonlyKeys); ++i) { + if (config->HasKey(kReadonlyKeys[i])) { + LOG(ERROR) << "Cannot update config: '" << kReadonlyKeys[i] + << "' is read only."; + InvokeCompletionCallback(done, false); + return; + } + } + // Get the old config. + base::FilePath config_dir = remoting::GetConfigDir(); + scoped_ptr<base::DictionaryValue> config_old; + if (!ReadConfig(config_dir.Append(kConfigFileName), &config_old)) { + InvokeCompletionCallback(done, false); return; } - // Update the configuration. - ScopedBstr config_str(nullptr); - ConfigToString(*config, &config_str); - if (config_str == nullptr) { - InvokeCompletionCallback(done, E_OUTOFMEMORY); - return; - } + // Merge items from the given config into the old config. + config_old->MergeDictionary(config.release()); - // Make sure that the PIN confirmation dialog is focused properly. - hr = control_->SetOwnerWindow( - reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); - return; - } + // Write the updated config. + std::string config_updated_str; + base::JSONWriter::Write(config_old.get(), &config_updated_str); + bool result = WriteConfig(config_updated_str); - hr = control_->UpdateConfig(config_str); - InvokeCompletionCallback(done, hr); + InvokeCompletionCallback(done, result); } void DaemonControllerDelegateWin::Stop( const DaemonController::CompletionCallback& done) { - HRESULT hr = ActivateElevatedController(); - if (SUCCEEDED(hr)) - hr = control_->StopDaemon(); + bool result = StopDaemon(); - InvokeCompletionCallback(done, hr); + InvokeCompletionCallback(done, result); } void DaemonControllerDelegateWin::SetWindow(void* window_handle) { - window_handle_ = reinterpret_cast<HWND>(window_handle); } std::string DaemonControllerDelegateWin::GetVersion() { - // Configure and start the Daemon Controller if it is installed already. - HRESULT hr = ActivateController(); - if (FAILED(hr)) - return std::string(); - - // Get the version string. - ScopedBstr version; - hr = control_->GetVersion(version.Receive()); - if (FAILED(hr)) - return std::string(); - - return base::UTF16ToUTF8( - base::string16(static_cast<BSTR>(version), version.Length())); + // TODO (weitaosu): Remove this as GetVersion is not used anymore. + return std::string(); } DaemonController::UsageStatsConsent @@ -280,154 +445,48 @@ consent.allowed = false; consent.set_by_policy = false; - // Activate the Daemon Controller and see if it supports |IDaemonControl2|. - HRESULT hr = ActivateController(); - if (FAILED(hr)) { - // The host is not installed yet. Assume that the user didn't consent to - // collecting crash dumps. - return consent; - } - - if (control2_.get() == nullptr) { - // The host is installed and does not support crash dump reporting. - return consent; - } - // Get the recorded user's consent. - BOOL allowed; - BOOL set_by_policy; - hr = control2_->GetUsageStatsConsent(&allowed, &set_by_policy); - if (FAILED(hr)) { - // If the user's consent is not recorded yet, assume that the user didn't - // consent to collecting crash dumps. - return consent; + bool allowed; + bool set_by_policy; + // If the user's consent is not recorded yet, assume that the user didn't + // consent to collecting crash dumps. + if (remoting::GetUsageStatsConsent(&allowed, &set_by_policy)) { + consent.allowed = allowed; + consent.set_by_policy = set_by_policy; } - consent.allowed = !!allowed; - consent.set_by_policy = !!set_by_policy; return consent; } -HRESULT DaemonControllerDelegateWin::ActivateController() { - if (!control_.get()) { - CLSID class_id; - HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); - if (FAILED(hr)) { - return hr; - } - - hr = CoCreateInstance(class_id, nullptr, CLSCTX_LOCAL_SERVER, - IID_IDaemonControl, control_.ReceiveVoid()); - if (FAILED(hr)) { - return hr; - } - - // Ignore the error. IID_IDaemonControl2 is optional. - control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); - - // Release |control_| upon expiration of the timeout. - release_timer_.reset(new base::OneShotTimer<DaemonControllerDelegateWin>()); - release_timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kUnprivilegedTimeoutSec), - this, - &DaemonControllerDelegateWin::ReleaseController); - } - - return S_OK; -} - -HRESULT DaemonControllerDelegateWin::ActivateElevatedController() { - // The COM elevation is supported on Vista and above. - if (base::win::GetVersion() < base::win::VERSION_VISTA) - return ActivateController(); - - // Release an unprivileged instance of the daemon controller if any. - if (!control_is_elevated_) - ReleaseController(); - - if (!control_.get()) { - BIND_OPTS3 bind_options; - memset(&bind_options, 0, sizeof(bind_options)); - bind_options.cbStruct = sizeof(bind_options); - bind_options.hwnd = GetTopLevelWindow(window_handle_); - bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; - - HRESULT hr = ::CoGetObject( - kDaemonControllerElevationMoniker, - &bind_options, - IID_IDaemonControl, - control_.ReceiveVoid()); - if (FAILED(hr)) { - return hr; - } - - // Ignore the error. IID_IDaemonControl2 is optional. - control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); - - // Note that we hold a reference to an elevated instance now. - control_is_elevated_ = true; - - // Release |control_| upon expiration of the timeout. - release_timer_.reset(new base::OneShotTimer<DaemonControllerDelegateWin>()); - release_timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kPrivilegedTimeoutSec), - this, - &DaemonControllerDelegateWin::ReleaseController); - } - - return S_OK; -} - -void DaemonControllerDelegateWin::ReleaseController() { - control_.Release(); - control2_.Release(); - release_timer_.reset(); - control_is_elevated_ = false; -} - void DaemonControllerDelegateWin::SetConfigAndStart( scoped_ptr<base::DictionaryValue> config, bool consent, const DaemonController::CompletionCallback& done) { - HRESULT hr = ActivateElevatedController(); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); - return; - } - // Record the user's consent. - if (control2_.get()) { - hr = control2_->SetUsageStatsConsent(consent); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); - return; - } + if (!remoting::SetUsageStatsConsent(consent)) { + InvokeCompletionCallback(done, false); + return; } // Set the configuration. - ScopedBstr config_str(nullptr); - ConfigToString(*config, &config_str); - if (config_str == nullptr) { - InvokeCompletionCallback(done, E_OUTOFMEMORY); + std::string config_str; + base::JSONWriter::Write(config.release(), &config_str); + + // Determine the config directory path and create it if necessary. + base::FilePath config_dir = remoting::GetConfigDir(); + if (!base::CreateDirectory(config_dir)) { + PLOG(ERROR) << "Failed to create the config directory."; + InvokeCompletionCallback(done, false); return; } - hr = control_->SetOwnerWindow( - reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); - return; - } - - hr = control_->SetConfig(config_str); - if (FAILED(hr)) { - InvokeCompletionCallback(done, hr); + if (!WriteConfig(config_str)) { + InvokeCompletionCallback(done, false); return; } // Start daemon. - hr = control_->StartDaemon(); - InvokeCompletionCallback(done, hr); + InvokeCompletionCallback(done, StartDaemon()); } scoped_refptr<DaemonController> DaemonController::Create() {
diff --git a/remoting/host/setup/daemon_controller_delegate_win.h b/remoting/host/setup/daemon_controller_delegate_win.h index 29ad739..b05a1e2 100644 --- a/remoting/host/setup/daemon_controller_delegate_win.h +++ b/remoting/host/setup/daemon_controller_delegate_win.h
@@ -5,11 +5,6 @@ #ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_WIN_H_ #define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_WIN_H_ -#include "base/memory/scoped_ptr.h" -#include "base/timer/timer.h" -#include "base/win/scoped_comptr.h" -// chromoting_lib.h contains MIDL-generated declarations. -#include "remoting/host/chromoting_lib.h" #include "remoting/host/setup/daemon_controller.h" namespace remoting { @@ -36,33 +31,6 @@ virtual std::string GetVersion() override; virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() override; - private: - // Activates an unprivileged instance of the daemon controller and caches it. - HRESULT ActivateController(); - - // Activates an instance of the daemon controller and caches it. If COM - // Elevation is supported (Vista+) the activated instance is elevated, - // otherwise it is activated under credentials of the caller. - HRESULT ActivateElevatedController(); - - // Releases the cached instance of the controller. - void ReleaseController(); - - // |control_| and |control2_| hold references to an instance of the daemon - // controller to prevent a UAC prompt on every operation. - base::win::ScopedComPtr<IDaemonControl> control_; - base::win::ScopedComPtr<IDaemonControl2> control2_; - - // True if |control_| holds a reference to an elevated instance of the daemon - // controller. - bool control_is_elevated_; - - // This timer is used to release |control_| after a timeout. - scoped_ptr<base::OneShotTimer<DaemonControllerDelegateWin> > release_timer_; - - // Handle of the plugin window. - HWND window_handle_; - DISALLOW_COPY_AND_ASSIGN(DaemonControllerDelegateWin); };
diff --git a/remoting/host/setup/me2me_native_messaging_host.cc b/remoting/host/setup/me2me_native_messaging_host.cc index e3480b1..7472c243 100644 --- a/remoting/host/setup/me2me_native_messaging_host.cc +++ b/remoting/host/setup/me2me_native_messaging_host.cc
@@ -584,8 +584,10 @@ // Create a security descriptor that gives full access to the caller and // denies access by anyone else. - std::string security_descriptor = base::StringPrintf( - "O:%1$sG:%1$sD:(A;;GA;;;%1$s)", base::UTF16ToASCII(user_sid).c_str()); + std::string user_sid_ascii = base::UTF16ToASCII(user_sid); + std::string security_descriptor = + base::StringPrintf("O:%sG:%sD:(A;;GA;;;%s)", user_sid_ascii.c_str(), + user_sid_ascii.c_str(), user_sid_ascii.c_str()); ScopedSd sd = ConvertSddlToSd(security_descriptor); if (!sd) {
diff --git a/remoting/host/video_frame_pump.cc b/remoting/host/video_frame_pump.cc new file mode 100644 index 0000000..4c82ece2 --- /dev/null +++ b/remoting/host/video_frame_pump.cc
@@ -0,0 +1,310 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/video_frame_pump.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/task_runner_util.h" +#include "base/time/time.h" +#include "remoting/host/capture_scheduler.h" +#include "remoting/proto/control.pb.h" +#include "remoting/proto/internal.pb.h" +#include "remoting/proto/video.pb.h" +#include "remoting/protocol/cursor_shape_stub.h" +#include "remoting/protocol/video_stub.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" +#include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h" + +namespace remoting { + +namespace { + +// Helper used to encode frames on the encode thread. +// +// TODO(sergeyu): This functions doesn't do much beside calling +// VideoEncoder::Encode(). It's only needed to handle empty frames properly and +// that logic can be moved to VideoEncoder implementations. +scoped_ptr<VideoPacket> EncodeFrame(VideoEncoder* encoder, + scoped_ptr<webrtc::DesktopFrame> frame) { + // If there is nothing to encode then send an empty packet. + if (!frame || frame->updated_region().is_empty()) + return make_scoped_ptr(new VideoPacket()); + + return encoder->Encode(*frame); +} + +} // namespace + +// Interval between empty keep-alive frames. These frames are sent only when the +// stream is paused or inactive for some other reason (e.g. when blocked on +// capturer). To prevent PseudoTCP from resetting congestion window this value +// must be smaller than the minimum RTO used in PseudoTCP, which is 250ms. +static const int kKeepAlivePacketIntervalMs = 200; + +static bool g_enable_timestamps = false; + +// static +void VideoFramePump::EnableTimestampsForTests() { + g_enable_timestamps = true; +} + +VideoFramePump::VideoFramePump( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, + scoped_ptr<webrtc::DesktopCapturer> capturer, + scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor, + scoped_ptr<VideoEncoder> encoder, + protocol::CursorShapeStub* cursor_stub, + protocol::VideoStub* video_stub) + : capture_task_runner_(capture_task_runner), + encode_task_runner_(encode_task_runner), + network_task_runner_(network_task_runner), + capturer_(capturer.Pass()), + mouse_cursor_monitor_(mouse_cursor_monitor.Pass()), + encoder_(encoder.Pass()), + cursor_stub_(cursor_stub), + video_stub_(video_stub), + latest_event_timestamp_(0) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + DCHECK(capturer_); + DCHECK(mouse_cursor_monitor_); + DCHECK(encoder_); + DCHECK(cursor_stub_); + DCHECK(video_stub_); +} + +// Public methods -------------------------------------------------------------- + +void VideoFramePump::Start() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + keep_alive_timer_.reset(new base::DelayTimer<VideoFramePump>( + FROM_HERE, base::TimeDelta::FromMilliseconds(kKeepAlivePacketIntervalMs), + this, &VideoFramePump::SendKeepAlivePacket)); + + capture_scheduler_.reset(new CaptureScheduler( + base::Bind(&VideoFramePump::CaptureNextFrame, this))); + capture_scheduler_->Start(); + + capture_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoFramePump::StartOnCaptureThread, this)); +} + +void VideoFramePump::Stop() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + // Clear stubs to prevent further updates reaching the client. + cursor_stub_ = nullptr; + video_stub_ = nullptr; + + capture_scheduler_.reset(); + keep_alive_timer_.reset(); + + capture_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoFramePump::StopOnCaptureThread, this)); +} + +void VideoFramePump::Pause(bool pause) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + capture_scheduler_->Pause(pause); +} + +void VideoFramePump::SetLatestEventTimestamp(int64 latest_event_timestamp) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + latest_event_timestamp_ = latest_event_timestamp; +} + +void VideoFramePump::SetLosslessEncode(bool want_lossless) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + encode_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoEncoder::SetLosslessEncode, + base::Unretained(encoder_.get()), want_lossless)); +} + +void VideoFramePump::SetLosslessColor(bool want_lossless) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + encode_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoEncoder::SetLosslessColor, + base::Unretained(encoder_.get()), want_lossless)); +} + +// Private methods ----------------------------------------------------------- + +VideoFramePump::~VideoFramePump() { + // Destroy the capturer and encoder on their respective threads. + capture_task_runner_->DeleteSoon(FROM_HERE, capturer_.release()); + capture_task_runner_->DeleteSoon(FROM_HERE, mouse_cursor_monitor_.release()); + encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release()); +} + +// Capturer thread ------------------------------------------------------------- + +webrtc::SharedMemory* VideoFramePump::CreateSharedMemory(size_t size) { + return nullptr; +} + +void VideoFramePump::OnCaptureCompleted(webrtc::DesktopFrame* frame) { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + + network_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoFramePump::EncodeAndSendFrame, this, + base::Passed(make_scoped_ptr(frame)))); +} + +void VideoFramePump::OnMouseCursor(webrtc::MouseCursor* cursor) { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + + scoped_ptr<webrtc::MouseCursor> owned_cursor(cursor); + + scoped_ptr<protocol::CursorShapeInfo> cursor_proto( + new protocol::CursorShapeInfo()); + cursor_proto->set_width(cursor->image()->size().width()); + cursor_proto->set_height(cursor->image()->size().height()); + cursor_proto->set_hotspot_x(cursor->hotspot().x()); + cursor_proto->set_hotspot_y(cursor->hotspot().y()); + + cursor_proto->set_data(std::string()); + uint8_t* current_row = cursor->image()->data(); + for (int y = 0; y < cursor->image()->size().height(); ++y) { + cursor_proto->mutable_data()->append( + current_row, + current_row + cursor->image()->size().width() * + webrtc::DesktopFrame::kBytesPerPixel); + current_row += cursor->image()->stride(); + } + + network_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoFramePump::SendCursorShape, this, + base::Passed(&cursor_proto))); +} + +void VideoFramePump::OnMouseCursorPosition( + webrtc::MouseCursorMonitor::CursorState state, + const webrtc::DesktopVector& position) { + // We're not subscribing to mouse position changes. + NOTREACHED(); +} + +void VideoFramePump::StartOnCaptureThread() { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + + mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY); + capturer_->Start(this); +} + +void VideoFramePump::StopOnCaptureThread() { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + + // This doesn't deleted already captured frames, so encoder can keep using the + // frames that were captured previously. + capturer_.reset(); + + mouse_cursor_monitor_.reset(); +} + +void VideoFramePump::CaptureNextFrameOnCaptureThread() { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + + // Capture mouse shape first and then screen content. + mouse_cursor_monitor_->Capture(); + capturer_->Capture(webrtc::DesktopRegion()); +} + +// Network thread -------------------------------------------------------------- + +void VideoFramePump::CaptureNextFrame() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + capture_task_runner_->PostTask( + FROM_HERE, + base::Bind(&VideoFramePump::CaptureNextFrameOnCaptureThread, this)); +} + +void VideoFramePump::EncodeAndSendFrame( + scoped_ptr<webrtc::DesktopFrame> frame) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + if (!video_stub_) + return; + + capture_scheduler_->OnCaptureCompleted(); + + // Even when |frame| is nullptr we still need to post it to the encode thread + // to make sure frames are freed in the same order they are received and + // that we don't start capturing frame n+2 before frame n is freed. + base::PostTaskAndReplyWithResult( + encode_task_runner_.get(), FROM_HERE, + base::Bind(&EncodeFrame, encoder_.get(), base::Passed(&frame)), + base::Bind(&VideoFramePump::SendEncodedFrame, this, + latest_event_timestamp_, base::TimeTicks::Now())); +} + +void VideoFramePump::SendEncodedFrame(int64 latest_event_timestamp, + base::TimeTicks timestamp, + scoped_ptr<VideoPacket> packet) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + if (!video_stub_) + return; + + if (g_enable_timestamps) + packet->set_timestamp(timestamp.ToInternalValue()); + + packet->set_latest_event_timestamp(latest_event_timestamp); + + capture_scheduler_->OnFrameEncoded( + base::TimeDelta::FromMilliseconds(packet->encode_time_ms())); + + video_stub_->ProcessVideoPacket( + packet.Pass(), base::Bind(&VideoFramePump::OnVideoPacketSent, this)); +} + +void VideoFramePump::OnVideoPacketSent() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + if (!video_stub_) + return; + + capture_scheduler_->OnFrameSent(); + keep_alive_timer_->Reset(); +} + +void VideoFramePump::SendKeepAlivePacket() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + video_stub_->ProcessVideoPacket( + make_scoped_ptr(new VideoPacket()), + base::Bind(&VideoFramePump::OnKeepAlivePacketSent, this)); +} + +void VideoFramePump::OnKeepAlivePacketSent() { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + if (keep_alive_timer_) + keep_alive_timer_->Reset(); +} + +void VideoFramePump::SendCursorShape( + scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + if (!cursor_stub_) + return; + + cursor_stub_->SetCursorShape(*cursor_shape); +} + +} // namespace remoting
diff --git a/remoting/host/video_scheduler.h b/remoting/host/video_frame_pump.h similarity index 74% rename from remoting/host/video_scheduler.h rename to remoting/host/video_frame_pump.h index 3bcf277..90fea78 100644 --- a/remoting/host/video_scheduler.h +++ b/remoting/host/video_frame_pump.h
@@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef REMOTING_HOST_VIDEO_SCHEDULER_H_ -#define REMOTING_HOST_VIDEO_SCHEDULER_H_ +#ifndef REMOTING_HOST_VIDEO_FRAME_PUMP_H_ +#define REMOTING_HOST_VIDEO_FRAME_PUMP_H_ #include <vector> @@ -13,7 +13,6 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "remoting/codec/video_encoder.h" -#include "remoting/host/capture_scheduler.h" #include "remoting/proto/video.pb.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" @@ -28,7 +27,7 @@ namespace remoting { -class CursorShapeInfo; +class CaptureScheduler; namespace protocol { class CursorShapeInfo; @@ -68,23 +67,24 @@ // | Time // v // -// VideoScheduler would ideally schedule captures so as to saturate the slowest +// VideoFramePump would ideally schedule captures so as to saturate the slowest // of the capture, encode and network processes. However, it also needs to // rate-limit captures to avoid overloading the host system, either by consuming // too much CPU, or hogging the host's graphics subsystem. - -class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, +// +// TODO(sergeyu): Rename this class to VideoFramePump. +class VideoFramePump : public base::RefCountedThreadSafe<VideoFramePump>, public webrtc::DesktopCapturer::Callback, public webrtc::MouseCursorMonitor::Callback { public: // Enables timestamps for generated frames. Used for testing. static void EnableTimestampsForTests(); - // Creates a VideoScheduler running capture, encode and network tasks on the + // Creates a VideoFramePump running capture, encode and network tasks on the // supplied TaskRunners. Video and cursor shape updates will be pumped to // |video_stub| and |client_stub|, which must remain valid until Stop() is // called. |capturer| is used to capture frames. - VideoScheduler( + VideoFramePump( scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, @@ -94,15 +94,6 @@ protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub); - // webrtc::DesktopCapturer::Callback implementation. - webrtc::SharedMemory* CreateSharedMemory(size_t size) override; - void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; - - // webrtc::MouseCursorMonitor::Callback implementation. - void OnMouseCursor(webrtc::MouseCursor* mouse_cursor) override; - void OnMouseCursorPosition(webrtc::MouseCursorMonitor::CursorState state, - const webrtc::DesktopVector& position) override; - // Starts scheduling frame captures. void Start(); @@ -124,30 +115,44 @@ void SetLosslessColor(bool want_lossless); private: - friend class base::RefCountedThreadSafe<VideoScheduler>; - ~VideoScheduler() override; + friend class base::RefCountedThreadSafe<VideoFramePump>; + ~VideoFramePump() override; // Capturer thread ---------------------------------------------------------- + // TODO(sergeyu): Move all methods that run on the capture thread to a + // separate class and make VideoFramePump not ref-counted. + + // webrtc::DesktopCapturer::Callback implementation. + webrtc::SharedMemory* CreateSharedMemory(size_t size) override; + void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; + + // webrtc::MouseCursorMonitor::Callback implementation. + void OnMouseCursor(webrtc::MouseCursor* mouse_cursor) override; + void OnMouseCursorPosition(webrtc::MouseCursorMonitor::CursorState state, + const webrtc::DesktopVector& position) override; + // Starts the capturer on the capture thread. void StartOnCaptureThread(); // Stops scheduling frame captures on the capture thread. void StopOnCaptureThread(); - // Schedules the next call to CaptureNextFrame. - void ScheduleNextCapture(); - - // Starts the next frame capture, unless there are already too many pending. - void CaptureNextFrame(); - - // Called when a frame capture has been encoded & sent to the client. - void FrameCaptureCompleted(); + // Captures next frame on the capture thread. + void CaptureNextFrameOnCaptureThread(); // Network thread ----------------------------------------------------------- - // Send |packet| to the client, unless we are in the process of stopping. - void SendVideoPacket(scoped_ptr<VideoPacket> packet); + // Captures a new frame. Called by CaptureScheduler. + void CaptureNextFrame(); + + // Encodes and sends |frame|. + void EncodeAndSendFrame(scoped_ptr<webrtc::DesktopFrame> frame); + + // Sends encoded frame + void SendEncodedFrame(int64 latest_event_timestamp, + base::TimeTicks timestamp, + scoped_ptr<VideoPacket> packet); // Callback passed to |video_stub_| for the last packet in each frame, to // rate-limit frame captures to network throughput. @@ -162,16 +167,6 @@ // Send updated cursor shape to client. void SendCursorShape(scoped_ptr<protocol::CursorShapeInfo> cursor_shape); - // Encoder thread ----------------------------------------------------------- - - // Encode a frame, passing generated VideoPackets to SendVideoPacket(). - void EncodeFrame(scoped_ptr<webrtc::DesktopFrame> frame, - int64 latest_event_timestamp, - base::TimeTicks timestamp); - - void EncodedDataAvailableCallback(int64 latest_event_timestamp, - scoped_ptr<VideoPacket> packet); - // Task runners used by this class. scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner_; @@ -191,36 +186,18 @@ protocol::CursorShapeStub* cursor_stub_; protocol::VideoStub* video_stub_; - // Timer used to schedule CaptureNextFrame(). - scoped_ptr<base::OneShotTimer<VideoScheduler> > capture_timer_; - // Timer used to ensure that we send empty keep-alive frames to the client // even when the video stream is paused or encoder is busy. - scoped_ptr<base::DelayTimer<VideoScheduler> > keep_alive_timer_; - - // The number of frames being processed, i.e. frames that we are currently - // capturing, encoding or sending. The value is capped at 2 to minimize - // latency. - int pending_frames_; - - // Set when the capturer is capturing a frame. - bool capture_pending_; - - // True if the previous scheduled capture was skipped. - bool did_skip_frame_; - - // True if capture of video frames is paused. - bool is_paused_; + scoped_ptr<base::DelayTimer<VideoFramePump> > keep_alive_timer_; // Number updated by the caller to trace performance. int64 latest_event_timestamp_; - // An object to schedule capturing. - CaptureScheduler scheduler_; + scoped_ptr<CaptureScheduler> capture_scheduler_; - DISALLOW_COPY_AND_ASSIGN(VideoScheduler); + DISALLOW_COPY_AND_ASSIGN(VideoFramePump); }; } // namespace remoting -#endif // REMOTING_HOST_VIDEO_SCHEDULER_H_ +#endif // REMOTING_HOST_VIDEO_FRAME_PUMP_H_
diff --git a/remoting/host/video_scheduler_unittest.cc b/remoting/host/video_frame_pump_unittest.cc similarity index 85% rename from remoting/host/video_scheduler_unittest.cc rename to remoting/host/video_frame_pump_unittest.cc index 5adfafa0..ea61973 100644 --- a/remoting/host/video_scheduler_unittest.cc +++ b/remoting/host/video_frame_pump_unittest.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "remoting/host/video_scheduler.h" +#include "remoting/host/video_frame_pump.h" #include "base/bind.h" #include "base/message_loop/message_loop.h" @@ -123,18 +123,18 @@ DISALLOW_COPY_AND_ASSIGN(ThreadCheckMouseCursorMonitor); }; -class VideoSchedulerTest : public testing::Test { +class VideoFramePumpTest : public testing::Test { public: - VideoSchedulerTest(); + VideoFramePumpTest(); void SetUp() override; void TearDown() override; - void StartVideoScheduler( + void StartVideoFramePump( scoped_ptr<webrtc::DesktopCapturer> capturer, scoped_ptr<VideoEncoder> encoder, scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor); - void StopVideoScheduler(); + void StopVideoFramePump(); // webrtc::DesktopCapturer mocks. void OnCapturerStart(webrtc::DesktopCapturer::Callback* callback); @@ -153,7 +153,7 @@ scoped_refptr<AutoThreadTaskRunner> capture_task_runner_; scoped_refptr<AutoThreadTaskRunner> encode_task_runner_; scoped_refptr<AutoThreadTaskRunner> main_task_runner_; - scoped_refptr<VideoScheduler> scheduler_; + scoped_refptr<VideoFramePump> scheduler_; MockClientStub client_stub_; MockVideoStub video_stub_; @@ -165,22 +165,22 @@ webrtc::MouseCursorMonitor::Callback* mouse_monitor_callback_; private: - DISALLOW_COPY_AND_ASSIGN(VideoSchedulerTest); + DISALLOW_COPY_AND_ASSIGN(VideoFramePumpTest); }; -VideoSchedulerTest::VideoSchedulerTest() +VideoFramePumpTest::VideoFramePumpTest() : capturer_callback_(nullptr), mouse_monitor_callback_(nullptr) { } -void VideoSchedulerTest::SetUp() { +void VideoFramePumpTest::SetUp() { main_task_runner_ = new AutoThreadTaskRunner( message_loop_.message_loop_proxy(), run_loop_.QuitClosure()); capture_task_runner_ = main_task_runner_; encode_task_runner_ = main_task_runner_; } -void VideoSchedulerTest::TearDown() { +void VideoFramePumpTest::TearDown() { // Release the task runners, so that the test can quit. capture_task_runner_ = nullptr; encode_task_runner_ = nullptr; @@ -190,11 +190,11 @@ run_loop_.Run(); } -void VideoSchedulerTest::StartVideoScheduler( +void VideoFramePumpTest::StartVideoFramePump( scoped_ptr<webrtc::DesktopCapturer> capturer, scoped_ptr<VideoEncoder> encoder, scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor) { - scheduler_ = new VideoScheduler( + scheduler_ = new VideoFramePump( capture_task_runner_, encode_task_runner_, main_task_runner_, @@ -206,12 +206,12 @@ scheduler_->Start(); } -void VideoSchedulerTest::StopVideoScheduler() { +void VideoFramePumpTest::StopVideoFramePump() { scheduler_->Stop(); scheduler_ = nullptr; } -void VideoSchedulerTest::OnCapturerStart( +void VideoFramePumpTest::OnCapturerStart( webrtc::DesktopCapturer::Callback* callback) { EXPECT_FALSE(capturer_callback_); EXPECT_TRUE(callback); @@ -219,7 +219,7 @@ capturer_callback_ = callback; } -void VideoSchedulerTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { +void VideoFramePumpTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { scoped_ptr<webrtc::DesktopFrame> frame( new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight))); frame->mutable_updated_region()->SetRect( @@ -227,7 +227,7 @@ capturer_callback_->OnCaptureCompleted(frame.release()); } -void VideoSchedulerTest::OnCaptureMouse() { +void VideoFramePumpTest::OnCaptureMouse() { EXPECT_TRUE(mouse_monitor_callback_); scoped_ptr<webrtc::MouseCursor> mouse_cursor( @@ -239,7 +239,7 @@ mouse_monitor_callback_->OnMouseCursor(mouse_cursor.release()); } -void VideoSchedulerTest::OnMouseCursorMonitorInit( +void VideoFramePumpTest::OnMouseCursorMonitorInit( webrtc::MouseCursorMonitor::Callback* callback, webrtc::MouseCursorMonitor::Mode mode) { EXPECT_FALSE(mouse_monitor_callback_); @@ -248,7 +248,7 @@ mouse_monitor_callback_ = callback; } -void VideoSchedulerTest::SetCursorShape( +void VideoFramePumpTest::SetCursorShape( const protocol::CursorShapeInfo& cursor_shape) { EXPECT_TRUE(cursor_shape.has_width()); EXPECT_EQ(kCursorWidth, cursor_shape.width()); @@ -265,9 +265,9 @@ // This test mocks capturer, encoder and network layer to simulate one capture // cycle. When the first encoded packet is submitted to the network -// VideoScheduler is instructed to come to a complete stop. We expect the stop +// VideoFramePump is instructed to come to a complete stop. We expect the stop // sequence to be executed successfully. -TEST_F(VideoSchedulerTest, StartAndStop) { +TEST_F(VideoFramePumpTest, StartAndStop) { scoped_ptr<webrtc::MockScreenCapturer> capturer( new webrtc::MockScreenCapturer()); scoped_ptr<MockMouseCursorMonitor> cursor_monitor( @@ -278,20 +278,20 @@ EXPECT_CALL(*cursor_monitor, Init(_, _)) .WillOnce( - Invoke(this, &VideoSchedulerTest::OnMouseCursorMonitorInit)); + Invoke(this, &VideoFramePumpTest::OnMouseCursorMonitorInit)); EXPECT_CALL(*cursor_monitor, Capture()) - .WillRepeatedly(Invoke(this, &VideoSchedulerTest::OnCaptureMouse)); + .WillRepeatedly(Invoke(this, &VideoFramePumpTest::OnCaptureMouse)); } Expectation capturer_start = EXPECT_CALL(*capturer, Start(_)) - .WillOnce(Invoke(this, &VideoSchedulerTest::OnCapturerStart)); + .WillOnce(Invoke(this, &VideoFramePumpTest::OnCapturerStart)); // First the capturer is called. Expectation capturer_capture = EXPECT_CALL(*capturer, Capture(_)) .After(capturer_start) - .WillRepeatedly(Invoke(this, &VideoSchedulerTest::OnCaptureFrame)); + .WillRepeatedly(Invoke(this, &VideoFramePumpTest::OnCaptureFrame)); scoped_ptr<MockVideoEncoder> encoder(new MockVideoEncoder()); @@ -303,22 +303,22 @@ EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillRepeatedly(FinishSend()); - // When the first ProcessVideoPacket is received we stop the VideoScheduler. + // When the first ProcessVideoPacket is received we stop the VideoFramePump. EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( FinishSend(), - InvokeWithoutArgs(this, &VideoSchedulerTest::StopVideoScheduler))) + InvokeWithoutArgs(this, &VideoFramePumpTest::StopVideoFramePump))) .RetiresOnSaturation(); EXPECT_CALL(client_stub_, SetCursorShape(_)) - .WillOnce(Invoke(this, &VideoSchedulerTest::SetCursorShape)); + .WillOnce(Invoke(this, &VideoFramePumpTest::SetCursorShape)); // Start video frame capture. scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor( new FakeMouseCursorMonitor()); - StartVideoScheduler(capturer.Pass(), encoder.Pass(), cursor_monitor.Pass()); + StartVideoFramePump(capturer.Pass(), encoder.Pass(), cursor_monitor.Pass()); - // Run until there are no more pending tasks from the VideoScheduler. + // Run until there are no more pending tasks from the VideoFramePump. // Otherwise, a lingering frame capture might attempt to trigger a capturer // expectation action and crash. base::RunLoop().RunUntilIdle(); @@ -326,7 +326,7 @@ // Verify that the capturer, encoder and mouse monitor are torn down on the // correct threads. -TEST_F(VideoSchedulerTest, DeleteOnThreads) { +TEST_F(VideoFramePumpTest, DeleteOnThreads) { capture_task_runner_ = AutoThread::Create("capture", main_task_runner_); encode_task_runner_ = AutoThread::Create("encode", main_task_runner_); @@ -339,9 +339,9 @@ // Start and stop the scheduler, so it will tear down the screen capturer, // video encoder and mouse monitor. - StartVideoScheduler(capturer.Pass(), encoder.Pass(), + StartVideoFramePump(capturer.Pass(), encoder.Pass(), mouse_cursor_monitor.Pass()); - StopVideoScheduler(); + StopVideoFramePump(); } } // namespace remoting
diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc deleted file mode 100644 index e2a3f94..0000000 --- a/remoting/host/video_scheduler.cc +++ /dev/null
@@ -1,407 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/video_scheduler.h" - -#include <algorithm> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/stl_util.h" -#include "base/sys_info.h" -#include "base/time/time.h" -#include "remoting/proto/control.pb.h" -#include "remoting/proto/internal.pb.h" -#include "remoting/proto/video.pb.h" -#include "remoting/protocol/cursor_shape_stub.h" -#include "remoting/protocol/message_decoder.h" -#include "remoting/protocol/video_stub.h" -#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" -#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" -#include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h" - -namespace remoting { - -// Maximum number of frames that can be processed simultaneously. -// TODO(hclam): Move this value to CaptureScheduler. -static const int kMaxPendingFrames = 2; - -// Interval between empty keep-alive frames. These frames are sent only when the -// stream is paused or inactive for some other reason (e.g. when blocked on -// capturer). To prevent PseudoTCP from resetting congestion window this value -// must be smaller than the minimum RTO used in PseudoTCP, which is 250ms. -static const int kKeepAlivePacketIntervalMs = 200; - -static bool g_enable_timestamps = false; - -// static -void VideoScheduler::EnableTimestampsForTests() { - g_enable_timestamps = true; -} - -VideoScheduler::VideoScheduler( - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_ptr<webrtc::DesktopCapturer> capturer, - scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor, - scoped_ptr<VideoEncoder> encoder, - protocol::CursorShapeStub* cursor_stub, - protocol::VideoStub* video_stub) - : capture_task_runner_(capture_task_runner), - encode_task_runner_(encode_task_runner), - network_task_runner_(network_task_runner), - capturer_(capturer.Pass()), - mouse_cursor_monitor_(mouse_cursor_monitor.Pass()), - encoder_(encoder.Pass()), - cursor_stub_(cursor_stub), - video_stub_(video_stub), - pending_frames_(0), - capture_pending_(false), - did_skip_frame_(false), - is_paused_(false), - latest_event_timestamp_(0) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - DCHECK(capturer_); - DCHECK(mouse_cursor_monitor_); - DCHECK(encoder_); - DCHECK(cursor_stub_); - DCHECK(video_stub_); -} - -// Public methods -------------------------------------------------------------- - -webrtc::SharedMemory* VideoScheduler::CreateSharedMemory(size_t size) { - return nullptr; -} - -void VideoScheduler::OnCaptureCompleted(webrtc::DesktopFrame* frame) { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - capture_pending_ = false; - - scoped_ptr<webrtc::DesktopFrame> owned_frame(frame); - - if (owned_frame) { - scheduler_.RecordCaptureTime( - base::TimeDelta::FromMilliseconds(owned_frame->capture_time_ms())); - } - - // Even when |frame| is nullptr we still need to post it to the encode thread - // to make sure frames are freed in the same order they are received and - // that we don't start capturing frame n+2 before frame n is freed. - encode_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this, - base::Passed(&owned_frame), latest_event_timestamp_, - base::TimeTicks::Now())); - - // If a frame was skipped, try to capture it again. - if (did_skip_frame_) { - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::CaptureNextFrame, this)); - } -} - -void VideoScheduler::OnMouseCursor(webrtc::MouseCursor* cursor) { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - scoped_ptr<webrtc::MouseCursor> owned_cursor(cursor); - - // Do nothing if the scheduler is being stopped. - if (!capturer_) - return; - - scoped_ptr<protocol::CursorShapeInfo> cursor_proto( - new protocol::CursorShapeInfo()); - cursor_proto->set_width(cursor->image()->size().width()); - cursor_proto->set_height(cursor->image()->size().height()); - cursor_proto->set_hotspot_x(cursor->hotspot().x()); - cursor_proto->set_hotspot_y(cursor->hotspot().y()); - - cursor_proto->set_data(std::string()); - uint8_t* current_row = cursor->image()->data(); - for (int y = 0; y < cursor->image()->size().height(); ++y) { - cursor_proto->mutable_data()->append( - current_row, - current_row + cursor->image()->size().width() * - webrtc::DesktopFrame::kBytesPerPixel); - current_row += cursor->image()->stride(); - } - - network_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, - base::Passed(&cursor_proto))); -} - -void VideoScheduler::OnMouseCursorPosition( - webrtc::MouseCursorMonitor::CursorState state, - const webrtc::DesktopVector& position) { - // We're not subscribing to mouse position changes. - NOTREACHED(); -} - -void VideoScheduler::Start() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this)); -} - -void VideoScheduler::Stop() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - // Clear stubs to prevent further updates reaching the client. - cursor_stub_ = nullptr; - video_stub_ = nullptr; - - keep_alive_timer_.reset(); - - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::StopOnCaptureThread, this)); -} - -void VideoScheduler::Pause(bool pause) { - if (!capture_task_runner_->BelongsToCurrentThread()) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::Pause, this, pause)); - return; - } - - if (is_paused_ != pause) { - is_paused_ = pause; - - // Restart captures if we're resuming and there are none scheduled. - if (!is_paused_ && capture_timer_ && !capture_timer_->IsRunning()) - CaptureNextFrame(); - } -} - -void VideoScheduler::SetLatestEventTimestamp(int64 latest_event_timestamp) { - if (!capture_task_runner_->BelongsToCurrentThread()) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::SetLatestEventTimestamp, - this, latest_event_timestamp)); - return; - } - - latest_event_timestamp_ = latest_event_timestamp; -} - -void VideoScheduler::SetLosslessEncode(bool want_lossless) { - if (!encode_task_runner_->BelongsToCurrentThread()) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - encode_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::SetLosslessEncode, - this, want_lossless)); - return; - } - - encoder_->SetLosslessEncode(want_lossless); -} - -void VideoScheduler::SetLosslessColor(bool want_lossless) { - if (!encode_task_runner_->BelongsToCurrentThread()) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - encode_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::SetLosslessColor, - this, want_lossless)); - return; - } - - encoder_->SetLosslessColor(want_lossless); -} - -// Private methods ----------------------------------------------------------- - -VideoScheduler::~VideoScheduler() { - // Destroy the capturer and encoder on their respective threads. - capture_task_runner_->DeleteSoon(FROM_HERE, capturer_.release()); - capture_task_runner_->DeleteSoon(FROM_HERE, mouse_cursor_monitor_.release()); - encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release()); -} - -// Capturer thread ------------------------------------------------------------- - -void VideoScheduler::StartOnCaptureThread() { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - DCHECK(!capture_timer_); - - // Start mouse cursor monitor. - mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY); - - // Start the capturer. - capturer_->Start(this); - - capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); - keep_alive_timer_.reset(new base::DelayTimer<VideoScheduler>( - FROM_HERE, base::TimeDelta::FromMilliseconds(kKeepAlivePacketIntervalMs), - this, &VideoScheduler::SendKeepAlivePacket)); - - // Capture first frame immediately. - CaptureNextFrame(); -} - -void VideoScheduler::StopOnCaptureThread() { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - // This doesn't deleted already captured frames, so encoder can keep using the - // frames that were captured previously. - capturer_.reset(); - - // |capture_timer_| must be destroyed on the thread on which it is used. - capture_timer_.reset(); -} - -void VideoScheduler::ScheduleNextCapture() { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - capture_timer_->Start(FROM_HERE, - scheduler_.NextCaptureDelay(), - this, - &VideoScheduler::CaptureNextFrame); -} - -void VideoScheduler::CaptureNextFrame() { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - // If we are stopping (|capturer_| is nullptr), or paused, then don't capture. - if (!capturer_ || is_paused_) - return; - - // Make sure we have at most two outstanding recordings. We can simply return - // if we can't make a capture now, the next capture will be started by the - // end of an encode operation. - if (pending_frames_ >= kMaxPendingFrames || capture_pending_) { - did_skip_frame_ = true; - return; - } - - did_skip_frame_ = false; - - // At this point we are going to perform one capture so save the current time. - pending_frames_++; - DCHECK_LE(pending_frames_, kMaxPendingFrames); - - // Before doing a capture schedule for the next one. - ScheduleNextCapture(); - - capture_pending_ = true; - - // Capture the mouse shape. - mouse_cursor_monitor_->Capture(); - - // And finally perform one capture. - capturer_->Capture(webrtc::DesktopRegion()); -} - -void VideoScheduler::FrameCaptureCompleted() { - DCHECK(capture_task_runner_->BelongsToCurrentThread()); - - // Decrement the pending capture count. - pending_frames_--; - DCHECK_GE(pending_frames_, 0); - - // If we've skipped a frame capture because too we had too many captures - // pending then schedule one now. - if (did_skip_frame_) - CaptureNextFrame(); -} - -// Network thread -------------------------------------------------------------- - -void VideoScheduler::SendVideoPacket(scoped_ptr<VideoPacket> packet) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!video_stub_) - return; - - video_stub_->ProcessVideoPacket( - packet.Pass(), base::Bind(&VideoScheduler::OnVideoPacketSent, this)); -} - -void VideoScheduler::OnVideoPacketSent() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!video_stub_) - return; - - keep_alive_timer_->Reset(); - - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::FrameCaptureCompleted, this)); -} - -void VideoScheduler::SendKeepAlivePacket() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!video_stub_) - return; - - video_stub_->ProcessVideoPacket( - make_scoped_ptr(new VideoPacket()), - base::Bind(&VideoScheduler::OnKeepAlivePacketSent, this)); -} - -void VideoScheduler::OnKeepAlivePacketSent() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (keep_alive_timer_) - keep_alive_timer_->Reset(); -} - -void VideoScheduler::SendCursorShape( - scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!cursor_stub_) - return; - - cursor_stub_->SetCursorShape(*cursor_shape); -} - -// Encoder thread -------------------------------------------------------------- - -void VideoScheduler::EncodeFrame( - scoped_ptr<webrtc::DesktopFrame> frame, - int64 latest_event_timestamp, - base::TimeTicks timestamp) { - DCHECK(encode_task_runner_->BelongsToCurrentThread()); - - // If there is nothing to encode then send an empty packet. - if (!frame || frame->updated_region().is_empty()) { - capture_task_runner_->DeleteSoon(FROM_HERE, frame.release()); - scoped_ptr<VideoPacket> packet(new VideoPacket()); - packet->set_latest_event_timestamp(latest_event_timestamp); - network_task_runner_->PostTask( - FROM_HERE, - base::Bind( - &VideoScheduler::SendVideoPacket, this, base::Passed(&packet))); - return; - } - - scoped_ptr<VideoPacket> packet = encoder_->Encode(*frame); - packet->set_latest_event_timestamp(latest_event_timestamp); - - if (g_enable_timestamps) { - packet->set_timestamp(timestamp.ToInternalValue()); - } - - // Destroy the frame before sending |packet| because SendVideoPacket() may - // trigger another frame to be captured, and the screen capturer expects the - // old frame to be freed by then. - frame.reset(); - - scheduler_.RecordEncodeTime( - base::TimeDelta::FromMilliseconds(packet->encode_time_ms())); - network_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this, - base::Passed(&packet))); -} - -} // namespace remoting
diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc index b7997912..0537218a 100644 --- a/remoting/host/win/unprivileged_process_delegate.cc +++ b/remoting/host/win/unprivileged_process_delegate.cc
@@ -58,7 +58,7 @@ // containers and objects inherit ACE giving SYSTEM and the logon SID full // access to them as well. const char kWindowStationSdFormat[] = "O:SYG:SYD:(A;CIOIIO;GA;;;SY)" - "(A;CIOIIO;GA;;;%1$s)(A;NP;0xf037f;;;SY)(A;NP;0xf037f;;;%1$s)"; + "(A;CIOIIO;GA;;;%s)(A;NP;0xf037f;;;SY)(A;NP;0xf037f;;;%s)"; // Security descriptor of the worker process. It gives access SYSTEM full access // to the process. It gives READ_CONTROL, SYNCHRONIZE, PROCESS_QUERY_INFORMATION @@ -123,7 +123,8 @@ std::string desktop_sddl = base::StringPrintf(kDesktopSdFormat, logon_sid_string.c_str()); std::string window_station_sddl = - base::StringPrintf(kWindowStationSdFormat, logon_sid_string.c_str()); + base::StringPrintf(kWindowStationSdFormat, logon_sid_string.c_str(), + logon_sid_string.c_str()); // The worker runs at low integrity level. Make sure it will be able to attach // to the window station and desktop.
diff --git a/remoting/remoting_client.gypi b/remoting/remoting_client.gypi index cf54377d..e8f3efb 100644 --- a/remoting/remoting_client.gypi +++ b/remoting/remoting_client.gypi
@@ -159,13 +159,22 @@ 'zip_path': '<(PRODUCT_DIR)/remoting-webapp.v2_pnacl.zip', 'webapp_type': 'v2_pnacl', 'extra_files': [ - 'webapp/crd/remoting_client_pnacl.nmf', + 'webapp/crd/remoting_client_pnacl.nmf.jinja2', '<(PRODUCT_DIR)/remoting_client_plugin_newlib.pexe', ], }, 'dependencies': [ 'remoting_nacl.gyp:remoting_client_plugin_nacl', ], + 'conditions': [ + ['buildtype == "Dev"', { + 'variables': { + 'extra_files': [ + '<(PRODUCT_DIR)/remoting_client_plugin_newlib.pexe.debug', + ], + }, + }], + ], 'includes': [ 'remoting_webapp.gypi', ], }, # end of target 'remoting_webapp_v2_pnacl' ],
diff --git a/remoting/remoting_host_srcs.gypi b/remoting/remoting_host_srcs.gypi index 8083520..2d92908 100644 --- a/remoting/remoting_host_srcs.gypi +++ b/remoting/remoting_host_srcs.gypi
@@ -230,8 +230,8 @@ 'host/video_frame_recorder.h', 'host/video_frame_recorder_host_extension.cc', 'host/video_frame_recorder_host_extension.h', - 'host/video_scheduler.cc', - 'host/video_scheduler.h', + 'host/video_frame_pump.cc', + 'host/video_frame_pump.h', 'host/win/com_imported_mstscax.tlh', 'host/win/com_security.cc', 'host/win/com_security.h',
diff --git a/remoting/remoting_key_tester.gypi b/remoting/remoting_key_tester.gypi index d1aab86..ca8c5029 100644 --- a/remoting/remoting_key_tester.gypi +++ b/remoting/remoting_key_tester.gypi
@@ -11,6 +11,7 @@ 'remoting_key_tester_js_files': [ 'tools/javascript_key_tester/background.js', 'tools/javascript_key_tester/chord_tracker.js', + 'tools/javascript_key_tester/event_listeners.js', 'tools/javascript_key_tester/keyboard_map.js', 'tools/javascript_key_tester/main.js', ], @@ -34,6 +35,7 @@ 'tools/javascript_key_tester/main.css', 'tools/javascript_key_tester/main.html', 'tools/javascript_key_tester/manifest.json', + 'tools/javascript_key_tester/icon_128.png', 'tools/javascript_key_tester/pnacl/remoting_key_tester.nmf', '<(PRODUCT_DIR)/remoting_key_tester_newlib.pexe', ], @@ -45,9 +47,7 @@ 'target_name': 'remoting_key_tester_jscompile', 'type': 'none', 'conditions': [ - # TODO(lukasza): Enable when remoting_key_tester_jscompile is clean. - # ['run_jscompile != 0', { - ['0 != 0', { + ['run_jscompile != 0', { 'variables': { 'success_stamp': '<(PRODUCT_DIR)/<(_target_name).stamp', }, @@ -56,6 +56,7 @@ 'action_name': 'jscompile remoting_key_tester', 'inputs': [ '<@(remoting_key_tester_js_files)', + 'webapp/js_proto/chrome_proto.js' ], 'outputs': [ '<(success_stamp)', @@ -66,6 +67,7 @@ '--no-single-file', '--success-stamp', '<(success_stamp)', '<@(remoting_key_tester_js_files)', + 'webapp/js_proto/chrome_proto.js' ], }, ], # actions
diff --git a/remoting/remoting_nacl.gyp b/remoting/remoting_nacl.gyp index 0b66b6b..aa7e848f 100644 --- a/remoting/remoting_nacl.gyp +++ b/remoting/remoting_nacl.gyp
@@ -182,7 +182,6 @@ '../native_client/tools.gyp:prep_toolchain', '../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted', '../net/net_nacl.gyp:net_nacl', - '../ppapi/native_client/native_client.gyp:nacl_irt', '../ppapi/native_client/native_client.gyp:ppapi_lib', '../ppapi/ppapi_nacl.gyp:ppapi_cpp_lib', '../third_party/expat/expat_nacl.gyp:expat_nacl',
diff --git a/remoting/remoting_test.gypi b/remoting/remoting_test.gypi index 67c5594..0b97aa22 100644 --- a/remoting/remoting_test.gypi +++ b/remoting/remoting_test.gypi
@@ -181,7 +181,7 @@ 'host/shaped_desktop_capturer_unittest.cc', 'host/token_validator_factory_impl_unittest.cc', 'host/video_frame_recorder_unittest.cc', - 'host/video_scheduler_unittest.cc', + 'host/video_frame_pump_unittest.cc', 'host/win/rdp_client_unittest.cc', 'host/win/worker_process_launcher.cc', 'host/win/worker_process_launcher.h',
diff --git a/remoting/remoting_webapp.gypi b/remoting/remoting_webapp.gypi index 0ad3fe6b..2c767fda 100644 --- a/remoting/remoting_webapp.gypi +++ b/remoting/remoting_webapp.gypi
@@ -13,6 +13,7 @@ '<(SHARED_INTERMEDIATE_DIR)/wcs_sandbox.html', '<(SHARED_INTERMEDIATE_DIR)/background.html', ], + 'dr_webapp_locales_listfile': '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)_locales.txt', }, 'dependencies': [ 'remoting_resources', @@ -47,12 +48,30 @@ ], 'actions': [ { + 'action_name': 'Build Remoting locales listfile', + 'inputs': [ + '<(remoting_localize_path)', + ], + 'outputs': [ + '<(dr_webapp_locales_listfile)', + ], + 'action': [ + 'python', '<(remoting_localize_path)', + '--locale_output', + '"<(webapp_locale_dir)/@{json_suffix}/messages.json"', + '--locales_listfile', + '<(dr_webapp_locales_listfile)', + '<@(remoting_locales)', + ], + }, + { 'action_name': 'Build Remoting WebApp', 'inputs': [ 'webapp/build-webapp.py', 'webapp/crd/manifest.json.jinja2', '<(chrome_version_path)', '<(remoting_version_path)', + '<(dr_webapp_locales_listfile)', '<@(generated_html_files)', '<@(remoting_webapp_crd_files)', '<@(remoting_webapp_locale_files)', @@ -73,7 +92,8 @@ '<@(generated_html_files)', '<@(remoting_webapp_crd_files)', '<@(extra_files)', - '--locales', '<@(remoting_webapp_locale_files)', + '--locales_listfile', + '<(dr_webapp_locales_listfile)', ], }, ],
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi index 6f1bf585..c98a8b3 100644 --- a/remoting/remoting_webapp_files.gypi +++ b/remoting/remoting_webapp_files.gypi
@@ -241,6 +241,7 @@ 'webapp/crd/js/hangout_consent_dialog.js', 'webapp/crd/js/host_installer.js', 'webapp/crd/js/host_session.js', + 'webapp/crd/js/identity.js', 'webapp/crd/js/it2me_helpee_channel.js', 'webapp/crd/js/it2me_helper_channel.js', 'webapp/crd/js/it2me_host_facade.js',
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index b026b41b..03ca7d71 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd
@@ -1050,6 +1050,9 @@ <message desc="Label for the button to decline sharing the computer in 'It2Me' mode." name="IDS_SHARE_CONFIRM_DIALOG_DECLINE" > Cancel </message> + <message desc="Text shown in tooltip to inform the user that a setting is managed by domain policy." name="IDS_SETTING_MANAGED_BY_POLICY"> + This setting is managed by your domain policy. + </message> </messages> </release>
diff --git a/remoting/test/app_remoting_test_driver.cc b/remoting/test/app_remoting_test_driver.cc new file mode 100644 index 0000000..07bbde7 --- /dev/null +++ b/remoting/test/app_remoting_test_driver.cc
@@ -0,0 +1,154 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/strings/stringprintf.h" +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" +#include "base/test/test_switches.h" +#include "google_apis/google_api_keys.h" +#include "net/base/escape.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace switches { + const char kUserNameSwitchName[] = "username"; + const char kAuthCodeSwitchName[] = "authcode"; + const char kServiceEnvironmentSwitchName[] = "environment"; + const char kHelpSwitchName[] = "help"; + const char kSingleProcessTestsSwitchName[] = "single-process-tests"; +} + +namespace { + +// Requested permissions needed for App Remoting tests. The spaces in between +// scope fragments are necessary and will be escaped properly before use. +const char kAppRemotingAuthScopeValues[] = + "https://www.googleapis.com/auth/appremoting.runapplication" + " https://www.googleapis.com/auth/googletalk" + " https://www.googleapis.com/auth/userinfo.email" + " https://docs.google.com/feeds" + " https://www.googleapis.com/auth/drive"; + +std::string GetAuthorizationCodeUri() { + // Replace space characters with a '+' sign when formatting. + bool use_plus = true; + return base::StringPrintf( + "https://accounts.google.com/o/oauth2/auth" + "?scope=%s" + "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/" + "talkgadget/oauth/chrome-remote-desktop/dev" + "&response_type=code" + "&client_id=%s" + "&access_type=offline" + "&approval_prompt=force", + net::EscapeUrlEncodedData(kAppRemotingAuthScopeValues, use_plus).c_str(), + net::EscapeUrlEncodedData(google_apis::GetOAuth2ClientID( + google_apis::CLIENT_REMOTING), use_plus).c_str()); +} + +void PrintUsage() { + printf("\n**************************************\n"); + printf("*** App Remoting Test Driver Usage ***\n"); + printf("**************************************\n"); + + printf("\nUsage:\n"); + printf(" ar_test_driver --username=<example@gmail.com> [options]\n"); + printf("\nRequired Parameters:\n"); + printf(" %s: Specifies which account to use when running tests\n", + switches::kUserNameSwitchName); + printf("\nOptional Parameters:\n"); + printf(" %s: Exchanged for a refresh and access token for authentication\n", + switches::kAuthCodeSwitchName); + printf(" %s: Displays additional usage information\n", + switches::kHelpSwitchName); + printf(" %s: Specifies the service api to use (dev|test) [default: dev]\n", + switches::kServiceEnvironmentSwitchName); +} + +void PrintAuthCodeInfo() { + printf("\n*******************************\n"); + printf("*** Auth Code Example Usage ***\n"); + printf("*******************************\n\n"); + + printf("If this is the first time you are running the tool,\n"); + printf("you will need to provide an authorization code.\n"); + printf("This code will be exchanged for a long term refresh token which\n"); + printf("will be stored locally and used to acquire a short lived access\n"); + printf("token to connect to the remoting service apis and establish a\n"); + printf("remote host connection.\n\n"); + + printf("Note: You may need to repeat this step if the stored refresh token"); + printf("\n has been revoked or expired.\n"); + printf(" Passing in the same auth code twice will result in an error\n"); + + printf("\nFollow these steps to produce an auth code:\n" + " - Open the Authorization URL link shown below in your browser\n" + " - Approve the requested permissions for the tool\n" + " - Copy the 'code' value in the redirected URL\n" + " - Run the tool and pass in copied auth code as a parameter\n"); + + printf("\nAuthorization URL:\n"); + printf("%s\n", GetAuthorizationCodeUri().c_str()); + + printf("\nRedirected URL Example:\n"); + printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/" + "chrome-remote-desktop/dev?code=4/AKtf...\n"); + + printf("\nTool usage example with the newly created auth code:\n"); + printf("ar_test_driver --%s=example@gmail.com --%s=4/AKtf...\n\n", + switches::kUserNameSwitchName, + switches::kAuthCodeSwitchName); +} + +} // namespace + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + TestSuite test_suite(argc, argv); + + // The pointer returned here refers to a singleton, since we don't own the + // lifetime of the object, don't wrap in a scoped_ptr construct or release it. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + DCHECK(command_line); + + // We do not want to retry failures as a failed test should signify an error + // to be investigated. + command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0"); + + // We do not want to run the tests in parallel and we do not want to retry + // failures. The reason for running in a single process is that some tests + // may share the same remoting host and they cannot be run concurrently, also + // the test output gets spammed with test launcher messages which reduces the + // readability of the results. + command_line->AppendSwitch(switches::kSingleProcessTestsSwitchName); + + // If the user passed in the help flag, then show the help info for this tool + // and 'run' the tests which will print the gtest specific help and then exit. + // NOTE: We do this check after updating the switches as otherwise the gtest + // help is written in parallel with our text and can appear interleaved. + if (command_line->HasSwitch(switches::kHelpSwitchName)) { + PrintUsage(); + PrintAuthCodeInfo(); + return base::LaunchUnitTestsSerially( + argc, + argv, + base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); + } + + // Verify we received the required input from the command line. + if (!command_line->HasSwitch(switches::kUserNameSwitchName)) { + LOG(ERROR) << "No user name passed in, can't authenticate without that!"; + PrintUsage(); + return -1; + } + + // Because many tests may access the same remoting host(s), we need to run + // the tests sequentially so they do not interfere with each other. + return base::LaunchUnitTestsSerially( + argc, + argv, + base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); +}
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc index 7c4ffa3..f5edd8fd 100644 --- a/remoting/test/protocol_perftest.cc +++ b/remoting/test/protocol_perftest.cc
@@ -22,7 +22,7 @@ #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/fake_desktop_environment.h" -#include "remoting/host/video_scheduler.h" +#include "remoting/host/video_frame_pump.h" #include "remoting/protocol/jingle_session_manager.h" #include "remoting/protocol/libjingle_transport_factory.h" #include "remoting/protocol/me2me_host_authenticator_factory.h" @@ -81,7 +81,7 @@ : host_thread_("host"), capture_thread_("capture"), encode_thread_("encode") { - VideoScheduler::EnableTimestampsForTests(); + VideoFramePump::EnableTimestampsForTests(); host_thread_.StartWithOptions( base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); capture_thread_.Start();
diff --git a/remoting/tools/build/remoting_localize.py b/remoting/tools/build/remoting_localize.py index 466a86e..4b6c901 100755 --- a/remoting/tools/build/remoting_localize.py +++ b/remoting/tools/build/remoting_localize.py
@@ -720,7 +720,7 @@ template_file_name = target.safe_substitute(context) outputs.append(template_file_name) - if not options.print_only: + if not options.print_only and not options.locales_listfile: WriteIfChanged(template_file_name, template.render(context), options.encoding) else: @@ -733,6 +733,11 @@ # it into a list. return " ".join(['"%s"' % x for x in outputs]) + if options.locales_listfile: + # Strip off the quotes from each filename when writing into a listfile. + content = u'\n'.join([x.strip('"') for x in outputs]) + WriteIfChanged(options.locales_listfile, content, options.encoding) + return @@ -761,6 +766,9 @@ '--print_only', dest='print_only', action='store_true', default=False, help='print the output file names only.') parser.add_option( + '--locales_listfile', dest='locales_listfile', type='string', + help='print the output file names into the specified file.') + parser.add_option( '-t', '--template', dest='template', type='string', help="specify the template file name.") parser.add_option( @@ -773,11 +781,12 @@ if bool(options.output) == bool(options.locale_output): parser.error( 'Either --output or --locale_output must be specified but not both') - if not options.template and not options.print_only: - parser.error('The template name is required unless --print_only is used') + if (not options.template and + not options.print_only and not options.locales_listfile): + parser.error('The template name is required unless either --print_only ' + 'or --locales_listfile is used') return Localize(options.template, locales, options) if __name__ == '__main__': sys.exit(DoMain(sys.argv[1:])) -
diff --git a/remoting/tools/javascript_key_tester/chord_tracker.js b/remoting/tools/javascript_key_tester/chord_tracker.js index a7cded1..ca1cdb4 100644 --- a/remoting/tools/javascript_key_tester/chord_tracker.js +++ b/remoting/tools/javascript_key_tester/chord_tracker.js
@@ -8,34 +8,39 @@ * @param {HTMLElement} parentDiv */ var ChordTracker = function(parentDiv) { + /** @type {HTMLElement} */ this.parentDiv_ = parentDiv; + /** @type {HTMLElement} */ this.currentDiv_ = null; + /** @type {Object.<HTMLElement>} */ this.pressedKeys_ = {}; }; /** - * @param {number} keyCode + * @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code" + * string. * @param {string} title * @return {void} */ -ChordTracker.prototype.addKeyUpEvent = function(keyCode, title) { - var text = this.keyName_(keyCode); +ChordTracker.prototype.addKeyUpEvent = function(keyId, title) { + var text = this.keyName_(keyId); var span = this.addSpanElement_('key-up', text, title); - delete this.pressedKeys_[keyCode]; + delete this.pressedKeys_[keyId]; if (!this.keysPressed_()) { this.end_(); } }; /** - * @param {number} keyCode + * @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code" + * string. * @param {string} title * @return {void} */ -ChordTracker.prototype.addKeyDownEvent = function(keyCode, title) { - var text = this.keyName_(keyCode); +ChordTracker.prototype.addKeyDownEvent = function(keyId, title) { + var text = this.keyName_(keyId); var span = this.addSpanElement_('key-down', text, title); - this.pressedKeys_[keyCode] = span; + this.pressedKeys_[keyId] = span; }; /** @@ -63,11 +68,13 @@ * @param {string} className * @param {string} text * @param {string} title + * @return {HTMLElement} */ ChordTracker.prototype.addSpanElement_ = function(className, text, title) { this.begin_(); - var span = document.createElement('span'); + var span = /** @type {HTMLElement} */ (document.createElement('span')); span.classList.add(className); + span.classList.add('key-div'); span.innerText = text; span.title = title; this.currentDiv_.appendChild(span); @@ -81,7 +88,7 @@ if (this.currentDiv_) { return; } - this.currentDiv_ = document.createElement('div'); + this.currentDiv_ = /** @type {HTMLElement} */ (document.createElement('div')); this.currentDiv_.classList.add('chord-div'); this.parentDiv_.appendChild(this.currentDiv_); }; @@ -113,15 +120,18 @@ }; /** - * @param {number} keyCode The keyCode field of the keyup or keydown event. + * @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code" + * string. * @return {string} A human-readable representation of the key. * @private */ -ChordTracker.prototype.keyName_ = function(keyCode) { - var result = keyboardMap[keyCode]; +ChordTracker.prototype.keyName_ = function(keyId) { + if (typeof keyId == 'string') { + return keyId; + } + var result = keyboardMap[keyId]; if (!result) { - result = '<' + keyCode + '>'; + result = '<' + keyId + '>'; } return result; }; -
diff --git a/remoting/tools/javascript_key_tester/event_listeners.js b/remoting/tools/javascript_key_tester/event_listeners.js new file mode 100644 index 0000000..a70d40c3 --- /dev/null +++ b/remoting/tools/javascript_key_tester/event_listeners.js
@@ -0,0 +1,179 @@ +/* Copyright 2015 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** @constructor */ +var PNaClEvent = function() { + /** @type {string} */ + this.type = ""; + /** @type {number} */ + this.modifiers = 0; + /** @type {number} */ + this.keyCode = 0; + /** @type {string} */ + this.characterText = ''; + /** @type {string} */ + this.code = ''; +}; + + +/** + * @param {HTMLElement} jsLog + * @param {HTMLElement} pnaclLog + * @param {HTMLElement} textLog + * @param {HTMLElement} pnaclPlugin + * @param {HTMLElement} pnaclListener + * @constructor + */ +var EventListeners = function(jsLog, pnaclLog, textLog, + pnaclPlugin, pnaclListener) { + this.pnaclPlugin_ = pnaclPlugin; + this.pnaclListener_ = pnaclListener; + this.textLog_ = textLog; + + this.onKeyDownHandler_ = this.onKeyDown_.bind(this); + this.onKeyUpHandler_ = this.onKeyUp_.bind(this); + this.onKeyPressHandler_ = this.onKeyPress_.bind(this); + this.onMessageHandler_ = this.onMessage_.bind(this); + this.onPluginBlurHandler_ = this.onPluginBlur_.bind(this); + this.onWindowBlurHandler_ = this.onWindowBlur_.bind(this); + + this.jsChordTracker_ = new ChordTracker(jsLog); + this.pnaclChordTracker_ = new ChordTracker(pnaclLog); + + this.startTime_ = new Date(); +}; + +/** + * Start listening for keyboard events. + */ +EventListeners.prototype.activate = function() { + window.addEventListener('blur', this.onWindowBlurHandler_, false); + document.body.addEventListener('keydown', this.onKeyDownHandler_, false); + document.body.addEventListener('keyup', this.onKeyUpHandler_, false); + document.body.addEventListener('keypress', this.onKeyPressHandler_, false); + this.pnaclListener_.addEventListener('message', this.onMessageHandler_, true); + this.pnaclPlugin_.addEventListener('blur', this.onPluginBlurHandler_, false); + this.onPluginBlur_(); +}; + +/** + * Stop listening for keyboard events. + */ +EventListeners.prototype.deactivate = function() { + window.removeEventListener('blur', this.onWindowBlurHandler_, false); + document.body.removeEventListener('keydown', this.onKeyDownHandler_, false); + document.body.removeEventListener('keyup', this.onKeyUpHandler_, false); + document.body.removeEventListener('keypress', this.onKeyPressHandler_, false); + this.pnaclListener_.removeEventListener( + 'message', this.onMessageHandler_, true); + this.pnaclPlugin_.removeEventListener( + 'blur', this.onPluginBlurHandler_, false); +}; + +/** + * @param {Event} event + * @private + */ +EventListeners.prototype.onKeyDown_ = function(event) { + this.appendToTextLog_(this.jsonifyJavascriptKeyEvent_(event, 'keydown')); + this.jsChordTracker_.addKeyDownEvent( + event.keyCode, this.jsonifyJavascriptKeyEvent_(event, 'keydown', 2)); +}; + +/** + * @param {Event} event + * @return {void} + */ +EventListeners.prototype.onKeyUp_ = function(event) { + this.appendToTextLog_(this.jsonifyJavascriptKeyEvent_(event, 'keyup')); + this.jsChordTracker_.addKeyUpEvent( + event.keyCode, this.jsonifyJavascriptKeyEvent_(event, 'keyup', 2)); +} + +/** + * @param {Event} event + * @return {void} + */ +EventListeners.prototype.onKeyPress_ = function(event) { + this.appendToTextLog_(this.jsonifyJavascriptKeyEvent_(event, 'keypress')); + this.jsChordTracker_.addCharEvent( + String.fromCharCode(event.keyCode), + this.jsonifyJavascriptKeyEvent_(event, 'keypress', 2)); +} + +/** + * @param {Event} event + * @return {void} + */ +EventListeners.prototype.onMessage_ = function (event) { + var pnaclEvent = /** @type {PNaClEvent} */ (event['data']); + + this.appendToTextLog_(this.jsonifyPnaclKeyboardInputEvent_(pnaclEvent)); + var title = this.jsonifyPnaclKeyboardInputEvent_(pnaclEvent, 2); + if (pnaclEvent.type == "KEYDOWN") { + this.pnaclChordTracker_.addKeyDownEvent(pnaclEvent.code, title); + } + if (pnaclEvent.type == "KEYUP") { + this.pnaclChordTracker_.addKeyUpEvent(pnaclEvent.code, title); + } + if (pnaclEvent.type == "CHAR") { + this.pnaclChordTracker_.addCharEvent(pnaclEvent.characterText, title); + } +} + +/** + * @return {void} + */ +EventListeners.prototype.onPluginBlur_ = function() { + this.pnaclPlugin_.focus(); +}; + +/** + * @return {void} + */ +EventListeners.prototype.onWindowBlur_ = function() { + this.jsChordTracker_.releaseAllKeys(); + this.pnaclChordTracker_.releaseAllKeys(); +}; + +/** + * @param {string} str + * @private + */ +EventListeners.prototype.appendToTextLog_ = function(str) { + var div = document.createElement('div'); + div.innerText = (new Date() - this.startTime_) + ':' + str; + this.textLog_.appendChild(div); +}; + +/** + * @param {Event} event + * @param {string} eventName + * @param {number=} opt_space + * @return {string} + * @private + */ +EventListeners.prototype.jsonifyJavascriptKeyEvent_ = + function(event, eventName, opt_space) { + return "JavaScript '" + eventName + "' event = " + JSON.stringify( + event, + ['type', 'alt', 'shift', 'control', 'meta', 'charCode', 'keyCode', + 'keyIdentifier', 'repeat'], + opt_space); +}; + +/** + * @param {PNaClEvent} event + * @param {number=} opt_space + * @return {string} + * @private + */ +EventListeners.prototype.jsonifyPnaclKeyboardInputEvent_ = + function(event, opt_space) { + return "PNaCl KeyboardInputEvent = " + JSON.stringify( + event, + ['type', 'modifiers', 'keyCode', 'characterText', 'code'], + opt_space); +};
diff --git a/remoting/tools/javascript_key_tester/icon_128.png b/remoting/tools/javascript_key_tester/icon_128.png new file mode 100644 index 0000000..77503b8 --- /dev/null +++ b/remoting/tools/javascript_key_tester/icon_128.png Binary files differ
diff --git a/remoting/tools/javascript_key_tester/keyboard_map.js b/remoting/tools/javascript_key_tester/keyboard_map.js index 8fd268a..7ca13665 100644 --- a/remoting/tools/javascript_key_tester/keyboard_map.js +++ b/remoting/tools/javascript_key_tester/keyboard_map.js
@@ -53,16 +53,16 @@ 'Insert', 'Delete', '', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', + 'Digit0', + 'Digit1', + 'Digit2', + 'Digit3', + 'Digit4', + 'Digit5', + 'Digit6', + 'Digit7', + 'Digit8', + 'Digit9', 'Colon', 'Semicolon', 'LessThan', @@ -70,53 +70,53 @@ 'GreaterThen', 'QuestionMark', 'At', - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - 'LeftWin', - 'RightWin', + 'KeyA', + 'KeyB', + 'KeyC', + 'KeyD', + 'KeyE', + 'KeyF', + 'KeyG', + 'KeyH', + 'KeyI', + 'KeyJ', + 'KeyK', + 'KeyL', + 'KeyM', + 'KeyN', + 'KeyO', + 'KeyP', + 'KeyQ', + 'KeyR', + 'KeyS', + 'KeyT', + 'KeyU', + 'KeyV', + 'KeyW', + 'KeyX', + 'KeyY', + 'KeyZ', + 'OSLeft', + 'OSRight', 'ContextMenu', '', 'Sleep', - 'Num0', - 'Num1', - 'Num2', - 'Num3', - 'Num4', - 'Num5', - 'Num6', - 'Num7', - 'Num8', - 'Num9', - 'Multiply', - 'Add', + 'Numpad0', + 'Numpad1', + 'Numpad2', + 'Numpad3', + 'Numpad4', + 'Numpad5', + 'Numpad6', + 'Numpad7', + 'Numpad8', + 'Numpad9', + 'NumpadMultiply', + 'NumpadAdd', 'Separator', - 'Subtract', - 'Decimal', - 'Divide', + 'NumpadSubtract', + 'NumpadDecimal', + 'NumpadDivide', 'F1', 'F2', 'F3', @@ -192,12 +192,12 @@ '', '', '', - '', + 'Equal', 'Comma', - '', + 'Minus', 'Period', 'Slash', - 'BackQuote', + 'Backquote', '', '', '',
diff --git a/remoting/tools/javascript_key_tester/main.css b/remoting/tools/javascript_key_tester/main.css index 8010f61..0c6f4e5 100644 --- a/remoting/tools/javascript_key_tester/main.css +++ b/remoting/tools/javascript_key_tester/main.css
@@ -12,44 +12,44 @@ height: 100%; } -#pnacl-plugin { - background-color: gray; - border: 1px solid -} - -#pnacl-plugin:focus { - background-color: yellow; -} - .summary-log-container { width: 50%; - height: 50vh; + height: 100%; overflow-y: auto; float: left; } -.text-log-container { - width: 100%; - max-height: 25vh; - overflow-y: auto; - float: left; +#text-log-container { + position: fixed; + top: 32px; + left: 16px; + right: 16px; + bottom: 32px; + border: 1px solid gray; + box-shadow: 0px 4px 10px 4px rgba(0,0,0,0.3); + background-color: white; + overflow: scroll; } -.char-event, -.key-down, -.key-up { +#text-log { + padding: 8px; +} + +.selectable { + -webkit-user-select: text; + cursor: text; +} + +.key-div { border-radius: 4px; border: 1px solid rgba(0, 0, 0, 0.3); padding: 2px; margin-right: 2px; + display: inline-block; } .char-event { - background-color: yellow; -} - -.char-event::before { - content: "char:"; + background-color: #DDF; } .key-up { @@ -57,7 +57,7 @@ } .key-up::before { - content: "-"; + content: "\2011"; /** non-breaking hyphen */ } .key-down { @@ -93,3 +93,9 @@ content: " \2716"; /* cross */ color: red; } + +.controls { + position: absolute; + right: 8px; + top: 8px; +} \ No newline at end of file
diff --git a/remoting/tools/javascript_key_tester/main.html b/remoting/tools/javascript_key_tester/main.html index 791c024..dfdf634 100644 --- a/remoting/tools/javascript_key_tester/main.html +++ b/remoting/tools/javascript_key_tester/main.html
@@ -9,20 +9,21 @@ <head> <title>Chrome AppsV2 Key Event Tester</title> <script src="chord_tracker.js"></script> + <script src="event_listeners.js"></script> <script src="keyboard_map.js"></script> <script src="main.js"></script> <link rel="stylesheet" href="main.css"> </head> <body> <h2>Chrome AppsV2 Key Event Tester</h2> - <div id="pnacl-listener"> - PNaCl focus box: - <embed id="pnacl-plugin" width=100 height=12 - src="remoting_key_tester.nmf" type="application/x-pnacl" /> - (click inside to get focus, yellow background means it has focus). + <div class="controls"> + <button id="show-log">Debug log</button> + <button id="clear-log">Clear logs</button> </div> - <button id="clear-log">Clear logs</button> - <hr/> + <div id="pnacl-listener"> + <embed id="pnacl-plugin" width=0 height=0 + src="remoting_key_tester.nmf" type="application/x-pnacl" /> + </div> <div class="logs"> <div class="summary-log-container"> Summary of JavaScript logs: @@ -34,9 +35,13 @@ <div id="pnacl-log"> </div> </div> - <div class="text-log-container"> - Text log of JSON-ified events: - <div id="text-log"> + <div id="text-log-container" hidden> + <div> + </div> + <div class="controls"> + <button id="hide-log">Close</button> + </div> + <div id="text-log" class="selectable"> </div> </div> </div>
diff --git a/remoting/tools/javascript_key_tester/main.js b/remoting/tools/javascript_key_tester/main.js index e37e426..1dc8bbee 100644 --- a/remoting/tools/javascript_key_tester/main.js +++ b/remoting/tools/javascript_key_tester/main.js
@@ -3,140 +3,44 @@ * found in the LICENSE file. */ -/** - * @param {string} eventName - * @param {number=} opt_space - * @return {string} - */ -function jsonifyJavascriptKeyEvent(event, eventName, opt_space) { - return "JavaScript '" + eventName + "' event = " + JSON.stringify( - event, - ['type', 'alt', 'shift', 'control', 'meta', 'charCode', 'keyCode', - 'keyIdentifier', 'repeat'], - opt_space); -}; - -/** - * @param {ChordTracker} jsChordTracker - * @param {Event} event - * @return {void} - */ -function handleJavascriptKeyDownEvent(jsChordTracker, event) { - appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keydown', undefined)); - jsChordTracker.addKeyDownEvent( - event.keyCode, jsonifyJavascriptKeyEvent(event, 'keydown', 2)); -} - -/** - * @param {ChordTracker} jsChordTracker - * @param {Event} event - * @return {void} - */ -function handleJavascriptKeyUpEvent(jsChordTracker, event) { - appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keyup', undefined)); - jsChordTracker.addKeyUpEvent( - event.keyCode, jsonifyJavascriptKeyEvent(event, 'keyup', 2)); -} - -/** @constructor */ -var PNaClEvent = function() { - /** @type {string} */ - this.type = ""; - /** @type {number} */ - this.modifiers = 0; - /** @type {number} */ - this.keyCode = 0; - /** @type {string|undefined} */ - this.characterText = undefined; - /** @type {string} */ - this.code = ""; -}; - -/** - * @param {PNaClEvent} event - * @param {number|undefined} space - * @return {string} - */ -function jsonifyPnaclKeyboardInputEvent(event, space) { - return "PNaCl KeyboardInputEvent = " + JSON.stringify( - event, - ['type', 'modifiers', 'keyCode', 'characterText', 'code'], - space); -}; - -/** - * @param {ChordTracker} pnaclChordTracker - * @param {Event} event - * @return {void} - */ -function handlePNaclMessage(pnaclChordTracker, event) { - var pnaclEvent = /** @type {PNaClEvent} */ (event.data); - - appendToTextLog(jsonifyPnaclKeyboardInputEvent(pnaclEvent, undefined)); - var title = jsonifyPnaclKeyboardInputEvent(pnaclEvent, 2); - if (pnaclEvent.type == "KEYDOWN") { - pnaclChordTracker.addKeyDownEvent(pnaclEvent.keyCode, title); - } - if (pnaclEvent.type == "KEYUP") { - pnaclChordTracker.addKeyUpEvent(pnaclEvent.keyCode, title); - } - if (pnaclEvent.type == "CHAR") { - pnaclChordTracker.addCharEvent(pnaclEvent.characterText, title); - } -} - -/** - * @param {string} str - * @return {void} - */ -function appendToTextLog(str) { - var textLog = document.getElementById('text-log'); - var div = document.createElement('div'); - div.innerText = str; - textLog.appendChild(div); -} - function onLoad() { - // Start listening to Javascript keyup/keydown events. var jsLog = document.getElementById('javascript-log'); - var jsChordTracker = new ChordTracker(jsLog); - document.body.addEventListener( - 'keydown', - function (event) { - handleJavascriptKeyDownEvent(jsChordTracker, event); - }, - false); - document.body.addEventListener( - 'keyup', - function (event) { - handleJavascriptKeyUpEvent(jsChordTracker, event); - }, - false); - - // Start listening to PNaCl keyboard input events. var pnaclLog = document.getElementById('pnacl-log'); - var pnaclChordTracker = new ChordTracker(pnaclLog); - document.getElementById('pnacl-listener').addEventListener( - 'message', - function (message) { - handlePNaclMessage(pnaclChordTracker, message); - }, - true); + var pnaclPlugin = document.getElementById('pnacl-plugin'); + var pnaclListener = document.getElementById('pnacl-listener'); + var textLog = document.getElementById('text-log'); + var textLogContainer = document.getElementById('text-log-container'); - // Start listening to generic, source-agnostic events. - window.addEventListener( - 'blur', - function () { - jsChordTracker.releaseAllKeys(); - pnaclChordTracker.releaseAllKeys(); - }, - false); + var eventListeners = new EventListeners(jsLog, pnaclLog, textLog, + pnaclPlugin, pnaclListener); + eventListeners.activate(); + document.getElementById('clear-log').addEventListener( 'click', function() { jsLog.innerText = ''; pnaclLog.innerText = ''; - document.getElementById('text-log').innerText = ''; + textLog.innerText = ''; + }, + false); + document.getElementById('show-log').addEventListener( + 'click', + function() { + eventListeners.deactivate(); + textLogContainer.hidden = false; + + var selection = window.getSelection(); + var range = document.createRange(); + range.selectNodeContents(textLog); + selection.removeAllRanges(); + selection.addRange(range); + }, + false); + document.getElementById('hide-log').addEventListener( + 'click', + function() { + eventListeners.activate(); + textLogContainer.hidden = true; }, false); }
diff --git a/remoting/tools/javascript_key_tester/manifest.json b/remoting/tools/javascript_key_tester/manifest.json index 62caf1f..625a4723 100644 --- a/remoting/tools/javascript_key_tester/manifest.json +++ b/remoting/tools/javascript_key_tester/manifest.json
@@ -1,7 +1,10 @@ { "name": "Javascript key event tester", - "version": "1.0", + "version": "1.1", "manifest_version": 2, + "icons": { + "128": "icon_128.png" + }, "app": { "background": { "scripts": ["background.js"]
diff --git a/remoting/tools/javascript_key_tester/promo_440x280.png b/remoting/tools/javascript_key_tester/promo_440x280.png new file mode 100644 index 0000000..f8cb5ce --- /dev/null +++ b/remoting/tools/javascript_key_tester/promo_440x280.png Binary files differ
diff --git a/remoting/tools/javascript_key_tester/screenshot_640x400.png b/remoting/tools/javascript_key_tester/screenshot_640x400.png new file mode 100644 index 0000000..18e9aa7 --- /dev/null +++ b/remoting/tools/javascript_key_tester/screenshot_640x400.png Binary files differ
diff --git a/remoting/webapp/app_remoting/js/loading_window.js b/remoting/webapp/app_remoting/js/loading_window.js index 98a710e9..5aaa1d2 100644 --- a/remoting/webapp/app_remoting/js/loading_window.js +++ b/remoting/webapp/app_remoting/js/loading_window.js
@@ -43,7 +43,7 @@ var kConnectionTimeout = 15 * 60 * 1000; var transparencyWarning = ''; - if (navigator.platform.indexOf('Mac') != -1) { + if (remoting.platformIsMac()) { transparencyWarning = chrome.i18n.getMessage(/*i18n-content*/'NO_TRANSPARENCY_WARNING'); }
diff --git a/remoting/webapp/base/js/application.js b/remoting/webapp/base/js/application.js index d0810be7c..0663528 100644 --- a/remoting/webapp/base/js/application.js +++ b/remoting/webapp/base/js/application.js
@@ -27,7 +27,13 @@ * @type {Array.<string>} * @private */ - this.app_capabilities_ = app_capabilities; + this.app_capabilities_ = [ + remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION, + remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS, + remoting.ClientSession.Capability.VIDEO_RECORDER + ]; + // Append the app-specific capabilities. + this.app_capabilities_.push.apply(this.app_capabilities_, app_capabilities); /** * @type {remoting.SessionConnector} @@ -49,14 +55,7 @@ * by this application. */ remoting.Application.prototype.getRequiredCapabilities_ = function() { - var capabilities = [ - remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION, - remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS, - remoting.ClientSession.Capability.VIDEO_RECORDER - ]; - // Append the app-specific capabilities. - capabilities.push.apply(capabilities, this.app_capabilities_); - return capabilities; + return this.app_capabilities_; }; /**
diff --git a/remoting/webapp/base/js/base.js b/remoting/webapp/base/js/base.js index e9454553..34a7e39 100644 --- a/remoting/webapp/base/js/base.js +++ b/remoting/webapp/base/js/base.js
@@ -78,6 +78,7 @@ for (var i = 0; i < this.disposables_.length; i++) { this.disposables_[i].dispose(); } + this.disposables_ = null; }; /**
diff --git a/remoting/webapp/build-webapp.py b/remoting/webapp/build-webapp.py index 9868b6c..9deddc6 100755 --- a/remoting/webapp/build-webapp.py +++ b/remoting/webapp/build-webapp.py
@@ -118,29 +118,20 @@ if buildtype != 'Official' and buildtype != 'Release' and buildtype != 'Dev': raise Exception('Unknown buildtype: ' + buildtype) - # Use symlinks on linux and mac for faster compile/edit cycle. - # - # On Windows Vista platform.system() can return 'Microsoft' with some - # versions of Python, see http://bugs.python.org/issue1082 - # should_symlink = platform.system() not in ['Windows', 'Microsoft'] - # - # TODO(ajwong): Pending decision on http://crbug.com/27185 we may not be - # able to load symlinked resources. - should_symlink = False + jinja_context = { + 'webapp_type': webapp_type, + 'buildtype': buildtype, + } # Copy all the files. for current_file in files: destination_file = os.path.join(destination, os.path.basename(current_file)) - destination_dir = os.path.dirname(destination_file) - if not os.path.exists(destination_dir): - os.makedirs(destination_dir, 0775) - if should_symlink: - # TODO(ajwong): Detect if we're vista or higher. Then use win32file - # to create a symlink in that case. - targetname = os.path.relpath(os.path.realpath(current_file), - os.path.realpath(destination_file)) - os.symlink(targetname, destination_file) + # Process *.jinja2 files as jinja2 templates + if current_file.endswith(".jinja2"): + destination_file = destination_file[:-len(".jinja2")] + processJinjaTemplate(current_file, jinja_paths, + destination_file, jinja_context) else: shutil.copy2(current_file, destination_file) @@ -374,14 +365,14 @@ '--app_description <description> ' '--app_capabilities <capabilities...> ' '[--appid <appid>] ' - '[--locales <locales...>] ' + '[--locales_listfile <locales-listfile-name>] ' '[--jinja_paths <paths...>] ' '[--service_environment <service_environment>]') return 1 arg_type = '' files = [] - locales = [] + locales_listfile = '' jinja_paths = [] app_id = None app_name = None @@ -390,7 +381,7 @@ service_environment = '' for arg in sys.argv[7:]: - if arg in ['--locales', + if arg in ['--locales_listfile', '--jinja_paths', '--appid', '--app_name', @@ -398,8 +389,9 @@ '--app_capabilities', '--service_environment']: arg_type = arg - elif arg_type == '--locales': - locales.append(arg) + elif arg_type == '--locales_listfile': + locales_listfile = arg + arg_type = '' elif arg_type == '--jinja_paths': jinja_paths.append(arg) elif arg_type == '--appid': @@ -419,6 +411,14 @@ else: files.append(arg) + # Load the locales files from the locales_listfile. + if not locales_listfile: + raise Exception('You must specify a locales_listfile') + locales = [] + with open(locales_listfile) as input: + for s in input: + locales.append(s.rstrip()) + return buildWebApp(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], app_id, app_name, app_description, app_capabilities, files, locales,
diff --git a/remoting/webapp/crd/js/background.js b/remoting/webapp/crd/js/background.js index fd2e41d..96f2833d 100644 --- a/remoting/webapp/crd/js/background.js +++ b/remoting/webapp/crd/js/background.js
@@ -9,45 +9,71 @@ 'use strict'; +var ENABLE_HANGOUT_REMOTE_ASSISTANCE = true; + /** - * The background service is responsible for listening to incoming connection - * requests from Hangouts and the webapp. - * - * @param {remoting.AppLauncher} appLauncher + * @constructor */ -function initializeBackgroundService(appLauncher) { - function initializeIt2MeService() { - /** @type {remoting.It2MeService} */ - remoting.it2meService = new remoting.It2MeService(appLauncher); - remoting.it2meService.init(); - } +var BackgroundPage = function() { + /** @private {remoting.AppLauncher} */ + this.appLauncher_ = null; + /** @private {remoting.ActivationHandler} */ + this.activationHandler_ = null; + /** @private {remoting.It2MeService} */ + this.it2meService_ = null; + /** @private {base.Disposables} */ + this.disposables_ = null; - chrome.runtime.onSuspend.addListener(function() { - base.debug.assert(remoting.it2meService != null); - remoting.it2meService.dispose(); - remoting.it2meService = null; - }); + this.preInit_(); + this.onResumed_(); - remoting.settings = new remoting.Settings(); - - chrome.runtime.onSuspendCanceled.addListener(initializeIt2MeService); - initializeIt2MeService(); -} - -function main() { - if (base.isAppsV2()) { - new remoting.ActivationHandler(base.Ipc.getInstance(), - new remoting.V2AppLauncher()); - } -} - -remoting.enableHangoutsRemoteAssistance = function() { - /** @type {remoting.AppLauncher} */ - var appLauncher = base.isAppsV2() ? new remoting.V1AppLauncher(): - new remoting.V2AppLauncher(); - initializeBackgroundService(appLauncher); + chrome.runtime.onSuspendCanceled.addListener(this.onResumed_.bind(this)); + chrome.runtime.onSuspend.addListener(this.onSuspended_.bind(this)); }; -window.addEventListener('load', main, false); +/** + * Initialize members and globals that are valid throughout the entire lifetime + * of the background page. + * + * @private + */ +BackgroundPage.prototype.preInit_ = function() { + remoting.settings = new remoting.Settings(); + if (base.isAppsV2()) { + remoting.identity = new remoting.Identity(); + } else { + remoting.oauth2 = new remoting.OAuth2(); + var oauth2 = /** @type {*} */ (remoting.oauth2); + remoting.identity = /** @type {remoting.Identity} */ (oauth2); + } + + if (base.isAppsV2()) { + this.appLauncher_ = new remoting.V2AppLauncher(); + this.activationHandler_ = new remoting.ActivationHandler( + base.Ipc.getInstance(), this.appLauncher_); + } else { + this.appLauncher_ = new remoting.V1AppLauncher(); + } +}; + +/** @private */ +BackgroundPage.prototype.onResumed_ = function() { + if (ENABLE_HANGOUT_REMOTE_ASSISTANCE) { + this.it2meService_ = new remoting.It2MeService(this.appLauncher_); + this.it2meService_.init(); + this.disposables_ = new base.Disposables(this.it2meService_); + } +}; + +/** @private */ +BackgroundPage.prototype.onSuspended_ = function() { + this.it2meService_ = null; + base.dispose(this.disposables_); + this.disposables_ = null; +}; + +window.addEventListener('load', function() { + remoting.backgroundPage = new BackgroundPage(); +}, false); }());
diff --git a/remoting/webapp/crd/js/host_screen.js b/remoting/webapp/crd/js/host_screen.js index 10304d06..e1ddda4 100644 --- a/remoting/webapp/crd/js/host_screen.js +++ b/remoting/webapp/crd/js/host_screen.js
@@ -7,18 +7,19 @@ * Functions related to the 'host screen' for Chromoting. */ -'use strict'; - /** @suppress {duplicate} */ var remoting = remoting || {}; +(function(){ + +'use strict'; + /** @type {remoting.HostSession} */ -remoting.hostSession = null; +var hostSession_ = null; /** * @type {boolean} Whether or not the last share was cancelled by the user. * This controls what screen is shown when the host signals completion. - * @private */ var lastShareWasCancelled_ = false; @@ -37,7 +38,7 @@ var tryInitializeFacade = function() { hostFacade.initialize(onFacadeInitialized, onFacadeInitializationFailed); - } + }; var onFacadeInitialized = function () { // Host already installed. @@ -47,7 +48,7 @@ var onFacadeInitializationFailed = function() { // If we failed to initialize the dispatcher then prompt the user to install // the host manually. - var hasHostDialog = (hostInstallDialog != null); /** jscompile hack */ + var hasHostDialog = (hostInstallDialog !== null); /** jscompile hack */ if (!hasHostDialog) { hostInstallDialog = new remoting.HostInstallDialog(); hostInstallDialog.show(tryInitializeFacade, onInstallError); @@ -63,7 +64,7 @@ } else { showShareError_(error); } - } + }; tryInitializeFacade(); }; @@ -91,9 +92,10 @@ document.getElementById('cancel-share-button').disabled = false; disableTimeoutCountdown_(); - remoting.hostSession = new remoting.HostSession(); + base.debug.assert(hostSession_ === null); + hostSession_ = new remoting.HostSession(); var email = /** @type {string} */ (remoting.identity.getCachedEmail()); - remoting.hostSession.connect( + hostSession_.connect( hostFacade, email, token, onHostStateChanged_, onNatTraversalPolicyChanged_, logDebugInfo_, it2meConnectFailed_); }; @@ -102,7 +104,6 @@ * Callback for the host plugin to notify the web app of state changes. * @param {remoting.HostSession.State} state The new state of the plugin. * @return {void} Nothing. - * @private */ function onHostStateChanged_(state) { if (state == remoting.HostSession.State.STARTING) { @@ -115,7 +116,7 @@ } else if (state == remoting.HostSession.State.RECEIVED_ACCESS_CODE) { console.log('Host state: RECEIVED_ACCESS_CODE'); - var accessCode = remoting.hostSession.getAccessCode(); + var accessCode = hostSession_.getAccessCode(); var accessCodeDisplay = document.getElementById('access-code-display'); accessCodeDisplay.innerText = ''; // Display the access code in groups of four digits for readability. @@ -126,7 +127,7 @@ nextFourDigits.innerText = accessCode.substring(i, i + kDigitsPerGroup); accessCodeDisplay.appendChild(nextFourDigits); } - accessCodeExpiresIn_ = remoting.hostSession.getAccessCodeLifetime(); + accessCodeExpiresIn_ = hostSession_.getAccessCodeLifetime(); if (accessCodeExpiresIn_ > 0) { // Check it hasn't expired. accessCodeTimerId_ = setInterval(decrementAccessCodeTimeout_, 1000); timerRunning_ = true; @@ -143,7 +144,7 @@ } else if (state == remoting.HostSession.State.CONNECTED) { console.log('Host state: CONNECTED'); var element = document.getElementById('host-shared-message'); - var client = remoting.hostSession.getClient(); + var client = hostSession_.getClient(); l10n.localizeElement(element, client); remoting.setMode(remoting.AppMode.HOST_SHARED); disableTimeoutCountdown_(); @@ -163,6 +164,7 @@ remoting.setMode(remoting.AppMode.HOST_SHARE_FINISHED); } } + cleanUp(); } else if (state == remoting.HostSession.State.ERROR) { console.error('Host state: ERROR'); showShareError_(remoting.Error.UNEXPECTED); @@ -178,7 +180,6 @@ * This is the callback that the host plugin invokes to indicate that there * is additional debug log info to display. * @param {string} msg The message (which will not be localized) to be logged. - * @private */ function logDebugInfo_(msg) { console.log('plugin: ' + msg); @@ -189,20 +190,19 @@ * * @param {string} errorTag The error message to be localized and displayed. * @return {void} Nothing. - * @private */ function showShareError_(errorTag) { var errorDiv = document.getElementById('host-plugin-error'); l10n.localizeElementFromTag(errorDiv, errorTag); console.error('Sharing error: ' + errorTag); remoting.setMode(remoting.AppMode.HOST_SHARE_FAILED); + cleanUp(); } /** * Show a sharing error with error code UNEXPECTED . * * @return {void} Nothing. - * @private */ function it2meConnectFailed_() { // TODO (weitaosu): Instruct the user to install the native messaging host. @@ -212,6 +212,11 @@ showShareError_(remoting.Error.UNEXPECTED); } +function cleanUp() { + base.dispose(hostSession_); + hostSession_ = null; +} + /** * Cancel an active or pending it2me share operation. * @@ -222,7 +227,7 @@ console.log('Canceling share...'); remoting.lastShareWasCancelled = true; try { - remoting.hostSession.disconnect(); + hostSession_.disconnect(); } catch (/** @type {*} */ error) { console.error('Error disconnecting: ' + error + '. The host probably crashed.'); @@ -237,36 +242,31 @@ /** * @type {boolean} Whether or not the access code timeout countdown is running. - * @private */ var timerRunning_ = false; /** * @type {number} The id of the access code expiry countdown timer. - * @private */ var accessCodeTimerId_ = 0; /** * @type {number} The number of seconds until the access code expires. - * @private */ var accessCodeExpiresIn_ = 0; /** * The timer callback function * @return {void} Nothing. - * @private */ function decrementAccessCodeTimeout_() { --accessCodeExpiresIn_; updateAccessCodeTimeoutElement_(); -}; +} /** * Stop the access code timeout countdown if it is running. * @return {void} Nothing. - * @private */ function disableTimeoutCountdown_() { if (timerRunning_) { @@ -278,7 +278,6 @@ /** * Constants controlling the access code timer countdown display. - * @private */ var ACCESS_CODE_TIMER_DISPLAY_THRESHOLD_ = 30; var ACCESS_CODE_RED_THRESHOLD_ = 10; @@ -289,7 +288,6 @@ * * @return {boolean} True if the timeout is in progress, false if it has * expired. - * @private */ function updateTimeoutStyles_() { if (timerRunning_) { @@ -314,7 +312,6 @@ * Update the text and appearance of the access code timeout element to * reflect the time remaining. * @return {void} Nothing. - * @private */ function updateAccessCodeTimeoutElement_() { var pad = (accessCodeExpiresIn_ < 10) ? '0:0' : '0:'; @@ -329,7 +326,6 @@ * Callback to show or hide the NAT traversal warning when the policy changes. * @param {boolean} enabled True if NAT traversal is enabled. * @return {void} Nothing. - * @private */ function onNatTraversalPolicyChanged_(enabled) { var natBox = document.getElementById('nat-box'); @@ -339,3 +335,5 @@ natBox.classList.remove('traversal-enabled'); } } + +})(); \ No newline at end of file
diff --git a/remoting/webapp/crd/js/host_session.js b/remoting/webapp/crd/js/host_session.js index 7fb8432..fb268cd 100644 --- a/remoting/webapp/crd/js/host_session.js +++ b/remoting/webapp/crd/js/host_session.js
@@ -18,6 +18,7 @@ /** * @constructor + * @implements {base.Disposable} */ remoting.HostSession = function() { /** @type {remoting.It2MeHostFacade} @private */ @@ -39,6 +40,11 @@ INVALID_DOMAIN_ERROR: 7 }; +remoting.HostSession.prototype.dispose = function() { + base.dispose(this.hostFacade_); + this.hostFacade_ = null; +}; + /** * @param {string} stateString The string representation of the host state. * @return {remoting.HostSession.State} The HostSession.State enum value @@ -50,7 +56,7 @@ return remoting.HostSession.State.UNKNOWN; } return remoting.HostSession.State[stateString]; -} +}; /** * Initiates a connection.
diff --git a/remoting/webapp/crd/js/host_setup_dialog.js b/remoting/webapp/crd/js/host_setup_dialog.js index 24097a1..8fb02de0 100644 --- a/remoting/webapp/crd/js/host_setup_dialog.js +++ b/remoting/webapp/crd/js/host_setup_dialog.js
@@ -190,9 +190,21 @@ * by policy. */ function onGetConsent(supported, allowed, set_by_policy) { - that.usageStats_.hidden = !supported; + // Hide the usage stats check box if it is not supported or the policy + // doesn't allow usage stats collection. + var checkBoxLabel = that.usageStats_.querySelector('.checkbox-label'); + that.usageStats_.hidden = !supported || (set_by_policy && !allowed); that.usageStatsCheckbox_.checked = allowed; + that.usageStatsCheckbox_.disabled = set_by_policy; + checkBoxLabel.classList.toggle('disabled', set_by_policy); + + if (set_by_policy) { + that.usageStats_.title = l10n.getTranslationOrError( + /*i18n-content*/ 'SETTING_MANAGED_BY_POLICY'); + } else { + that.usageStats_.title = ''; + } } /** @param {remoting.Error} error */ @@ -200,7 +212,7 @@ console.error('Error getting consent status: ' + error); } - this.usageStats_.hidden = false; + this.usageStats_.hidden = true; this.usageStatsCheckbox_.checked = false; // Prevent user from ticking the box until the current consent status is
diff --git a/remoting/webapp/crd/js/identity.js b/remoting/webapp/crd/js/identity.js index 0421410..161e083 100644 --- a/remoting/webapp/crd/js/identity.js +++ b/remoting/webapp/crd/js/identity.js
@@ -21,12 +21,12 @@ remoting.identity = null; /** - * @param {remoting.Identity.ConsentDialog} consentDialog + * @param {remoting.Identity.ConsentDialog=} opt_consentDialog * @constructor */ -remoting.Identity = function(consentDialog) { +remoting.Identity = function(opt_consentDialog) { /** @private */ - this.consentDialog_ = consentDialog; + this.consentDialog_ = opt_consentDialog; /** @type {string} @private */ this.email_ = ''; /** @type {string} @private */ @@ -36,7 +36,7 @@ }; /** - * chrome.identity.getAuthToken must be initiated from user interactions if + * chrome.identity.getAuthToken should be initiated from user interactions if * called with interactive equals true. This interface prompts a dialog for * the user's consent. * @@ -223,7 +223,9 @@ // If there's no token, but we haven't yet prompted for permission, do so // now. var that = this; - this.consentDialog_.show().then(function() { + var showConsentDialog = + (this.consentDialog_) ? this.consentDialog_.show() : Promise.resolve(); + showConsentDialog.then(function() { chrome.identity.getAuthToken({'interactive': true}, that.onAuthComplete_.bind(that, true)); });
diff --git a/remoting/webapp/crd/js/it2me_helpee_channel.js b/remoting/webapp/crd/js/it2me_helpee_channel.js index 97a14c2..65614f456 100644 --- a/remoting/webapp/crd/js/it2me_helpee_channel.js +++ b/remoting/webapp/crd/js/it2me_helpee_channel.js
@@ -249,33 +249,26 @@ */ remoting.It2MeHelpeeChannel.prototype.handleConnect_ = function(message) { - var email = getStringAttr(message, 'email'); var bounds = /** @type {Bounds} */ (getObjectAttr(message, 'hangoutBounds', null)); - if (!email) { - throw new Error('Missing required parameter: email'); - } - if (this.hostState_ !== remoting.HostSession.State.UNKNOWN) { throw new Error('An existing connection is in progress.'); } var that = this; - this.showConfirmDialog_(bounds).then( - this.initializeHost_.bind(this) - ).then( - this.fetchOAuthToken_.bind(this) - ).then( - /** @type {function(*):void} */(this.connectToHost_.bind(this, email)) - ).catch( - /** @param {*} reason */ - function(reason) { - var error = /** @type {Error} */ (reason); - that.sendErrorResponse_(message, error); - that.dispose(); - } - ); + this.showConfirmDialog_(bounds) + .then(this.initializeHost_.bind(this)) + .then(this.fetchOAuthToken_.bind(this)) + .then(this.fetchEmail_.bind(this)) + /** @param {{email:string, token:string}|Promise} result */ + .then(function(result) { + that.connectToHost_(result.email, result.token); + /** @param {*} reason */ + }).catch(function(reason) { + that.sendErrorResponse_(message, /** @type {Error} */ (reason)); + that.dispose(); + }); }; /** @@ -368,9 +361,10 @@ if (base.isAppsV2()) { /** * @param {function(*=):void} resolve + * @param {function(*=):void} reject */ - return new Promise(function(resolve){ - chrome.identity.getAuthToken({'interactive': true}, resolve); + return new Promise(function(resolve, reject){ + remoting.identity.callWithToken(resolve, reject); }); } else { /** @@ -378,24 +372,41 @@ * @param {function(*=):void} reject */ return new Promise(function(resolve, reject) { - /** @type {remoting.OAuth2} */ - var oauth2 = new remoting.OAuth2(); /** @param {remoting.Error} error */ var onError = function(error) { if (error === remoting.Error.NOT_AUTHENTICATED) { - oauth2.doAuthRedirect(function() { - oauth2.callWithToken(resolve, reject); + remoting.oauth2.doAuthRedirect(function() { + remoting.identity.callWithToken(resolve, reject); }); return; } reject(new Error(remoting.Error.NOT_AUTHENTICATED)); }; - oauth2.callWithToken(resolve, onError); + remoting.identity.callWithToken(resolve, onError); }); } }; /** + * @param {string|Promise} token + * @return {Promise} Promise that resolves with the access token and the email + * of the user. + */ +remoting.It2MeHelpeeChannel.prototype.fetchEmail_ = function(token) { + /** + * @param {function(*=):void} resolve + * @param {function(*=):void} reject + */ + return new Promise(function(resolve, reject){ + /** @param {string} email */ + function onEmail (email) { + resolve({ email: email, token: token }); + } + remoting.identity.getEmail(onEmail, reject); + }); +}; + +/** * Connects to the It2Me Native Messaging Host and retrieves the access code * in the |onHostStateChanged_| callback. *
diff --git a/remoting/webapp/crd/js/it2me_host_facade.js b/remoting/webapp/crd/js/it2me_host_facade.js index 621befb..c33f8ebd 100644 --- a/remoting/webapp/crd/js/it2me_host_facade.js +++ b/remoting/webapp/crd/js/it2me_host_facade.js
@@ -7,51 +7,39 @@ * Class to communicate with the It2me Host component via Native Messaging. */ -'use strict'; - /** @suppress {duplicate} */ var remoting = remoting || {}; +(function() { + +'use strict'; + /** * @constructor + * @implements {base.Disposable} */ remoting.It2MeHostFacade = function() { - /** - * @type {number} - * @private - */ + /** @private {number} */ this.nextId_ = 0; - /** - * @type {?chrome.runtime.Port} - * @private - */ + /** @private {?chrome.runtime.Port} */ this.port_ = null; - /** - * @type {string} - * @private - */ + /** @private {string} */ this.accessCode_ = ''; - /** - * @type {number} - * @private - */ + /** @private {number} */ this.accessCodeLifetime_ = 0; - /** - * @type {string} - * @private - */ + /** @private {string} */ this.clientId_ = ''; - /** - * @type {boolean} - * @private - */ + /** @private {boolean} */ this.initialized_ = false; + /** @private {base.Disposables} */ + this.eventHooks_ = null; + /** * @type {?function():void} * @private @@ -85,6 +73,15 @@ this.onNatPolicyChanged_ = function() {}; }; +remoting.It2MeHostFacade.prototype.dispose = function() { + base.dispose(this.eventHooks_); + this.eventHooks_ = null; + if (this.port_) { + this.port_.disconnect(); + this.port_ = null; + } +}; + /** * Sets up connection to the Native Messaging host process and exchanges * 'hello' messages. If Native Messaging is not supported or if the it2me @@ -105,8 +102,11 @@ try { this.port_ = chrome.runtime.connectNative( 'com.google.chrome.remote_assistance'); - this.port_.onMessage.addListener(this.onIncomingMessage_.bind(this)); - this.port_.onDisconnect.addListener(this.onHostDisconnect_.bind(this)); + this.eventHooks_ = new base.Disposables( + new base.ChromeEventHook(this.port_.onMessage, + this.onIncomingMessage_.bind(this)), + new base.ChromeEventHook(this.port_.onDisconnect, + this.onHostDisconnect_.bind(this))); this.port_.postMessage({type: 'hello'}); } catch (/** @type {*} */ err) { console.log('Native Messaging initialization failed: ', err); @@ -328,4 +328,6 @@ this.port_ = null; this.onError_(remoting.Error.UNEXPECTED); } -} +}; + +})();
diff --git a/remoting/webapp/crd/js/it2me_service.js b/remoting/webapp/crd/js/it2me_service.js index 6d2d3557..d705f5b7f 100644 --- a/remoting/webapp/crd/js/it2me_service.js +++ b/remoting/webapp/crd/js/it2me_service.js
@@ -16,7 +16,9 @@ /** * @param {remoting.AppLauncher} appLauncher + * * @constructor + * @implements {base.Disposable} */ remoting.It2MeService = function(appLauncher) { /**
diff --git a/remoting/webapp/crd/manifest.json.jinja2 b/remoting/webapp/crd/manifest.json.jinja2 index d0b1ccd3..2e71a42 100644 --- a/remoting/webapp/crd/manifest.json.jinja2 +++ b/remoting/webapp/crd/manifest.json.jinja2
@@ -62,7 +62,7 @@ {% endif %} "externally_connectable": { "matches": [ - "https://*.talkgadget.google.com/*" + "https://*.google.com/hangouts*" ] }, "permissions": [
diff --git a/remoting/webapp/crd/remoting_client_pnacl.nmf b/remoting/webapp/crd/remoting_client_pnacl.nmf deleted file mode 100644 index 8181c0a0..0000000 --- a/remoting/webapp/crd/remoting_client_pnacl.nmf +++ /dev/null
@@ -1,10 +0,0 @@ -{ - "program": { - "portable": { - "pnacl-translate": { - "url": "remoting_client_plugin_newlib.pexe", - "optlevel": 2 - } - } - } -}
diff --git a/remoting/webapp/crd/remoting_client_pnacl.nmf.jinja2 b/remoting/webapp/crd/remoting_client_pnacl.nmf.jinja2 new file mode 100644 index 0000000..ef5ae50 --- /dev/null +++ b/remoting/webapp/crd/remoting_client_pnacl.nmf.jinja2
@@ -0,0 +1,16 @@ +{ + "program": { + "portable": { + "pnacl-translate": { + "url": "remoting_client_plugin_newlib.pexe", + "optlevel": 2 + } +{% if buildtype == 'Dev' %} + , "pnacl-debug": { + "url": "remoting_client_plugin_newlib.pexe.debug", + "optlevel": 0 + } +{% endif %} + } + } +}
diff --git a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js index 3a8cb962..9c66b49 100644 --- a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js +++ b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js
@@ -47,6 +47,11 @@ // remoting.settings remoting.settings = new remoting.Settings(); + remoting.identity = new remoting.Identity(); + }, + tearDown: function() { + remoting.settings = null; + remoting.identity = null; } }); @@ -112,19 +117,6 @@ sinon.assert.called(hostInstaller.download); }); -test('connect() should return error if email is missing', - function() { - var MessageTypes = remoting.It2MeHelpeeChannel.HangoutMessageTypes; - - hangoutPort.onMessage.mock$fire({ - method: MessageTypes.CONNECT - }); - - sinon.assert.calledWithMatch(hangoutPort.postMessage, { - method: MessageTypes.ERROR - }); -}); - QUnit.asyncTest('connect() should return access code', function() { // Stubs authentication. @@ -136,6 +128,10 @@ }); sinon.stub(chrome.identity, 'getAuthToken') .callsArgWith(1, 'token'); + sinon.stub(remoting.identity, 'callWithToken') + .callsArgWith(0, 'token'); + sinon.stub(remoting.identity, 'getEmail') + .callsArgWith(0, {token: 'token', email: 'test@chromium.org'}); // Stubs Host behavior. sinon.stub(host, 'initialized').returns(true); sinon.stub(host, 'connect') @@ -145,7 +141,6 @@ var MessageTypes = remoting.It2MeHelpeeChannel.HangoutMessageTypes; hangoutPort.onMessage.mock$fire({ method: MessageTypes.CONNECT, - email: 'test@chromium.org', hangoutBounds: {widht: 10, height: 10, left:10, top: 10} });
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn index 96df5fd..64940f1 100644 --- a/sandbox/linux/BUILD.gn +++ b/sandbox/linux/BUILD.gn
@@ -94,20 +94,23 @@ } if (compile_suid_client) { - sources += [ "suid/client/setuid_sandbox_client_unittest.cc" ] + sources += [ + "suid/client/setuid_sandbox_client_unittest.cc", + "suid/client/setuid_sandbox_host_unittest.cc", + ] } if (use_seccomp_bpf) { sources += [ "bpf_dsl/bpf_dsl_more_unittest.cc", "bpf_dsl/bpf_dsl_unittest.cc", + "bpf_dsl/codegen_unittest.cc", "bpf_dsl/cons_unittest.cc", + "bpf_dsl/syscall_set_unittest.cc", "seccomp-bpf-helpers/baseline_policy_unittest.cc", "seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc", "seccomp-bpf/bpf_tests_unittest.cc", - "seccomp-bpf/codegen_unittest.cc", "seccomp-bpf/errorcode_unittest.cc", "seccomp-bpf/sandbox_bpf_unittest.cc", - "seccomp-bpf/syscall_iterator_unittest.cc", "seccomp-bpf/syscall_unittest.cc", ] } @@ -146,6 +149,8 @@ "bpf_dsl/bpf_dsl.h", "bpf_dsl/bpf_dsl_forward.h", "bpf_dsl/bpf_dsl_impl.h", + "bpf_dsl/codegen.cc", + "bpf_dsl/codegen.h", "bpf_dsl/cons.h", "bpf_dsl/dump_bpf.cc", "bpf_dsl/dump_bpf.h", @@ -153,9 +158,9 @@ "bpf_dsl/policy.h", "bpf_dsl/policy_compiler.cc", "bpf_dsl/policy_compiler.h", + "bpf_dsl/syscall_set.cc", + "bpf_dsl/syscall_set.h", "bpf_dsl/trap_registry.h", - "seccomp-bpf/codegen.cc", - "seccomp-bpf/codegen.h", "seccomp-bpf/die.cc", "seccomp-bpf/die.h", "seccomp-bpf/errorcode.cc", @@ -165,8 +170,6 @@ "seccomp-bpf/sandbox_bpf.h", "seccomp-bpf/syscall.cc", "seccomp-bpf/syscall.h", - "seccomp-bpf/syscall_iterator.cc", - "seccomp-bpf/syscall_iterator.h", "seccomp-bpf/trap.cc", "seccomp-bpf/trap.h", "seccomp-bpf/verifier.cc", @@ -306,6 +309,8 @@ "suid/common/suid_unsafe_environment_variables.h", "suid/client/setuid_sandbox_client.cc", "suid/client/setuid_sandbox_client.h", + "suid/client/setuid_sandbox_host.cc", + "suid/client/setuid_sandbox_host.h", ] defines = [ "SANDBOX_IMPLEMENTATION" ]
diff --git a/sandbox/linux/seccomp-bpf/codegen.cc b/sandbox/linux/bpf_dsl/codegen.cc similarity index 98% rename from sandbox/linux/seccomp-bpf/codegen.cc rename to sandbox/linux/bpf_dsl/codegen.cc index 055aa71..793d95d 100644 --- a/sandbox/linux/seccomp-bpf/codegen.cc +++ b/sandbox/linux/bpf_dsl/codegen.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include <linux/filter.h>
diff --git a/sandbox/linux/seccomp-bpf/codegen.h b/sandbox/linux/bpf_dsl/codegen.h similarity index 96% rename from sandbox/linux/seccomp-bpf/codegen.h rename to sandbox/linux/bpf_dsl/codegen.h index ef04a5d..c2e1f937 100644 --- a/sandbox/linux/seccomp-bpf/codegen.h +++ b/sandbox/linux/bpf_dsl/codegen.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_LINUX_SECCOMP_BPF_CODEGEN_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_CODEGEN_H__ +#ifndef SANDBOX_LINUX_BPF_DSL_CODEGEN_H__ +#define SANDBOX_LINUX_BPF_DSL_CODEGEN_H__ #include <stddef.h> #include <stdint.h> @@ -120,4 +120,4 @@ } // namespace sandbox -#endif // SANDBOX_LINUX_SECCOMP_BPF_CODEGEN_H__ +#endif // SANDBOX_LINUX_BPF_DSL_CODEGEN_H__
diff --git a/sandbox/linux/seccomp-bpf/codegen_unittest.cc b/sandbox/linux/bpf_dsl/codegen_unittest.cc similarity index 99% rename from sandbox/linux/seccomp-bpf/codegen_unittest.cc rename to sandbox/linux/bpf_dsl/codegen_unittest.cc index 8d4bf5d..3abfc85a 100644 --- a/sandbox/linux/seccomp-bpf/codegen_unittest.cc +++ b/sandbox/linux/bpf_dsl/codegen_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include <linux/filter.h>
diff --git a/sandbox/linux/bpf_dsl/dump_bpf.cc b/sandbox/linux/bpf_dsl/dump_bpf.cc index ddbcd0e..5cf53ff 100644 --- a/sandbox/linux/bpf_dsl/dump_bpf.cc +++ b/sandbox/linux/bpf_dsl/dump_bpf.cc
@@ -6,8 +6,8 @@ #include <stdio.h> +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/linux/seccomp-bpf/codegen.h" #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" namespace sandbox {
diff --git a/sandbox/linux/bpf_dsl/dump_bpf.h b/sandbox/linux/bpf_dsl/dump_bpf.h index ce260f87..cd12be7 100644 --- a/sandbox/linux/bpf_dsl/dump_bpf.h +++ b/sandbox/linux/bpf_dsl/dump_bpf.h
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/sandbox_export.h" namespace sandbox {
diff --git a/sandbox/linux/bpf_dsl/policy_compiler.cc b/sandbox/linux/bpf_dsl/policy_compiler.cc index f91f70c..2b72f3b 100644 --- a/sandbox/linux/bpf_dsl/policy_compiler.cc +++ b/sandbox/linux/bpf_dsl/policy_compiler.cc
@@ -14,13 +14,13 @@ #include "base/macros.h" #include "sandbox/linux/bpf_dsl/bpf_dsl.h" #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/syscall_set.h" #include "sandbox/linux/seccomp-bpf/die.h" #include "sandbox/linux/seccomp-bpf/errorcode.h" #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" #include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" namespace sandbox { namespace bpf_dsl {
diff --git a/sandbox/linux/bpf_dsl/policy_compiler.h b/sandbox/linux/bpf_dsl/policy_compiler.h index 8737c42..faf6be5 100644 --- a/sandbox/linux/bpf_dsl/policy_compiler.h +++ b/sandbox/linux/bpf_dsl/policy_compiler.h
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/linux/seccomp-bpf/errorcode.h" #include "sandbox/sandbox_export.h"
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.cc b/sandbox/linux/bpf_dsl/syscall_set.cc similarity index 97% rename from sandbox/linux/seccomp-bpf/syscall_iterator.cc rename to sandbox/linux/bpf_dsl/syscall_set.cc index 195a8b0a..22d6046 100644 --- a/sandbox/linux/seccomp-bpf/syscall_iterator.cc +++ b/sandbox/linux/bpf_dsl/syscall_set.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" +#include "sandbox/linux/bpf_dsl/syscall_set.h" #include "base/logging.h" #include "base/macros.h"
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.h b/sandbox/linux/bpf_dsl/syscall_set.h similarity index 92% rename from sandbox/linux/seccomp-bpf/syscall_iterator.h rename to sandbox/linux/bpf_dsl/syscall_set.h index 5080fcc..b9f076d 100644 --- a/sandbox/linux/seccomp-bpf/syscall_iterator.h +++ b/sandbox/linux/bpf_dsl/syscall_set.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_ITERATOR_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_ITERATOR_H__ +#ifndef SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ +#define SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ #include <stdint.h> @@ -14,8 +14,6 @@ namespace sandbox { -// TODO(mdempsky): Rename this header to syscall_set.h. - // Iterates over the entire system call range from 0..0xFFFFFFFFu. This // iterator is aware of how system calls look like and will skip quickly // over ranges that can't contain system calls. It iterates more slowly @@ -102,4 +100,4 @@ } // namespace sandbox -#endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_ITERATOR_H__ +#endif // SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc b/sandbox/linux/bpf_dsl/syscall_set_unittest.cc similarity index 87% rename from sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc rename to sandbox/linux/bpf_dsl/syscall_set_unittest.cc index 3bc1eaa5..5730dc45 100644 --- a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc +++ b/sandbox/linux/bpf_dsl/syscall_set_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" +#include "sandbox/linux/bpf_dsl/syscall_set.h" #include <stdint.h> @@ -18,7 +18,7 @@ SyscallSet::InvalidOnly(), }; -SANDBOX_TEST(SyscallIterator, Monotonous) { +SANDBOX_TEST(SyscallSet, Monotonous) { for (const SyscallSet& set : kSyscallSets) { uint32_t prev = 0; bool have_prev = false; @@ -54,7 +54,7 @@ SANDBOX_ASSERT(prev == max); } -SANDBOX_TEST(SyscallIterator, ValidSyscallRanges) { +SANDBOX_TEST(SyscallSet, ValidSyscallRanges) { AssertRange(MIN_SYSCALL, MAX_PUBLIC_SYSCALL); #if defined(__arm__) AssertRange(MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL); @@ -62,7 +62,7 @@ #endif } -SANDBOX_TEST(SyscallIterator, InvalidSyscalls) { +SANDBOX_TEST(SyscallSet, InvalidSyscalls) { static const uint32_t kExpected[] = { #if defined(__mips__) 0, @@ -93,19 +93,19 @@ } } -SANDBOX_TEST(SyscallIterator, ValidOnlyIsOnlyValid) { +SANDBOX_TEST(SyscallSet, ValidOnlyIsOnlyValid) { for (uint32_t sysnum : SyscallSet::ValidOnly()) { SANDBOX_ASSERT(SyscallSet::IsValid(sysnum)); } } -SANDBOX_TEST(SyscallIterator, InvalidOnlyIsOnlyInvalid) { +SANDBOX_TEST(SyscallSet, InvalidOnlyIsOnlyInvalid) { for (uint32_t sysnum : SyscallSet::InvalidOnly()) { SANDBOX_ASSERT(!SyscallSet::IsValid(sysnum)); } } -SANDBOX_TEST(SyscallIterator, AllIsValidOnlyPlusInvalidOnly) { +SANDBOX_TEST(SyscallSet, AllIsValidOnlyPlusInvalidOnly) { std::vector<uint32_t> merged; const SyscallSet valid_only = SyscallSet::ValidOnly(); const SyscallSet invalid_only = SyscallSet::InvalidOnly();
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi index 15bd71c..c03b024e 100644 --- a/sandbox/linux/sandbox_linux.gypi +++ b/sandbox/linux/sandbox_linux.gypi
@@ -122,6 +122,8 @@ 'bpf_dsl/bpf_dsl.h', 'bpf_dsl/bpf_dsl_forward.h', 'bpf_dsl/bpf_dsl_impl.h', + 'bpf_dsl/codegen.cc', + 'bpf_dsl/codegen.h', 'bpf_dsl/cons.h', 'bpf_dsl/dump_bpf.cc', 'bpf_dsl/dump_bpf.h', @@ -129,9 +131,9 @@ 'bpf_dsl/policy.h', 'bpf_dsl/policy_compiler.cc', 'bpf_dsl/policy_compiler.h', + 'bpf_dsl/syscall_set.cc', + 'bpf_dsl/syscall_set.h', 'bpf_dsl/trap_registry.h', - 'seccomp-bpf/codegen.cc', - 'seccomp-bpf/codegen.h', 'seccomp-bpf/die.cc', 'seccomp-bpf/die.h', 'seccomp-bpf/errorcode.cc', @@ -141,8 +143,6 @@ 'seccomp-bpf/sandbox_bpf.h', 'seccomp-bpf/syscall.cc', 'seccomp-bpf/syscall.h', - 'seccomp-bpf/syscall_iterator.cc', - 'seccomp-bpf/syscall_iterator.h', 'seccomp-bpf/trap.cc', 'seccomp-bpf/trap.h', 'seccomp-bpf/verifier.cc', @@ -315,6 +315,8 @@ 'suid/common/suid_unsafe_environment_variables.h', 'suid/client/setuid_sandbox_client.cc', 'suid/client/setuid_sandbox_client.h', + 'suid/client/setuid_sandbox_host.cc', + 'suid/client/setuid_sandbox_host.h', ], 'defines': [ 'SANDBOX_IMPLEMENTATION',
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi index 61517cc5..eef29db 100644 --- a/sandbox/linux/sandbox_linux_test_sources.gypi +++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -34,20 +34,21 @@ [ 'compile_suid_client==1', { 'sources': [ 'suid/client/setuid_sandbox_client_unittest.cc', + 'suid/client/setuid_sandbox_host_unittest.cc', ], }], [ 'use_seccomp_bpf==1', { 'sources': [ 'bpf_dsl/bpf_dsl_more_unittest.cc', 'bpf_dsl/bpf_dsl_unittest.cc', + 'bpf_dsl/codegen_unittest.cc', 'bpf_dsl/cons_unittest.cc', + 'bpf_dsl/syscall_set_unittest.cc', 'seccomp-bpf-helpers/baseline_policy_unittest.cc', 'seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc', 'seccomp-bpf/bpf_tests_unittest.cc', - 'seccomp-bpf/codegen_unittest.cc', 'seccomp-bpf/errorcode_unittest.cc', 'seccomp-bpf/sandbox_bpf_unittest.cc', - 'seccomp-bpf/syscall_iterator_unittest.cc', 'seccomp-bpf/syscall_unittest.cc', ], }],
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc index 555f672..d51fa781 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -23,15 +23,15 @@ #include "base/memory/scoped_ptr.h" #include "base/posix/eintr_wrapper.h" #include "base/third_party/valgrind/valgrind.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/linux/bpf_dsl/dump_bpf.h" #include "sandbox/linux/bpf_dsl/policy.h" #include "sandbox/linux/bpf_dsl/policy_compiler.h" -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/syscall_set.h" #include "sandbox/linux/seccomp-bpf/die.h" #include "sandbox/linux/seccomp-bpf/errorcode.h" #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" #include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" #include "sandbox/linux/seccomp-bpf/trap.h" #include "sandbox/linux/seccomp-bpf/verifier.h" #include "sandbox/linux/services/linux_syscalls.h"
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h index 1a9c1f8..e46889b 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -10,7 +10,7 @@ #include "base/files/scoped_file.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "sandbox/linux/seccomp-bpf/codegen.h" +#include "sandbox/linux/bpf_dsl/codegen.h" #include "sandbox/sandbox_export.h" namespace sandbox {
diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc index 548df25..68fca882e 100644 --- a/sandbox/linux/seccomp-bpf/verifier.cc +++ b/sandbox/linux/seccomp-bpf/verifier.cc
@@ -12,10 +12,10 @@ #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" #include "sandbox/linux/bpf_dsl/policy.h" #include "sandbox/linux/bpf_dsl/policy_compiler.h" +#include "sandbox/linux/bpf_dsl/syscall_set.h" #include "sandbox/linux/seccomp-bpf/errorcode.h" #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" namespace sandbox {
diff --git a/sandbox/linux/services/namespace_sandbox.cc b/sandbox/linux/services/namespace_sandbox.cc index 559b93c..d5856882e 100644 --- a/sandbox/linux/services/namespace_sandbox.cc +++ b/sandbox/linux/services/namespace_sandbox.cc
@@ -11,6 +11,7 @@ #include <string> #include <utility> +#include <vector> #include "base/command_line.h" #include "base/environment.h" @@ -59,6 +60,13 @@ base::Process NamespaceSandbox::LaunchProcess( const base::CommandLine& cmdline, const base::LaunchOptions& options) { + return LaunchProcess(cmdline.argv(), options); +} + +// static +base::Process NamespaceSandbox::LaunchProcess( + const std::vector<std::string>& argv, + const base::LaunchOptions& options) { int clone_flags = 0; int ns_types[] = {CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET}; for (const int ns_type : ns_types) { @@ -91,7 +99,7 @@ SetEnvironForNamespaceType(environ, environ_name, clone_flags & flag); } - return base::LaunchProcess(cmdline, launch_options); + return base::LaunchProcess(argv, launch_options); } // static
diff --git a/sandbox/linux/services/namespace_sandbox.h b/sandbox/linux/services/namespace_sandbox.h index ddc4dee..b92f581 100644 --- a/sandbox/linux/services/namespace_sandbox.h +++ b/sandbox/linux/services/namespace_sandbox.h
@@ -5,6 +5,9 @@ #ifndef SANDBOX_LINUX_SERVICES_NAMESPACE_SANDBOX_H_ #define SANDBOX_LINUX_SERVICES_NAMESPACE_SANDBOX_H_ +#include <string> +#include <vector> + #include "base/command_line.h" #include "base/macros.h" #include "base/process/launch.h" @@ -41,6 +44,8 @@ // overrides them. static base::Process LaunchProcess(const base::CommandLine& cmdline, const base::LaunchOptions& options); + static base::Process LaunchProcess(const std::vector<std::string>& argv, + const base::LaunchOptions& options); // Returns whether the namespace sandbox created a new user, PID, and network // namespace. In particular, InNewUserNamespace should return true iff the
diff --git a/sandbox/linux/services/unix_domain_socket_unittest.cc b/sandbox/linux/services/unix_domain_socket_unittest.cc index 4d57c0d..dafa91d 100644 --- a/sandbox/linux/services/unix_domain_socket_unittest.cc +++ b/sandbox/linux/services/unix_domain_socket_unittest.cc
@@ -17,7 +17,7 @@ #include "base/memory/scoped_vector.h" #include "base/posix/eintr_wrapper.h" #include "base/posix/unix_domain_socket_linux.h" -#include "base/process/process_handle.h" +#include "base/process/process.h" #include "sandbox/linux/services/syscall_wrappers.h" #include "sandbox/linux/tests/unit_tests.h" @@ -57,10 +57,9 @@ // base::GetParentProcessId() is defined as taking a ProcessHandle instead of // a ProcessId, even though it's a POSIX-only function and IDs and Handles // are both simply pid_t on POSIX... :/ - base::ProcessHandle handle; - CHECK(base::OpenProcessHandle(pid, &handle)); - base::ProcessId ret = base::GetParentProcessId(pid); - base::CloseProcessHandle(handle); + base::Process process = base::Process::Open(pid); + CHECK(process.IsValid()); + base::ProcessId ret = base::GetParentProcessId(process.Handle()); return ret; }
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc index 9eb538a..12ef7f9f 100644 --- a/sandbox/linux/suid/client/setuid_sandbox_client.cc +++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -5,94 +5,24 @@ #include "sandbox/linux/suid/client/setuid_sandbox_client.h" #include <fcntl.h> -#include <stdlib.h> -#include <sys/socket.h> #include <sys/stat.h> -#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> -#include "base/command_line.h" +#include <string> + #include "base/environment.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" #include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "base/process/process_metrics.h" #include "base/strings/string_number_conversions.h" -#include "sandbox/linux/services/init_process_reaper.h" #include "sandbox/linux/suid/common/sandbox.h" -#include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h" namespace { bool IsFileSystemAccessDenied() { - base::ScopedFD self_exe(HANDLE_EINTR(open("/", O_RDONLY))); - return !self_exe.is_valid(); -} - -// Set an environment variable that reflects the API version we expect from the -// setuid sandbox. Old versions of the sandbox will ignore this. -void SetSandboxAPIEnvironmentVariable(base::Environment* env) { - env->SetVar(sandbox::kSandboxEnvironmentApiRequest, - base::IntToString(sandbox::kSUIDSandboxApiNumber)); -} - -// Unset environment variables that are expected to be set by the setuid -// sandbox. This is to allow nesting of one instance of the SUID sandbox -// inside another. -void UnsetExpectedEnvironmentVariables(base::EnvironmentMap* env_map) { - DCHECK(env_map); - const base::NativeEnvironmentString environment_vars[] = { - sandbox::kSandboxDescriptorEnvironmentVarName, - sandbox::kSandboxHelperPidEnvironmentVarName, - sandbox::kSandboxEnvironmentApiProvides, - sandbox::kSandboxPIDNSEnvironmentVarName, - sandbox::kSandboxNETNSEnvironmentVarName, - }; - - for (size_t i = 0; i < arraysize(environment_vars); ++i) { - // Setting values in EnvironmentMap to an empty-string will make - // sure that they get unset from the environment via AlterEnvironment(). - (*env_map)[environment_vars[i]] = base::NativeEnvironmentString(); - } -} - -// Wrapper around a shared C function. -// Returns the "saved" environment variable name corresponding to |envvar| -// in a new string or NULL. -std::string* CreateSavedVariableName(const char* env_var) { - char* const saved_env_var = SandboxSavedEnvironmentVariable(env_var); - if (!saved_env_var) - return NULL; - std::string* saved_env_var_copy = new std::string(saved_env_var); - // SandboxSavedEnvironmentVariable is the C function that we wrap and uses - // malloc() to allocate memory. - free(saved_env_var); - return saved_env_var_copy; -} - -// The ELF loader will clear many environment variables so we save them to -// different names here so that the SUID sandbox can resolve them for the -// renderer. -void SaveSUIDUnsafeEnvironmentVariables(base::Environment* env) { - for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) { - const char* env_var = kSUIDUnsafeEnvironmentVariables[i]; - // Get the saved environment variable corresponding to envvar. - scoped_ptr<std::string> saved_env_var(CreateSavedVariableName(env_var)); - if (saved_env_var == NULL) - continue; - - std::string value; - if (env->GetVar(env_var, &value)) - env->SetVar(saved_env_var->c_str(), value); - else - env->UnSetVar(saved_env_var->c_str()); - } + base::ScopedFD root_dir(HANDLE_EINTR(open("/", O_RDONLY))); + return !root_dir.is_valid(); } int GetHelperApi(base::Environment* env) { @@ -127,30 +57,21 @@ return EnvToInt(env, sandbox::kSandboxDescriptorEnvironmentVarName); } -const char* GetDevelSandboxPath() { - return getenv("CHROME_DEVEL_SANDBOX"); -} - } // namespace namespace sandbox { SetuidSandboxClient* SetuidSandboxClient::Create() { base::Environment* environment(base::Environment::Create()); - SetuidSandboxClient* sandbox_client(new SetuidSandboxClient); - CHECK(environment); - sandbox_client->env_ = environment; - return sandbox_client; + return new SetuidSandboxClient(environment); } -SetuidSandboxClient::SetuidSandboxClient() - : env_(NULL), - sandboxed_(false) { +SetuidSandboxClient::SetuidSandboxClient(base::Environment* env) + : env_(env), sandboxed_(false) { } SetuidSandboxClient::~SetuidSandboxClient() { - delete env_; } void SetuidSandboxClient::CloseDummyFile() { @@ -169,7 +90,7 @@ } bool SetuidSandboxClient::ChrootMe() { - int ipc_fd = GetIPCDescriptor(env_); + int ipc_fd = GetIPCDescriptor(env_.get()); if (ipc_fd < 0) { LOG(ERROR) << "Failed to obtain the sandbox IPC descriptor"; @@ -182,7 +103,7 @@ } // We need to reap the chroot helper process in any event. - pid_t helper_pid = GetHelperPID(env_); + pid_t helper_pid = GetHelperPID(env_.get()); // If helper_pid is -1 we wait for any child. if (HANDLE_EINTR(waitpid(helper_pid, NULL, 0)) < 0) { PLOG(ERROR) << "Failed to wait for setuid helper to die"; @@ -208,11 +129,11 @@ } bool SetuidSandboxClient::IsSuidSandboxUpToDate() const { - return GetHelperApi(env_) == kSUIDSandboxApiNumber; + return GetHelperApi(env_.get()) == kSUIDSandboxApiNumber; } bool SetuidSandboxClient::IsSuidSandboxChild() const { - return GetIPCDescriptor(env_) >= 0; + return GetIPCDescriptor(env_.get()) >= 0; } bool SetuidSandboxClient::IsInNewPIDNamespace() const { @@ -227,87 +148,4 @@ return sandboxed_; } -// Check if CHROME_DEVEL_SANDBOX is set but empty. This currently disables -// the setuid sandbox. TODO(jln): fix this (crbug.com/245376). -bool SetuidSandboxClient::IsDisabledViaEnvironment() { - const char* devel_sandbox_path = GetDevelSandboxPath(); - if (devel_sandbox_path && '\0' == *devel_sandbox_path) { - return true; - } - return false; -} - -base::FilePath SetuidSandboxClient::GetSandboxBinaryPath() { - base::FilePath sandbox_binary; - base::FilePath exe_dir; - if (PathService::Get(base::DIR_EXE, &exe_dir)) { - base::FilePath sandbox_candidate = exe_dir.AppendASCII("chrome-sandbox"); - if (base::PathExists(sandbox_candidate)) - sandbox_binary = sandbox_candidate; - } - - // In user-managed builds, including development builds, an environment - // variable is required to enable the sandbox. See - // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment - struct stat st; - if (sandbox_binary.empty() && stat(base::kProcSelfExe, &st) == 0 && - st.st_uid == getuid()) { - const char* devel_sandbox_path = GetDevelSandboxPath(); - if (devel_sandbox_path) { - sandbox_binary = base::FilePath(devel_sandbox_path); - } - } - - return sandbox_binary; -} - -void SetuidSandboxClient::PrependWrapper(base::CommandLine* cmd_line) { - std::string sandbox_binary(GetSandboxBinaryPath().value()); - struct stat st; - if (sandbox_binary.empty() || stat(sandbox_binary.c_str(), &st) != 0) { - LOG(FATAL) << "The SUID sandbox helper binary is missing: " - << sandbox_binary << " Aborting now. See " - "https://code.google.com/p/chromium/wiki/" - "LinuxSUIDSandboxDevelopment."; - } - - if (access(sandbox_binary.c_str(), X_OK) != 0 || (st.st_uid != 0) || - ((st.st_mode & S_ISUID) == 0) || ((st.st_mode & S_IXOTH)) == 0) { - LOG(FATAL) << "The SUID sandbox helper binary was found, but is not " - "configured correctly. Rather than run without sandboxing " - "I'm aborting now. You need to make sure that " - << sandbox_binary << " is owned by root and has mode 4755."; - } - - cmd_line->PrependWrapper(sandbox_binary); -} - -void SetuidSandboxClient::SetupLaunchOptions( - base::LaunchOptions* options, - base::FileHandleMappingVector* fds_to_remap, - base::ScopedFD* dummy_fd) { - DCHECK(options); - DCHECK(fds_to_remap); - - // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used. - options->allow_new_privs = true; - UnsetExpectedEnvironmentVariables(&options->environ); - - // Set dummy_fd to the reading end of a closed pipe. - int pipe_fds[2]; - PCHECK(0 == pipe(pipe_fds)); - PCHECK(0 == IGNORE_EINTR(close(pipe_fds[1]))); - dummy_fd->reset(pipe_fds[0]); - - // We no longer need a dummy socket for discovering the child's PID, - // but the sandbox is still hard-coded to expect a file descriptor at - // kZygoteIdFd. Fixing this requires a sandbox API change. :( - fds_to_remap->push_back(std::make_pair(dummy_fd->get(), kZygoteIdFd)); -} - -void SetuidSandboxClient::SetupLaunchEnvironment() { - SaveSUIDUnsafeEnvironmentVariables(env_); - SetSandboxAPIEnvironmentVariable(env_); -} - } // namespace sandbox
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h index b24eb4c5f..026894fc 100644 --- a/sandbox/linux/suid/client/setuid_sandbox_client.h +++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -5,29 +5,20 @@ #ifndef SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_ #define SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_ -#include "base/basictypes.h" -#include "base/command_line.h" #include "base/environment.h" -#include "base/files/file_path.h" -#include "base/files/scoped_file.h" -#include "base/process/launch.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "sandbox/sandbox_export.h" namespace sandbox { -// Helper class to use the setuid sandbox. This class is to be used both -// before launching the setuid helper and after being executed through the -// setuid helper. +// Helper class to use the setuid sandbox. This class is to be used +// after being executed through the setuid helper. // This class is difficult to use. It has been created by refactoring very old // code scathered through the Chromium code base. // // A typical use for "A" launching a sandboxed process "B" would be: -// 1. A calls SetupLaunchEnvironment() -// 2. A sets up a CommandLine and then amends it with -// PrependWrapper() (or manually, by relying on GetSandboxBinaryPath()). -// 3. A uses SetupLaunchOptions() to arrange for a dummy descriptor for the -// setuid sandbox ABI. -// 4. A launches B with base::LaunchProcess, using the amended CommandLine. +// (Steps 1 through 4 are described in setuid_sandbox_host.h.) // 5. B uses CloseDummyFile() to close the dummy file descriptor. // 6. B performs various initializations that require access to the file // system. @@ -38,13 +29,13 @@ // cannot receive any signal from any other process, excluding SIGKILL. // If B dies, all the processes in the namespace will die. // B can fork() and the parent can assume the role of init(1), by using -// CreateInitProcessReaper(). +// sandbox::CreateInitProcessReaper(). // 8. B requests being chroot-ed through ChrootMe() and // requests other sandboxing status via the status functions. class SANDBOX_EXPORT SetuidSandboxClient { public: // All instantation should go through this factory method. - static class SetuidSandboxClient* Create(); + static SetuidSandboxClient* Create(); ~SetuidSandboxClient(); // Close the dummy file descriptor leftover from the sandbox ABI. @@ -65,33 +56,11 @@ // Are we done and fully sandboxed ? bool IsSandboxed() const; - // The setuid sandbox may still be disabled via the environment. - // This is tracked in crbug.com/245376. - bool IsDisabledViaEnvironment(); - // Get the sandbox binary path. This method knows about the - // CHROME_DEVEL_SANDBOX environment variable used for user-managed builds. If - // the sandbox binary cannot be found, it will return an empty FilePath. - base::FilePath GetSandboxBinaryPath(); - // Modify |cmd_line| to launch via the setuid sandbox. Crash if the setuid - // sandbox binary cannot be found. |cmd_line| must not be NULL. - void PrependWrapper(base::CommandLine* cmd_line); - // Set-up the launch options for launching via the setuid sandbox. Caller is - // responsible for keeping |dummy_fd| alive until LaunchProcess() completes. - // |options| and |fds_to_remap| must not be NULL. - // (Keeping |dummy_fd| alive is an unfortunate historical artifact of the - // chrome-sandbox ABI.) - void SetupLaunchOptions(base::LaunchOptions* options, - base::FileHandleMappingVector* fds_to_remap, - base::ScopedFD* dummy_fd); - // Set-up the environment. This should be done prior to launching the setuid - // helper. - void SetupLaunchEnvironment(); - private: - SetuidSandboxClient(); + explicit SetuidSandboxClient(base::Environment* env); // Holds the environment. Will never be NULL. - base::Environment* env_; + scoped_ptr<base::Environment> env_; bool sandboxed_; DISALLOW_COPY_AND_ASSIGN(SetuidSandboxClient);
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc b/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc index d4f7dfe..2acd8fb 100644 --- a/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc +++ b/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc
@@ -2,63 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "sandbox/linux/suid/client/setuid_sandbox_client.h" + #include "base/environment.h" -#include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" -#include "sandbox/linux/suid/client/setuid_sandbox_client.h" #include "sandbox/linux/suid/common/sandbox.h" #include "testing/gtest/include/gtest/gtest.h" namespace sandbox { -TEST(SetuidSandboxClient, SetupLaunchEnvironment) { - const char kTestValue[] = "This is a test"; - scoped_ptr<base::Environment> env(base::Environment::Create()); - EXPECT_TRUE(env != NULL); - - std::string saved_ld_preload; - bool environment_had_ld_preload; - // First, back-up the real LD_PRELOAD if any. - environment_had_ld_preload = env->GetVar("LD_PRELOAD", &saved_ld_preload); - // Setup environment variables to save or not save. - EXPECT_TRUE(env->SetVar("LD_PRELOAD", kTestValue)); - EXPECT_TRUE(env->UnSetVar("LD_ORIGIN_PATH")); - - scoped_ptr<SetuidSandboxClient> - sandbox_client(SetuidSandboxClient::Create()); - EXPECT_TRUE(sandbox_client != NULL); - - // Make sure the environment is clean. - EXPECT_TRUE(env->UnSetVar(kSandboxEnvironmentApiRequest)); - EXPECT_TRUE(env->UnSetVar(kSandboxEnvironmentApiProvides)); - - sandbox_client->SetupLaunchEnvironment(); - - // Check if the requested API environment was set. - std::string api_request; - EXPECT_TRUE(env->GetVar(kSandboxEnvironmentApiRequest, &api_request)); - int api_request_num; - EXPECT_TRUE(base::StringToInt(api_request, &api_request_num)); - EXPECT_EQ(api_request_num, kSUIDSandboxApiNumber); - - // Now check if LD_PRELOAD was saved to SANDBOX_LD_PRELOAD. - std::string sandbox_ld_preload; - EXPECT_TRUE(env->GetVar("SANDBOX_LD_PRELOAD", &sandbox_ld_preload)); - EXPECT_EQ(sandbox_ld_preload, kTestValue); - - // Check that LD_ORIGIN_PATH was not saved. - EXPECT_FALSE(env->HasVar("SANDBOX_LD_ORIGIN_PATH")); - - // We should not forget to restore LD_PRELOAD at the end, or this environment - // variable will affect the next running tests! - if (environment_had_ld_preload) { - EXPECT_TRUE(env->SetVar("LD_PRELOAD", saved_ld_preload)); - } else { - EXPECT_TRUE(env->UnSetVar("LD_PRELOAD")); - } -} - TEST(SetuidSandboxClient, SandboxedClientAPI) { scoped_ptr<base::Environment> env(base::Environment::Create()); EXPECT_TRUE(env != NULL); @@ -89,13 +42,5 @@ EXPECT_FALSE(sandbox_client->IsSandboxed()); } -// This test doesn't accomplish much, but will make sure that analysis tools -// will run this codepath. -TEST(SetuidSandboxClient, GetSandboxBinaryPath) { - scoped_ptr<SetuidSandboxClient> setuid_sandbox_client( - SetuidSandboxClient::Create()); - ignore_result(setuid_sandbox_client->GetSandboxBinaryPath()); -} - } // namespace sandbox
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host.cc b/sandbox/linux/suid/client/setuid_sandbox_host.cc new file mode 100644 index 0000000..71171eb --- /dev/null +++ b/sandbox/linux/suid/client/setuid_sandbox_host.cc
@@ -0,0 +1,195 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/linux/suid/client/setuid_sandbox_host.h" + +#include <fcntl.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <string> +#include <utility> + +#include "base/command_line.h" +#include "base/environment.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_file.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "base/posix/eintr_wrapper.h" +#include "base/process/launch.h" +#include "base/process/process_metrics.h" +#include "base/strings/string_number_conversions.h" +#include "sandbox/linux/suid/common/sandbox.h" +#include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h" + +namespace { + +// Set an environment variable that reflects the API version we expect from the +// setuid sandbox. Old versions of the sandbox will ignore this. +void SetSandboxAPIEnvironmentVariable(base::Environment* env) { + env->SetVar(sandbox::kSandboxEnvironmentApiRequest, + base::IntToString(sandbox::kSUIDSandboxApiNumber)); +} + +// Unset environment variables that are expected to be set by the setuid +// sandbox. This is to allow nesting of one instance of the SUID sandbox +// inside another. +void UnsetExpectedEnvironmentVariables(base::EnvironmentMap* env_map) { + DCHECK(env_map); + const base::NativeEnvironmentString environment_vars[] = { + sandbox::kSandboxDescriptorEnvironmentVarName, + sandbox::kSandboxHelperPidEnvironmentVarName, + sandbox::kSandboxEnvironmentApiProvides, + sandbox::kSandboxPIDNSEnvironmentVarName, + sandbox::kSandboxNETNSEnvironmentVarName, + }; + + for (size_t i = 0; i < arraysize(environment_vars); ++i) { + // Setting values in EnvironmentMap to an empty-string will make + // sure that they get unset from the environment via AlterEnvironment(). + (*env_map)[environment_vars[i]] = base::NativeEnvironmentString(); + } +} + +// Wrapper around a shared C function. +// Returns the "saved" environment variable name corresponding to |envvar| +// in a new string or NULL. +std::string* CreateSavedVariableName(const char* env_var) { + char* const saved_env_var = SandboxSavedEnvironmentVariable(env_var); + if (!saved_env_var) + return NULL; + std::string* saved_env_var_copy = new std::string(saved_env_var); + // SandboxSavedEnvironmentVariable is the C function that we wrap and uses + // malloc() to allocate memory. + free(saved_env_var); + return saved_env_var_copy; +} + +// The ELF loader will clear many environment variables so we save them to +// different names here so that the SUID sandbox can resolve them for the +// renderer. +void SaveSUIDUnsafeEnvironmentVariables(base::Environment* env) { + for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) { + const char* env_var = kSUIDUnsafeEnvironmentVariables[i]; + // Get the saved environment variable corresponding to envvar. + scoped_ptr<std::string> saved_env_var(CreateSavedVariableName(env_var)); + if (saved_env_var == NULL) + continue; + + std::string value; + if (env->GetVar(env_var, &value)) + env->SetVar(saved_env_var->c_str(), value); + else + env->UnSetVar(saved_env_var->c_str()); + } +} + +const char* GetDevelSandboxPath() { + return getenv("CHROME_DEVEL_SANDBOX"); +} + +} // namespace + +namespace sandbox { + +SetuidSandboxHost* SetuidSandboxHost::Create() { + base::Environment* environment(base::Environment::Create()); + CHECK(environment); + return new SetuidSandboxHost(environment); +} + +SetuidSandboxHost::SetuidSandboxHost(base::Environment* env) : env_(env) { +} + +SetuidSandboxHost::~SetuidSandboxHost() { +} + +// Check if CHROME_DEVEL_SANDBOX is set but empty. This currently disables +// the setuid sandbox. TODO(jln): fix this (crbug.com/245376). +bool SetuidSandboxHost::IsDisabledViaEnvironment() { + const char* devel_sandbox_path = GetDevelSandboxPath(); + if (devel_sandbox_path && '\0' == *devel_sandbox_path) { + return true; + } + return false; +} + +base::FilePath SetuidSandboxHost::GetSandboxBinaryPath() { + base::FilePath sandbox_binary; + base::FilePath exe_dir; + if (PathService::Get(base::DIR_EXE, &exe_dir)) { + base::FilePath sandbox_candidate = exe_dir.AppendASCII("chrome-sandbox"); + if (base::PathExists(sandbox_candidate)) + sandbox_binary = sandbox_candidate; + } + + // In user-managed builds, including development builds, an environment + // variable is required to enable the sandbox. See + // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment + struct stat st; + if (sandbox_binary.empty() && stat(base::kProcSelfExe, &st) == 0 && + st.st_uid == getuid()) { + const char* devel_sandbox_path = GetDevelSandboxPath(); + if (devel_sandbox_path) { + sandbox_binary = base::FilePath(devel_sandbox_path); + } + } + + return sandbox_binary; +} + +void SetuidSandboxHost::PrependWrapper(base::CommandLine* cmd_line) { + std::string sandbox_binary(GetSandboxBinaryPath().value()); + struct stat st; + if (sandbox_binary.empty() || stat(sandbox_binary.c_str(), &st) != 0) { + LOG(FATAL) << "The SUID sandbox helper binary is missing: " + << sandbox_binary << " Aborting now. See " + "https://code.google.com/p/chromium/wiki/" + "LinuxSUIDSandboxDevelopment."; + } + + if (access(sandbox_binary.c_str(), X_OK) != 0 || (st.st_uid != 0) || + ((st.st_mode & S_ISUID) == 0) || ((st.st_mode & S_IXOTH)) == 0) { + LOG(FATAL) << "The SUID sandbox helper binary was found, but is not " + "configured correctly. Rather than run without sandboxing " + "I'm aborting now. You need to make sure that " + << sandbox_binary << " is owned by root and has mode 4755."; + } + + cmd_line->PrependWrapper(sandbox_binary); +} + +void SetuidSandboxHost::SetupLaunchOptions( + base::LaunchOptions* options, + base::FileHandleMappingVector* fds_to_remap, + base::ScopedFD* dummy_fd) { + DCHECK(options); + DCHECK(fds_to_remap); + + // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used. + options->allow_new_privs = true; + UnsetExpectedEnvironmentVariables(&options->environ); + + // Set dummy_fd to the reading end of a closed pipe. + int pipe_fds[2]; + PCHECK(0 == pipe(pipe_fds)); + PCHECK(0 == IGNORE_EINTR(close(pipe_fds[1]))); + dummy_fd->reset(pipe_fds[0]); + + // We no longer need a dummy socket for discovering the child's PID, + // but the sandbox is still hard-coded to expect a file descriptor at + // kZygoteIdFd. Fixing this requires a sandbox API change. :( + fds_to_remap->push_back(std::make_pair(dummy_fd->get(), kZygoteIdFd)); +} + +void SetuidSandboxHost::SetupLaunchEnvironment() { + SaveSUIDUnsafeEnvironmentVariables(env_.get()); + SetSandboxAPIEnvironmentVariable(env_.get()); +} + +} // namespace sandbox
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host.h b/sandbox/linux/suid/client/setuid_sandbox_host.h new file mode 100644 index 0000000..67888924 --- /dev/null +++ b/sandbox/linux/suid/client/setuid_sandbox_host.h
@@ -0,0 +1,70 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_LINUX_SUID_SETUID_SANDBOX_HOST_H_ +#define SANDBOX_LINUX_SUID_SETUID_SANDBOX_HOST_H_ + +#include "base/files/file_path.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/process/launch.h" +#include "sandbox/sandbox_export.h" + +namespace sandbox { + +// Helper class to use the setuid sandbox. This class is to be used +// before launching the setuid helper. +// This class is difficult to use. It has been created by refactoring very old +// code scathered through the Chromium code base. +// +// A typical use for "A" launching a sandboxed process "B" would be: +// 1. A calls SetupLaunchEnvironment() +// 2. A sets up a base::CommandLine and then amends it with +// PrependWrapper() (or manually, by relying on GetSandboxBinaryPath()). +// 3. A uses SetupLaunchOptions() to arrange for a dummy descriptor for the +// setuid sandbox ABI. +// 4. A launches B with base::LaunchProcess, using the amended +// base::CommandLine. +// (The remaining steps are described within setuid_sandbox_client.h.) +class SANDBOX_EXPORT SetuidSandboxHost { + public: + // All instantation should go through this factory method. + static SetuidSandboxHost* Create(); + ~SetuidSandboxHost(); + + // The setuid sandbox may still be disabled via the environment. + // This is tracked in crbug.com/245376. + bool IsDisabledViaEnvironment(); + // Get the sandbox binary path. This method knows about the + // CHROME_DEVEL_SANDBOX environment variable used for user-managed builds. If + // the sandbox binary cannot be found, it will return an empty FilePath. + base::FilePath GetSandboxBinaryPath(); + // Modify |cmd_line| to launch via the setuid sandbox. Crash if the setuid + // sandbox binary cannot be found. |cmd_line| must not be NULL. + void PrependWrapper(base::CommandLine* cmd_line); + // Set-up the launch options for launching via the setuid sandbox. Caller is + // responsible for keeping |dummy_fd| alive until LaunchProcess() completes. + // |options| and |fds_to_remap| must not be NULL. + // (Keeping |dummy_fd| alive is an unfortunate historical artifact of the + // chrome-sandbox ABI.) + void SetupLaunchOptions(base::LaunchOptions* options, + base::FileHandleMappingVector* fds_to_remap, + base::ScopedFD* dummy_fd); + // Set-up the environment. This should be done prior to launching the setuid + // helper. + void SetupLaunchEnvironment(); + + private: + explicit SetuidSandboxHost(base::Environment* env); + + // Holds the environment. Will never be NULL. + scoped_ptr<base::Environment> env_; + + DISALLOW_COPY_AND_ASSIGN(SetuidSandboxHost); +}; + +} // namespace sandbox + +#endif // SANDBOX_LINUX_SUID_SETUID_SANDBOX_HOST_H_
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc b/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc new file mode 100644 index 0000000..8415abb --- /dev/null +++ b/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc
@@ -0,0 +1,72 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/linux/suid/client/setuid_sandbox_host.h" + +#include <string> + +#include "base/environment.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/strings/string_number_conversions.h" +#include "sandbox/linux/suid/common/sandbox.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sandbox { + +TEST(SetuidSandboxHost, SetupLaunchEnvironment) { + const char kTestValue[] = "This is a test"; + scoped_ptr<base::Environment> env(base::Environment::Create()); + EXPECT_TRUE(env != NULL); + + std::string saved_ld_preload; + bool environment_had_ld_preload; + // First, back-up the real LD_PRELOAD if any. + environment_had_ld_preload = env->GetVar("LD_PRELOAD", &saved_ld_preload); + // Setup environment variables to save or not save. + EXPECT_TRUE(env->SetVar("LD_PRELOAD", kTestValue)); + EXPECT_TRUE(env->UnSetVar("LD_ORIGIN_PATH")); + + scoped_ptr<SetuidSandboxHost> sandbox_host(SetuidSandboxHost::Create()); + EXPECT_TRUE(sandbox_host != NULL); + + // Make sure the environment is clean. + EXPECT_TRUE(env->UnSetVar(kSandboxEnvironmentApiRequest)); + EXPECT_TRUE(env->UnSetVar(kSandboxEnvironmentApiProvides)); + + sandbox_host->SetupLaunchEnvironment(); + + // Check if the requested API environment was set. + std::string api_request; + EXPECT_TRUE(env->GetVar(kSandboxEnvironmentApiRequest, &api_request)); + int api_request_num; + EXPECT_TRUE(base::StringToInt(api_request, &api_request_num)); + EXPECT_EQ(api_request_num, kSUIDSandboxApiNumber); + + // Now check if LD_PRELOAD was saved to SANDBOX_LD_PRELOAD. + std::string sandbox_ld_preload; + EXPECT_TRUE(env->GetVar("SANDBOX_LD_PRELOAD", &sandbox_ld_preload)); + EXPECT_EQ(sandbox_ld_preload, kTestValue); + + // Check that LD_ORIGIN_PATH was not saved. + EXPECT_FALSE(env->HasVar("SANDBOX_LD_ORIGIN_PATH")); + + // We should not forget to restore LD_PRELOAD at the end, or this environment + // variable will affect the next running tests! + if (environment_had_ld_preload) { + EXPECT_TRUE(env->SetVar("LD_PRELOAD", saved_ld_preload)); + } else { + EXPECT_TRUE(env->UnSetVar("LD_PRELOAD")); + } +} + +// This test doesn't accomplish much, but will make sure that analysis tools +// will run this codepath. +TEST(SetuidSandboxHost, GetSandboxBinaryPath) { + scoped_ptr<SetuidSandboxHost> setuid_sandbox_host( + SetuidSandboxHost::Create()); + ignore_result(setuid_sandbox_host->GetSandboxBinaryPath()); +} + +} // namespace sandbox
diff --git a/sandbox/win/BUILD.gn b/sandbox/win/BUILD.gn index fe37f22..0d9d1fb 100644 --- a/sandbox/win/BUILD.gn +++ b/sandbox/win/BUILD.gn
@@ -185,6 +185,7 @@ test("sbox_integration_tests") { sources = [ + "src/address_sanitizer_test.cc", "src/app_container_test.cc", "src/file_policy_test.cc", "src/handle_inheritance_test.cc",
diff --git a/sandbox/win/sandbox_win.gypi b/sandbox/win/sandbox_win.gypi index 7d9cf94..e085cfb5 100644 --- a/sandbox/win/sandbox_win.gypi +++ b/sandbox/win/sandbox_win.gypi
@@ -218,6 +218,7 @@ '../testing/gtest.gyp:gtest', ], 'sources': [ + 'src/address_sanitizer_test.cc', 'src/app_container_test.cc', 'src/file_policy_test.cc', 'src/handle_inheritance_test.cc',
diff --git a/sandbox/win/src/address_sanitizer_test.cc b/sandbox/win/src/address_sanitizer_test.cc new file mode 100644 index 0000000..6eb2c85 --- /dev/null +++ b/sandbox/win/src/address_sanitizer_test.cc
@@ -0,0 +1,107 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdio.h> + +#include "base/environment.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/path_service.h" +#include "base/win/scoped_handle.h" +#include "base/win/windows_version.h" +#include "sandbox/win/tests/common/controller.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sandbox { + +class AddressSanitizerTests : public ::testing::Test { + public: + void SetUp() { + env_.reset(base::Environment::Create()); + had_asan_options_ = env_->GetVar("ASAN_OPTIONS", &old_asan_options_); + } + + void TearDown() { + if (had_asan_options_) + ASSERT_TRUE(env_->SetVar("ASAN_OPTIONS", old_asan_options_)); + else + env_->UnSetVar("ASAN_OPTIONS"); + } + + protected: + scoped_ptr<base::Environment> env_; + bool had_asan_options_; + std::string old_asan_options_; +}; + +SBOX_TESTS_COMMAND int AddressSanitizerTests_Report(int argc, wchar_t** argv) { + // AddressSanitizer should detect an out of bounds write (heap buffer + // overflow) in this code. + volatile int idx = 42; + int *blah = new int[42]; + blah[idx] = 42; + delete [] blah; + return SBOX_TEST_FAILED; +} + +TEST_F(AddressSanitizerTests, TestAddressSanitizer) { + // This test is only supposed to work when using AddressSanitizer. + // However, ASan/Win is not on the CQ yet, so compiler breakages may get into + // the code unnoticed. To avoid that, we compile this test in all Windows + // builds, but only run the AddressSanitizer-specific part of the test when + // compiled with AddressSanitizer. +#if defined(ADDRESS_SANITIZER) + bool asan_build = true; +#else + bool asan_build = false; +#endif + base::ScopedTempDir temp_directory; + base::FilePath temp_file_name; + ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); + ASSERT_TRUE(CreateTemporaryFileInDir(temp_directory.path(), &temp_file_name)); + + SECURITY_ATTRIBUTES attrs = {}; + attrs.nLength = sizeof(attrs); + attrs.bInheritHandle = TRUE; + base::win::ScopedHandle tmp_handle( + CreateFile(temp_file_name.value().c_str(), GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &attrs, OPEN_EXISTING, 0, NULL)); + EXPECT_TRUE(tmp_handle.IsValid()); + + TestRunner runner; + ASSERT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetStderrHandle(tmp_handle.Get())); + + base::FilePath exe; + ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe)); + base::FilePath pdb_path = exe.DirName().Append(L"*.pdb"); + ASSERT_TRUE(runner.AddFsRule(sandbox::TargetPolicy::FILES_ALLOW_READONLY, + pdb_path.value().c_str())); + + env_->SetVar("ASAN_OPTIONS", "exitcode=123"); + if (asan_build) { + int result = runner.RunTest(L"AddressSanitizerTests_Report"); + EXPECT_EQ(123, result); + + std::string data; + ASSERT_TRUE(base::ReadFileToString(base::FilePath(temp_file_name), &data)); + // Redirection uses a feature that was added in Windows Vista. + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + ASSERT_TRUE( + strstr(data.c_str(), "ERROR: AddressSanitizer: heap-buffer-overflow")) + << "There doesn't seem to be an ASan report:\n" << data; + ASSERT_TRUE(strstr(data.c_str(), "AddressSanitizerTests_Report")) + << "The ASan report doesn't appear to be symbolized:\n" << data; + ASSERT_TRUE(strstr(data.c_str(), strrchr(__FILE__, '\\'))) + << "The stack trace doesn't have a correct filename:\n" << data; + } else { + LOG(WARNING) << "Pre-Vista versions are not supported."; + } + } else { + LOG(WARNING) << "Not an AddressSanitizer build, skipping the run."; + } +} + +}
diff --git a/sandbox/win/src/handle_inheritance_test.cc b/sandbox/win/src/handle_inheritance_test.cc index 8074c41..37974e3 100644 --- a/sandbox/win/src/handle_inheritance_test.cc +++ b/sandbox/win/src/handle_inheritance_test.cc
@@ -5,6 +5,8 @@ #include <stdio.h> #include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/win/scoped_handle.h" #include "base/win/windows_version.h" #include "sandbox/win/tests/common/controller.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,37 +20,33 @@ } TEST(HandleInheritanceTests, TestStdoutInheritance) { - wchar_t temp_directory[MAX_PATH]; - wchar_t temp_file_name[MAX_PATH]; - ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u); - ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u); + base::ScopedTempDir temp_directory; + base::FilePath temp_file_name; + ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); + ASSERT_TRUE(CreateTemporaryFileInDir(temp_directory.path(), &temp_file_name)); SECURITY_ATTRIBUTES attrs = {}; attrs.nLength = sizeof(attrs); - attrs.lpSecurityDescriptor = NULL; attrs.bInheritHandle = TRUE; - HANDLE file_handle = CreateFile( - temp_file_name, GENERIC_WRITE, - FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, - &attrs, OPEN_EXISTING, 0, NULL); - EXPECT_NE(file_handle, INVALID_HANDLE_VALUE); + base::win::ScopedHandle tmp_handle( + CreateFile(temp_file_name.value().c_str(), GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &attrs, OPEN_EXISTING, 0, NULL)); + ASSERT_TRUE(tmp_handle.IsValid()); TestRunner runner; - EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetStdoutHandle(file_handle)); + ASSERT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetStdoutHandle(tmp_handle.Get())); int result = runner.RunTest(L"HandleInheritanceTests_PrintToStdout"); - EXPECT_EQ(SBOX_TEST_SUCCEEDED, result); - EXPECT_TRUE(::CloseHandle(file_handle)); + ASSERT_EQ(SBOX_TEST_SUCCEEDED, result); std::string data; - EXPECT_TRUE(base::ReadFileToString(base::FilePath(temp_file_name), &data)); + ASSERT_TRUE(base::ReadFileToString(base::FilePath(temp_file_name), &data)); // Redirection uses a feature that was added in Windows Vista. if (base::win::GetVersion() >= base::win::VERSION_VISTA) { - EXPECT_EQ("Example output to stdout\r\n", data); + ASSERT_EQ("Example output to stdout\r\n", data); } else { - EXPECT_EQ("", data); + ASSERT_EQ("", data); } - - EXPECT_TRUE(::DeleteFile(temp_file_name)); } }
diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc index 03813c8..518507e9 100644 --- a/sandbox/win/src/target_services.cc +++ b/sandbox/win/src/target_services.cc
@@ -7,6 +7,7 @@ #include <process.h> #include "base/basictypes.h" +#include "base/win/windows_version.h" #include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/handle_closer_agent.h" #include "sandbox/win/src/handle_interception.h" @@ -45,6 +46,13 @@ // Checks if we have handle entries pending and runs the closer. bool CloseOpenHandles() { + // Windows 10 has FLG_ENABLE_HANDLE_EXCEPTIONS enabled by default so causes + // exceptions to be raised if target process attempts to close a handle that + // has already been closed by HandleCloser. Therefore, do not close any + // handles on Windows 10 until this flag is removed by MS. + // See crbug.com/452613. + if (base::win::GetVersion() == base::win::VERSION_WIN10) + return true; if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) { sandbox::HandleCloserAgent handle_closer;
diff --git a/sandbox/win/tests/common/controller.cc b/sandbox/win/tests/common/controller.cc index 00334009..738ba14 100644 --- a/sandbox/win/tests/common/controller.cc +++ b/sandbox/win/tests/common/controller.cc
@@ -325,6 +325,13 @@ else if (EVERY_STATE == state) command(argc - 4, argv + 4); +#if defined(ADDRESS_SANITIZER) + // Bind and leak dbghelp.dll before the token is lowered, otherwise + // AddressSanitizer will crash when trying to symbolize a report. + if (!LoadLibraryA("dbghelp.dll")) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; +#endif + target->LowerToken(); } else if (0 != _wcsicmp(argv[1], L"-child-no-sandbox")) { return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 87f1831..e55730f 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -332,9 +332,6 @@ "ext/skia_utils_mac.h", "ext/skia_utils_win.cc", "ext/skia_utils_win.h", - "ext/vector_canvas.h", - "ext/vector_platform_device_emf_win.cc", - "ext/vector_platform_device_emf_win.h", ] # The skia gypi values are relative to the skia_dir, so we need to rebase. @@ -646,13 +643,8 @@ "ext/refptr_unittest.cc", "ext/skia_utils_ios_unittest.mm", "ext/skia_utils_mac_unittest.mm", - "ext/vector_canvas_unittest.cc", ] - if (!is_win) { - sources -= [ "ext/vector_canvas_unittest.cc" ] - } - if (!is_win && !is_mac) { sources -= [ "ext/platform_canvas_unittest.cc" ] }
diff --git a/skia/ext/vector_canvas.h b/skia/ext/vector_canvas.h deleted file mode 100644 index 673becc..0000000 --- a/skia/ext/vector_canvas.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SKIA_EXT_VECTOR_CANVAS_H_ -#define SKIA_EXT_VECTOR_CANVAS_H_ - -#include "base/compiler_specific.h" -#include "skia/ext/platform_canvas.h" - -// This was a specialization of PlatformCanvas, but all necessary functionality -// has been subsumed by just SkCanvas and a specialized device (PDF or EMF). -// Future evolution goal is to replace this notion (canvas+device) with -// an updated version of SkDocument, which will have explicit APIs for margins. -// At that point, this class (and header) will be removed entirely. - -namespace skia { - typedef PlatformCanvas VectorCanvas; -} // namespace skia - -#endif // SKIA_EXT_VECTOR_CANVAS_H_ -
diff --git a/skia/ext/vector_canvas_unittest.cc b/skia/ext/vector_canvas_unittest.cc deleted file mode 100644 index d3ad9a0..0000000 --- a/skia/ext/vector_canvas_unittest.cc +++ /dev/null
@@ -1,970 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" - -#if !defined(OS_WIN) -#include <unistd.h> -#endif - -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "skia/ext/vector_canvas.h" -#include "skia/ext/vector_platform_device_emf_win.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/effects/SkDashPathEffect.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/geometry/size.h" - -namespace skia { - -namespace { - -const char kGenerateSwitch[] = "vector-canvas-generate"; - -// Lightweight HDC management. -class Context { - public: - Context() : context_(CreateCompatibleDC(NULL)) { - EXPECT_TRUE(context_); - } - ~Context() { - DeleteDC(context_); - } - - HDC context() const { return context_; } - - private: - HDC context_; - - DISALLOW_COPY_AND_ASSIGN(Context); -}; - -// Lightweight HBITMAP management. -class Bitmap { - public: - Bitmap(const Context& context, int x, int y) { - BITMAPINFOHEADER hdr; - hdr.biSize = sizeof(BITMAPINFOHEADER); - hdr.biWidth = x; - hdr.biHeight = -y; // Minus means top-down bitmap. - hdr.biPlanes = 1; - hdr.biBitCount = 32; - hdr.biCompression = BI_RGB; // No compression. - hdr.biSizeImage = 0; - hdr.biXPelsPerMeter = 1; - hdr.biYPelsPerMeter = 1; - hdr.biClrUsed = 0; - hdr.biClrImportant = 0; - bitmap_ = CreateDIBSection(context.context(), - reinterpret_cast<BITMAPINFO*>(&hdr), 0, - &data_, NULL, 0); - EXPECT_TRUE(bitmap_); - EXPECT_TRUE(SelectObject(context.context(), bitmap_)); - } - ~Bitmap() { - EXPECT_TRUE(DeleteObject(bitmap_)); - } - - private: - HBITMAP bitmap_; - - void* data_; - - DISALLOW_COPY_AND_ASSIGN(Bitmap); -}; - -// Lightweight raw-bitmap management. The image, once initialized, is immuable. -// It is mainly used for comparison. -class Image { - public: - // Creates the image from the given filename on disk. - explicit Image(const base::FilePath& filename) : ignore_alpha_(true) { - std::string compressed; - base::ReadFileToString(filename, &compressed); - EXPECT_TRUE(compressed.size()); - - SkBitmap bitmap; - EXPECT_TRUE(gfx::PNGCodec::Decode( - reinterpret_cast<const unsigned char*>(compressed.data()), - compressed.size(), &bitmap)); - SetSkBitmap(bitmap); - } - - // Loads the image from a canvas. - Image(skia::PlatformCanvas& canvas) : ignore_alpha_(true) { - // Use a different way to access the bitmap. The normal way would be to - // query the SkBitmap. - skia::ScopedPlatformPaint scoped_platform_paint(&canvas); - HDC context = scoped_platform_paint.GetPlatformSurface(); - HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP); - EXPECT_TRUE(bitmap != NULL); - // Initialize the clip region to the entire bitmap. - BITMAP bitmap_data; - EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data), sizeof(BITMAP)); - width_ = bitmap_data.bmWidth; - height_ = bitmap_data.bmHeight; - row_length_ = bitmap_data.bmWidthBytes; - size_t size = row_length_ * height_; - data_.resize(size); - memcpy(&*data_.begin(), bitmap_data.bmBits, size); - } - - // Loads the image from a canvas. - Image(const SkBitmap& bitmap) : ignore_alpha_(true) { - SetSkBitmap(bitmap); - } - - int width() const { return width_; } - int height() const { return height_; } - int row_length() const { return row_length_; } - - // Save the image to a png file. Used to create the initial test files. - void SaveToFile(const base::FilePath& filename) { - std::vector<unsigned char> compressed; - ASSERT_TRUE(gfx::PNGCodec::Encode(&*data_.begin(), - gfx::PNGCodec::FORMAT_BGRA, - gfx::Size(width_, height_), - row_length_, - true, - std::vector<gfx::PNGCodec::Comment>(), - &compressed)); - ASSERT_TRUE(compressed.size()); - FILE* f = base::OpenFile(filename, "wb"); - ASSERT_TRUE(f); - ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f), - compressed.size()); - base::CloseFile(f); - } - - // Returns the percentage of the image that is different from the other, - // between 0 and 100. - double PercentageDifferent(const Image& rhs) const { - if (width_ != rhs.width_ || - height_ != rhs.height_ || - row_length_ != rhs.row_length_ || - width_ == 0 || - height_ == 0) { - return 100.; // When of different size or empty, they are 100% different. - } - // Compute pixels different in the overlap - int pixels_different = 0; - for (int y = 0; y < height_; ++y) { - for (int x = 0; x < width_; ++x) { - uint32_t lhs_pixel = pixel_at(x, y); - uint32_t rhs_pixel = rhs.pixel_at(x, y); - if (lhs_pixel != rhs_pixel) - ++pixels_different; - } - } - - // Like the WebKit ImageDiff tool, we define percentage different in terms - // of the size of the 'actual' bitmap. - double total_pixels = static_cast<double>(width_) * - static_cast<double>(height_); - return static_cast<double>(pixels_different) / total_pixels * 100.; - } - - // Returns the 0x0RGB or 0xARGB value of the pixel at the given location, - // depending on ignore_alpha_. - uint32 pixel_at(int x, int y) const { - EXPECT_TRUE(x >= 0 && x < width_); - EXPECT_TRUE(y >= 0 && y < height_); - const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin()); - const uint32* data_row = data + y * row_length_ / sizeof(uint32); - if (ignore_alpha_) - return data_row[x] & 0xFFFFFF; // Strip out A. - else - return data_row[x]; - } - - protected: - void SetSkBitmap(const SkBitmap& bitmap) { - SkAutoLockPixels lock(bitmap); - width_ = bitmap.width(); - height_ = bitmap.height(); - row_length_ = static_cast<int>(bitmap.rowBytes()); - size_t size = row_length_ * height_; - data_.resize(size); - memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size); - } - - private: - // Pixel dimensions of the image. - int width_; - int height_; - - // Length of a line in bytes. - int row_length_; - - // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's - // 0xABGR). - std::vector<unsigned char> data_; - - // Flag to signal if the comparison functions should ignore the alpha channel. - const bool ignore_alpha_; - - DISALLOW_COPY_AND_ASSIGN(Image); -}; - -// Base for tests. Capability to process an image. -class ImageTest : public testing::Test { - public: - // In what state is the test running. - enum ProcessAction { - GENERATE, - COMPARE, - NOOP, - }; - - ImageTest(ProcessAction default_action) - : action_(default_action) { - } - - protected: - virtual void SetUp() { - const testing::TestInfo& test_info = - *testing::UnitTest::GetInstance()->current_test_info(); - PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_); - test_dir_ = test_dir_.AppendASCII("skia"). - AppendASCII("ext"). - AppendASCII("data"). - AppendASCII(test_info.test_case_name()). - AppendASCII(test_info.name()); - - // Hack for a quick lowercase. We assume all the tests names are ASCII. - base::FilePath::StringType tmp(test_dir_.value()); - for (size_t i = 0; i < tmp.size(); ++i) - tmp[i] = base::ToLowerASCII(tmp[i]); - test_dir_ = base::FilePath(tmp); - - if (action_ == GENERATE) { - // Make sure the directory exist. - base::CreateDirectory(test_dir_); - } - } - - // Returns the fully qualified path of a data file. - base::FilePath test_file(const base::FilePath::StringType& filename) const { - // Hack for a quick lowercase. We assume all the test data file names are - // ASCII. -#if defined(OS_WIN) - std::string tmp = base::UTF16ToASCII(filename); -#else - std::string tmp(filename); -#endif - for (size_t i = 0; i < tmp.size(); ++i) - tmp[i] = base::ToLowerASCII(tmp[i]); - - return test_dir_.AppendASCII(tmp); - } - - // Compares or saves the bitmap currently loaded in the context, depending on - // kGenerating value. Returns 0 on success or any positive value between ]0, - // 100] on failure. The return value is the percentage of difference between - // the image in the file and the image in the canvas. - double ProcessCanvas(skia::PlatformCanvas& canvas, - base::FilePath::StringType filename) const { - filename = filename + FILE_PATH_LITERAL(".png"); - switch (action_) { - case GENERATE: - SaveImage(canvas, filename); - return 0.; - case COMPARE: - return CompareImage(canvas, filename); - case NOOP: - return 0; - default: - // Invalid state, returns that the image is 100 different. - return 100.; - } - } - - // Compares the bitmap currently loaded in the context with the file. Returns - // the percentage of pixel difference between both images, between 0 and 100. - double CompareImage(skia::PlatformCanvas& canvas, - const base::FilePath::StringType& filename) const { - Image image1(canvas); - Image image2(test_file(filename)); - double diff = image1.PercentageDifferent(image2); - return diff; - } - - // Saves the bitmap currently loaded in the context into the file. - void SaveImage(skia::PlatformCanvas& canvas, - const base::FilePath::StringType& filename) const { - Image(canvas).SaveToFile(test_file(filename)); - } - - ProcessAction action_; - - // Path to directory used to contain the test data. - base::FilePath test_dir_; - - DISALLOW_COPY_AND_ASSIGN(ImageTest); -}; - -// Premultiply the Alpha channel on the R, B and G channels. -void Premultiply(SkBitmap bitmap) { - SkAutoLockPixels lock(bitmap); - for (int x = 0; x < bitmap.width(); ++x) { - for (int y = 0; y < bitmap.height(); ++y) { - uint32_t* pixel_addr = bitmap.getAddr32(x, y); - uint32_t color = *pixel_addr; - BYTE alpha = SkColorGetA(color); - if (!alpha) { - *pixel_addr = 0; - } else { - BYTE alpha_offset = alpha / 2; - *pixel_addr = SkColorSetARGB( - SkColorGetA(color), - (SkColorGetR(color) * 255 + alpha_offset) / alpha, - (SkColorGetG(color) * 255 + alpha_offset) / alpha, - (SkColorGetB(color) * 255 + alpha_offset) / alpha); - } - } - } -} - -void LoadPngFileToSkBitmap(const base::FilePath& filename, - SkBitmap* bitmap, - bool is_opaque) { - std::string compressed; - base::ReadFileToString(base::MakeAbsoluteFilePath(filename), &compressed); - ASSERT_TRUE(compressed.size()); - - ASSERT_TRUE(gfx::PNGCodec::Decode( - reinterpret_cast<const unsigned char*>(compressed.data()), - compressed.size(), bitmap)); - - EXPECT_EQ(is_opaque, bitmap->isOpaque()); - Premultiply(*bitmap); -} - -} // namespace - -// Streams an image. -inline std::ostream& operator<<(std::ostream& out, const Image& image) { - return out << "Image(" << image.width() << ", " - << image.height() << ", " << image.row_length() << ")"; -} - -// Runs simultaneously the same drawing commands on VectorCanvas and -// PlatformCanvas and compare the results. -class VectorCanvasTest : public ImageTest { - public: - typedef ImageTest parent; - - VectorCanvasTest() : parent(CurrentMode()), compare_canvas_(true) { - } - - protected: - virtual void SetUp() { - parent::SetUp(); - Init(100); - number_ = 0; - } - - virtual void TearDown() { - delete pcanvas_; - pcanvas_ = NULL; - - delete vcanvas_; - vcanvas_ = NULL; - - delete bitmap_; - bitmap_ = NULL; - - delete context_; - context_ = NULL; - - parent::TearDown(); - } - - void Init(int size) { - size_ = size; - context_ = new Context(); - bitmap_ = new Bitmap(*context_, size_, size_); - vcanvas_ = new VectorCanvas( - VectorPlatformDeviceEmf::CreateDevice( - size_, size_, true, context_->context())); - pcanvas_ = CreatePlatformCanvas(size_, size_, false); - - // Clear white. - vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); - pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); - } - - // Compares both canvas and returns the pixel difference in percentage between - // both images. 0 on success and ]0, 100] on failure. - double ProcessImage(const base::FilePath::StringType& filename) { - std::wstring number(base::StringPrintf(L"%02d_", number_++)); - double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename); - double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename); - if (!compare_canvas_) - return std::max(diff1, diff2); - - Image image1(*vcanvas_); - Image image2(*pcanvas_); - double diff = image1.PercentageDifferent(image2); - return std::max(std::max(diff1, diff2), diff); - } - - // Returns COMPARE, which is the default. If kGenerateSwitch command - // line argument is used to start this process, GENERATE is returned instead. - static ProcessAction CurrentMode() { - return base::CommandLine::ForCurrentProcess()->HasSwitch(kGenerateSwitch) - ? GENERATE - : COMPARE; - } - - // Length in x and y of the square canvas. - int size_; - - // Current image number in the current test. Used to number of test files. - int number_; - - // A temporary HDC to draw into. - Context* context_; - - // Bitmap created inside context_. - Bitmap* bitmap_; - - // Vector based canvas. - VectorCanvas* vcanvas_; - - // Pixel based canvas. - PlatformCanvas* pcanvas_; - - // When true (default), vcanvas_ and pcanvas_ contents are compared and - // verified to be identical. - bool compare_canvas_; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Actual tests - -#if !defined(USE_AURA) // http://crbug.com/154358 - -TEST_F(VectorCanvasTest, BasicDrawing) { - EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.) - << L"clean"; - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clean"))); - - // Clear white. - { - vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); - pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawARGB"))); - - // Diagonal line top-left to bottom-right. - { - SkPaint paint; - // Default color is black. - vcanvas_->drawLine(10, 10, 90, 90, paint); - pcanvas_->drawLine(10, 10, 90, 90, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_black"))); - - // Rect. - { - SkPaint paint; - paint.setColor(SK_ColorGREEN); - vcanvas_->drawRectCoords(25, 25, 75, 75, paint); - pcanvas_->drawRectCoords(25, 25, 75, 75, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_green"))); - - // A single-point rect doesn't leave any mark. - { - SkPaint paint; - paint.setColor(SK_ColorBLUE); - vcanvas_->drawRectCoords(5, 5, 5, 5, paint); - pcanvas_->drawRectCoords(5, 5, 5, 5, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop"))); - - // Rect. - { - SkPaint paint; - paint.setColor(SK_ColorBLUE); - vcanvas_->drawRectCoords(75, 50, 80, 55, paint); - pcanvas_->drawRectCoords(75, 50, 80, 55, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop"))); - - // Empty again - { - vcanvas_->drawPaint(SkPaint()); - pcanvas_->drawPaint(SkPaint()); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPaint_black"))); - - // Horizontal line left to right. - { - SkPaint paint; - paint.setColor(SK_ColorRED); - vcanvas_->drawLine(10, 20, 90, 20, paint); - pcanvas_->drawLine(10, 20, 90, 20, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_left_to_right"))); - - // Vertical line downward. - { - SkPaint paint; - paint.setColor(SK_ColorRED); - vcanvas_->drawLine(30, 10, 30, 90, paint); - pcanvas_->drawLine(30, 10, 30, 90, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_red"))); -} - -TEST_F(VectorCanvasTest, Circles) { - // There is NO WAY to make them agree. At least verify that the output doesn't - // change across versions. This test is disabled. See bug 1060231. - compare_canvas_ = false; - - // Stroked Circle. - { - SkPaint paint; - SkPath path; - path.addCircle(50, 75, 10); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorMAGENTA); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke"))); - - // Filled Circle. - { - SkPaint paint; - SkPath path; - path.addCircle(50, 25, 10); - paint.setStyle(SkPaint::kFill_Style); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_fill"))); - - // Stroked Circle over. - { - SkPaint paint; - SkPath path; - path.addCircle(50, 25, 10); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorBLUE); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_over_strike"))); - - // Stroke and Fill Circle. - { - SkPaint paint; - SkPath path; - path.addCircle(12, 50, 10); - paint.setStyle(SkPaint::kStrokeAndFill_Style); - paint.setColor(SK_ColorRED); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke_and_fill"))); - - // Line + Quad + Cubic. - { - SkPaint paint; - SkPath path; - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorGREEN); - path.moveTo(1, 1); - path.lineTo(60, 40); - path.lineTo(80, 80); - path.quadTo(20, 50, 10, 90); - path.quadTo(50, 20, 90, 10); - path.cubicTo(20, 40, 50, 50, 10, 10); - path.cubicTo(30, 20, 50, 50, 90, 10); - path.addRect(90, 90, 95, 96); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("mixed_stroke"))); -} - -TEST_F(VectorCanvasTest, LineOrientation) { - // There is NO WAY to make them agree. At least verify that the output doesn't - // change across versions. This test is disabled. See bug 1060231. - compare_canvas_ = false; - - // Horizontal lines. - { - SkPaint paint; - paint.setColor(SK_ColorRED); - // Left to right. - vcanvas_->drawLine(10, 20, 90, 20, paint); - pcanvas_->drawLine(10, 20, 90, 20, paint); - // Right to left. - vcanvas_->drawLine(90, 30, 10, 30, paint); - pcanvas_->drawLine(90, 30, 10, 30, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal"))); - - // Vertical lines. - { - SkPaint paint; - paint.setColor(SK_ColorRED); - // Top down. - vcanvas_->drawLine(20, 10, 20, 90, paint); - pcanvas_->drawLine(20, 10, 20, 90, paint); - // Bottom up. - vcanvas_->drawLine(30, 90, 30, 10, paint); - pcanvas_->drawLine(30, 90, 30, 10, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical"))); - - // Try again with a 180 degres rotation. - vcanvas_->rotate(180); - pcanvas_->rotate(180); - - // Horizontal lines (rotated). - { - SkPaint paint; - paint.setColor(SK_ColorRED); - vcanvas_->drawLine(-10, -25, -90, -25, paint); - pcanvas_->drawLine(-10, -25, -90, -25, paint); - vcanvas_->drawLine(-90, -35, -10, -35, paint); - pcanvas_->drawLine(-90, -35, -10, -35, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal_180"))); - - // Vertical lines (rotated). - { - SkPaint paint; - paint.setColor(SK_ColorRED); - vcanvas_->drawLine(-25, -10, -25, -90, paint); - pcanvas_->drawLine(-25, -10, -25, -90, paint); - vcanvas_->drawLine(-35, -90, -35, -10, paint); - pcanvas_->drawLine(-35, -90, -35, -10, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical_180"))); -} - -TEST_F(VectorCanvasTest, PathOrientation) { - // There is NO WAY to make them agree. At least verify that the output doesn't - // change across versions. This test is disabled. See bug 1060231. - compare_canvas_ = false; - - // Horizontal lines. - { - SkPaint paint; - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorRED); - SkPath path; - SkPoint start; - start.set(10, 20); - SkPoint end; - end.set(90, 20); - path.moveTo(start); - path.lineTo(end); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_ltr"))); - - // Horizontal lines. - { - SkPaint paint; - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorRED); - SkPath path; - SkPoint start; - start.set(90, 30); - SkPoint end; - end.set(10, 30); - path.moveTo(start); - path.lineTo(end); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_rtl"))); -} - -TEST_F(VectorCanvasTest, DiagonalLines) { - SkPaint paint; - paint.setColor(SK_ColorRED); - - vcanvas_->drawLine(10, 10, 90, 90, paint); - pcanvas_->drawLine(10, 10, 90, 90, paint); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("nw-se"))); - - // Starting here, there is NO WAY to make them agree. At least verify that the - // output doesn't change across versions. This test is disabled. See bug - // 1060231. - compare_canvas_ = false; - - vcanvas_->drawLine(10, 95, 90, 15, paint); - pcanvas_->drawLine(10, 95, 90, 15, paint); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("sw-ne"))); - - vcanvas_->drawLine(90, 10, 10, 90, paint); - pcanvas_->drawLine(90, 10, 10, 90, paint); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("ne-sw"))); - - vcanvas_->drawLine(95, 90, 15, 10, paint); - pcanvas_->drawLine(95, 90, 15, 10, paint); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("se-nw"))); -} - -#if defined(OS_WIN) -#define MAYBE_PathEffects DISABLED_PathEffects -#else -#define MAYBE_PathEffects PathEffects -#endif -TEST_F(VectorCanvasTest, MAYBE_PathEffects) { - { - SkPaint paint; - SkScalar intervals[] = { 1, 1 }; - skia::RefPtr<SkPathEffect> effect = skia::AdoptRef( - new SkDashPathEffect(intervals, arraysize(intervals), 0)); - paint.setPathEffect(effect.get()); - paint.setColor(SK_ColorMAGENTA); - paint.setStyle(SkPaint::kStroke_Style); - - vcanvas_->drawLine(10, 10, 90, 10, paint); - pcanvas_->drawLine(10, 10, 90, 10, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_line"))); - - - // Starting here, there is NO WAY to make them agree. At least verify that the - // output doesn't change across versions. This test is disabled. See bug - // 1060231. - compare_canvas_ = false; - - { - SkPaint paint; - SkScalar intervals[] = { 3, 5 }; - skia::RefPtr<SkPathEffect> effect = skia::AdoptRef( - new SkDashPathEffect(intervals, arraysize(intervals), 0)); - paint.setPathEffect(effect.get()); - paint.setColor(SK_ColorMAGENTA); - paint.setStyle(SkPaint::kStroke_Style); - - SkPath path; - path.moveTo(10, 15); - path.lineTo(90, 15); - path.lineTo(90, 90); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_path"))); - - { - SkPaint paint; - SkScalar intervals[] = { 2, 1 }; - skia::RefPtr<SkPathEffect> effect = skia::AdoptRef( - new SkDashPathEffect(intervals, arraysize(intervals), 0)); - paint.setPathEffect(effect.get()); - paint.setColor(SK_ColorMAGENTA); - paint.setStyle(SkPaint::kStroke_Style); - - vcanvas_->drawRectCoords(20, 20, 30, 30, paint); - pcanvas_->drawRectCoords(20, 20, 30, 30, paint); - } - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_rect"))); - - // This thing looks like it has been drawn by a 3 years old kid. I haven't - // filed a bug on this since I guess nobody is expecting this to look nice. - { - SkPaint paint; - SkScalar intervals[] = { 1, 1 }; - skia::RefPtr<SkPathEffect> effect = skia::AdoptRef( - new SkDashPathEffect(intervals, arraysize(intervals), 0)); - paint.setPathEffect(effect.get()); - paint.setColor(SK_ColorMAGENTA); - paint.setStyle(SkPaint::kStroke_Style); - - SkPath path; - path.addCircle(50, 75, 10); - vcanvas_->drawPath(path, paint); - pcanvas_->drawPath(path, paint); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle"))); - } -} - -TEST_F(VectorCanvasTest, Bitmaps) { - { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap, true); - vcanvas_->drawBitmap(bitmap, 13, 3, NULL); - pcanvas_->drawBitmap(bitmap, 13, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("opaque"))); - } - - { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap, false); - vcanvas_->drawBitmap(bitmap, 5, 15, NULL); - pcanvas_->drawBitmap(bitmap, 5, 15, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("alpha"))); - } -} - -TEST_F(VectorCanvasTest, ClippingRect) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - SkRect rect; - rect.fLeft = 2; - rect.fTop = 2; - rect.fRight = 30.5f; - rect.fBottom = 30.5f; - vcanvas_->clipRect(rect); - pcanvas_->clipRect(rect); - - vcanvas_->drawBitmap(bitmap, 13, 3, NULL); - pcanvas_->drawBitmap(bitmap, 13, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rect"))); -} - -TEST_F(VectorCanvasTest, ClippingPath) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - SkPath path; - path.addCircle(20, 20, 10); - vcanvas_->clipPath(path); - pcanvas_->clipPath(path); - - vcanvas_->drawBitmap(bitmap, 14, 3, NULL); - pcanvas_->drawBitmap(bitmap, 14, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("path"))); -} - -TEST_F(VectorCanvasTest, ClippingCombined) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - - SkRect rect; - rect.fLeft = 2; - rect.fTop = 2; - rect.fRight = 30.5f; - rect.fBottom = 30.5f; - vcanvas_->clipRect(rect); - pcanvas_->clipRect(rect); - SkPath path; - path.addCircle(20, 20, 10); - vcanvas_->clipPath(path, SkRegion::kUnion_Op); - pcanvas_->clipPath(path, SkRegion::kUnion_Op); - - vcanvas_->drawBitmap(bitmap, 15, 3, NULL); - pcanvas_->drawBitmap(bitmap, 15, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("combined"))); -} - -TEST_F(VectorCanvasTest, ClippingIntersect) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - - SkRect rect; - rect.fLeft = 2; - rect.fTop = 2; - rect.fRight = 30.5f; - rect.fBottom = 30.5f; - vcanvas_->clipRect(rect); - pcanvas_->clipRect(rect); - SkPath path; - path.addCircle(23, 23, 15); - vcanvas_->clipPath(path); - pcanvas_->clipPath(path); - - vcanvas_->drawBitmap(bitmap, 15, 3, NULL); - pcanvas_->drawBitmap(bitmap, 15, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("intersect"))); -} - -TEST_F(VectorCanvasTest, ClippingClean) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - { - SkAutoCanvasRestore acrv(vcanvas_, true); - SkAutoCanvasRestore acrp(pcanvas_, true); - SkRect rect; - rect.fLeft = 2; - rect.fTop = 2; - rect.fRight = 30.5f; - rect.fBottom = 30.5f; - vcanvas_->clipRect(rect); - pcanvas_->clipRect(rect); - - vcanvas_->drawBitmap(bitmap, 15, 3, NULL); - pcanvas_->drawBitmap(bitmap, 15, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clipped"))); - } - { - // Verify that the clipping region has been fixed back. - vcanvas_->drawBitmap(bitmap, 55, 3, NULL); - pcanvas_->drawBitmap(bitmap, 55, 3, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("unclipped"))); - } -} - -// See http://crbug.com/26938 -TEST_F(VectorCanvasTest, DISABLED_Matrix) { - SkBitmap bitmap; - LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap, - true); - { - vcanvas_->translate(15, 3); - pcanvas_->translate(15, 3); - vcanvas_->drawBitmap(bitmap, 0, 0, NULL); - pcanvas_->drawBitmap(bitmap, 0, 0, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate1"))); - } - { - vcanvas_->translate(-30, -23); - pcanvas_->translate(-30, -23); - vcanvas_->drawBitmap(bitmap, 0, 0, NULL); - pcanvas_->drawBitmap(bitmap, 0, 0, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate2"))); - } - vcanvas_->resetMatrix(); - pcanvas_->resetMatrix(); - - // For scaling and rotation, they use a different algorithm (nearest - // neighborhood vs smoothing). At least verify that the output doesn't change - // across versions. - compare_canvas_ = false; - - { - vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5)); - pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5)); - vcanvas_->drawBitmap(bitmap, 1, 1, NULL); - pcanvas_->drawBitmap(bitmap, 1, 1, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("scale"))); - } - vcanvas_->resetMatrix(); - pcanvas_->resetMatrix(); - - { - vcanvas_->rotate(67); - pcanvas_->rotate(67); - vcanvas_->drawBitmap(bitmap, 20, -50, NULL); - pcanvas_->drawBitmap(bitmap, 20, -50, NULL); - EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rotate"))); - } -} - -#endif // !defined(USE_AURA) - -} // namespace skia
diff --git a/skia/ext/vector_platform_device_emf_win.cc b/skia/ext/vector_platform_device_emf_win.cc deleted file mode 100644 index 90e4a201..0000000 --- a/skia/ext/vector_platform_device_emf_win.cc +++ /dev/null
@@ -1,982 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "skia/ext/vector_platform_device_emf_win.h" - -#include <windows.h> - -#include "base/logging.h" -#include "base/strings/string16.h" -#include "skia/ext/bitmap_platform_device.h" -#include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkPathEffect.h" -#include "third_party/skia/include/core/SkTemplates.h" -#include "third_party/skia/include/core/SkUtils.h" -#include "third_party/skia/include/ports/SkTypeface_win.h" - -namespace skia { - -#define CHECK_FOR_NODRAW_ANNOTATION(paint) \ - do { if (paint.isNoDrawAnnotation()) { return; } } while (0) - -// static -SkBaseDevice* VectorPlatformDeviceEmf::CreateDevice( - int width, int height, bool is_opaque, HANDLE shared_section) { - if (!is_opaque) { - // TODO(maruel): http://crbug.com/18382 When restoring a semi-transparent - // layer, i.e. merging it, we need to rasterize it because GDI doesn't - // support transparency except for AlphaBlend(). Right now, a - // BitmapPlatformDevice is created when VectorCanvas think a saveLayers() - // call is being done. The way to save a layer would be to create an - // EMF-based VectorDevice and have this device registers the drawing. When - // playing back the device into a bitmap, do it at the printer's dpi instead - // of the layout's dpi (which is much lower). - return BitmapPlatformDevice::Create(width, height, is_opaque, - shared_section); - } - - // TODO(maruel): http://crbug.com/18383 Look if it would be worth to - // increase the resolution by ~10x (any worthy factor) to increase the - // rendering precision (think about printing) while using a relatively - // low dpi. This happens because we receive float as input but the GDI - // functions works with integers. The idea is to premultiply the matrix - // with this factor and multiply each SkScalar that are passed to - // SkScalarRound(value) as SkScalarRound(value * 10). Safari is already - // doing the same for text rendering. - SkASSERT(shared_section); - SkBaseDevice* device = VectorPlatformDeviceEmf::create( - reinterpret_cast<HDC>(shared_section), width, height); - return device; -} - -static void FillBitmapInfoHeader(int width, int height, BITMAPINFOHEADER* hdr) { - hdr->biSize = sizeof(BITMAPINFOHEADER); - hdr->biWidth = width; - hdr->biHeight = -height; // Minus means top-down bitmap. - hdr->biPlanes = 1; - hdr->biBitCount = 32; - hdr->biCompression = BI_RGB; // no compression - hdr->biSizeImage = 0; - hdr->biXPelsPerMeter = 1; - hdr->biYPelsPerMeter = 1; - hdr->biClrUsed = 0; - hdr->biClrImportant = 0; -} - -SkBaseDevice* VectorPlatformDeviceEmf::create(HDC dc, int width, int height) { - InitializeDC(dc); - - // Link the SkBitmap to the current selected bitmap in the device context. - SkBitmap bitmap; - HGDIOBJ selected_bitmap = GetCurrentObject(dc, OBJ_BITMAP); - bool succeeded = false; - if (selected_bitmap != NULL) { - BITMAP bitmap_data = {0}; - if (GetObject(selected_bitmap, sizeof(BITMAP), &bitmap_data) == - sizeof(BITMAP)) { - // The context has a bitmap attached. Attach our SkBitmap to it. - // Warning: If the bitmap gets unselected from the HDC, - // VectorPlatformDeviceEmf has no way to detect this, so the HBITMAP - // could be released while SkBitmap still has a reference to it. Be - // cautious. - if (width == bitmap_data.bmWidth && height == bitmap_data.bmHeight) { - SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); - succeeded = bitmap.installPixels(info, bitmap_data.bmBits, - bitmap_data.bmWidthBytes); - } - } - } - - if (!succeeded) - bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); - - return new VectorPlatformDeviceEmf(dc, bitmap); -} - -VectorPlatformDeviceEmf::VectorPlatformDeviceEmf(HDC dc, const SkBitmap& bitmap) - : SkBitmapDevice(bitmap), - hdc_(dc), - previous_brush_(NULL), - previous_pen_(NULL) { - transform_.reset(); - SetPlatformDevice(this, this); -} - -VectorPlatformDeviceEmf::~VectorPlatformDeviceEmf() { - SkASSERT(previous_brush_ == NULL); - SkASSERT(previous_pen_ == NULL); -} - -HDC VectorPlatformDeviceEmf::BeginPlatformPaint() { - return hdc_; -} - -void VectorPlatformDeviceEmf::drawPaint(const SkDraw& draw, - const SkPaint& paint) { - // TODO(maruel): Bypass the current transformation matrix. - SkRect rect; - rect.fLeft = 0; - rect.fTop = 0; - rect.fRight = SkIntToScalar(width() + 1); - rect.fBottom = SkIntToScalar(height() + 1); - drawRect(draw, rect, paint); -} - -void VectorPlatformDeviceEmf::drawPoints(const SkDraw& draw, - SkCanvas::PointMode mode, - size_t count, - const SkPoint pts[], - const SkPaint& paint) { - if (!count) - return; - - if (mode == SkCanvas::kPoints_PointMode) { - SkASSERT(false); - return; - } - - SkPaint tmp_paint(paint); - tmp_paint.setStyle(SkPaint::kStroke_Style); - - // Draw a path instead. - SkPath path; - switch (mode) { - case SkCanvas::kLines_PointMode: - if (count % 2) { - SkASSERT(false); - return; - } - for (size_t i = 0; i < count / 2; ++i) { - path.moveTo(pts[2 * i]); - path.lineTo(pts[2 * i + 1]); - } - break; - case SkCanvas::kPolygon_PointMode: - path.moveTo(pts[0]); - for (size_t i = 1; i < count; ++i) { - path.lineTo(pts[i]); - } - break; - default: - SkASSERT(false); - return; - } - // Draw the calculated path. - drawPath(draw, path, tmp_paint); -} - -void VectorPlatformDeviceEmf::drawRect(const SkDraw& draw, - const SkRect& rect, - const SkPaint& paint) { - CHECK_FOR_NODRAW_ANNOTATION(paint); - if (paint.getPathEffect()) { - // Draw a path instead. - SkPath path_orginal; - path_orginal.addRect(rect); - - // Apply the path effect to the rect. - SkPath path_modified; - paint.getFillPath(path_orginal, &path_modified); - - // Removes the path effect from the temporary SkPaint object. - SkPaint paint_no_effet(paint); - paint_no_effet.setPathEffect(NULL); - - // Draw the calculated path. - drawPath(draw, path_modified, paint_no_effet); - return; - } - - if (!ApplyPaint(paint)) { - return; - } - HDC dc = BeginPlatformPaint(); - if (!Rectangle(dc, SkScalarRoundToInt(rect.fLeft), - SkScalarRoundToInt(rect.fTop), - SkScalarRoundToInt(rect.fRight), - SkScalarRoundToInt(rect.fBottom))) { - SkASSERT(false); - } - EndPlatformPaint(); - Cleanup(); -} - -void VectorPlatformDeviceEmf::drawRRect(const SkDraw& draw, const SkRRect& rr, - const SkPaint& paint) { - SkPath path; - path.addRRect(rr); - this->drawPath(draw, path, paint, NULL, true); -} - -void VectorPlatformDeviceEmf::drawPath(const SkDraw& draw, - const SkPath& path, - const SkPaint& paint, - const SkMatrix* prePathMatrix, - bool pathIsMutable) { - CHECK_FOR_NODRAW_ANNOTATION(paint); - if (paint.getPathEffect()) { - // Apply the path effect forehand. - SkPath path_modified; - paint.getFillPath(path, &path_modified); - - // Removes the path effect from the temporary SkPaint object. - SkPaint paint_no_effet(paint); - paint_no_effet.setPathEffect(NULL); - - // Draw the calculated path. - drawPath(draw, path_modified, paint_no_effet); - return; - } - - if (!ApplyPaint(paint)) { - return; - } - HDC dc = BeginPlatformPaint(); - if (PlatformDevice::LoadPathToDC(dc, path)) { - switch (paint.getStyle()) { - case SkPaint::kFill_Style: { - BOOL res = StrokeAndFillPath(dc); - SkASSERT(res != 0); - break; - } - case SkPaint::kStroke_Style: { - BOOL res = StrokePath(dc); - SkASSERT(res != 0); - break; - } - case SkPaint::kStrokeAndFill_Style: { - BOOL res = StrokeAndFillPath(dc); - SkASSERT(res != 0); - break; - } - default: - SkASSERT(false); - break; - } - } - EndPlatformPaint(); - Cleanup(); -} - -void VectorPlatformDeviceEmf::drawBitmapRect(const SkDraw& draw, - const SkBitmap& bitmap, - const SkRect* src, - const SkRect& dst, - const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) { - SkMatrix matrix; - SkRect bitmapBounds, tmpSrc, tmpDst; - SkBitmap tmpBitmap; - - bitmapBounds.isetWH(bitmap.width(), bitmap.height()); - - // Compute matrix from the two rectangles - if (src) { - tmpSrc = *src; - } else { - tmpSrc = bitmapBounds; - } - matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); - - const SkBitmap* bitmapPtr = &bitmap; - - // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if - // needed (if the src was clipped). No check needed if src==null. - if (src) { - if (!bitmapBounds.contains(*src)) { - if (!tmpSrc.intersect(bitmapBounds)) { - return; // nothing to draw - } - // recompute dst, based on the smaller tmpSrc - matrix.mapRect(&tmpDst, tmpSrc); - } - - // since we may need to clamp to the borders of the src rect within - // the bitmap, we extract a subset. - // TODO: make sure this is handled in drawrect and remove it from here. - SkIRect srcIR; - tmpSrc.roundOut(&srcIR); - if (!bitmap.extractSubset(&tmpBitmap, srcIR)) { - return; - } - bitmapPtr = &tmpBitmap; - - // Since we did an extract, we need to adjust the matrix accordingly - SkScalar dx = 0, dy = 0; - if (srcIR.fLeft > 0) { - dx = SkIntToScalar(srcIR.fLeft); - } - if (srcIR.fTop > 0) { - dy = SkIntToScalar(srcIR.fTop); - } - if (dx || dy) { - matrix.preTranslate(dx, dy); - } - } - this->drawBitmap(draw, *bitmapPtr, matrix, paint); -} - -void VectorPlatformDeviceEmf::drawBitmap(const SkDraw& draw, - const SkBitmap& bitmap, - const SkMatrix& matrix, - const SkPaint& paint) { - // Load the temporary matrix. This is what will translate, rotate and resize - // the bitmap. - SkMatrix actual_transform(transform_); - actual_transform.preConcat(matrix); - LoadTransformToDC(hdc_, actual_transform); - - InternalDrawBitmap(bitmap, 0, 0, paint); - - // Restore the original matrix. - LoadTransformToDC(hdc_, transform_); -} - -void VectorPlatformDeviceEmf::drawSprite(const SkDraw& draw, - const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint) { - SkMatrix identity; - identity.reset(); - LoadTransformToDC(hdc_, identity); - - InternalDrawBitmap(bitmap, x, y, paint); - - // Restore the original matrix. - LoadTransformToDC(hdc_, transform_); -} - -///////////////////////////////////////////////////////////////////////// - -static bool gdiCanHandleText(const SkPaint& paint) { - return !paint.getShader() && - !paint.getPathEffect() && - (SkPaint::kFill_Style == paint.getStyle()) && - (255 == paint.getAlpha()); -} - -class SkGDIFontSetup { - public: - SkGDIFontSetup() : - fHDC(NULL), - fNewFont(NULL), - fSavedFont(NULL), - fSavedTextColor(0), - fUseGDI(false) { - SkDEBUGCODE(fUseGDIHasBeenCalled = false;) - } - ~SkGDIFontSetup(); - - // can only be called once - bool useGDI(HDC hdc, const SkPaint&); - - private: - HDC fHDC; - HFONT fNewFont; - HFONT fSavedFont; - COLORREF fSavedTextColor; - bool fUseGDI; - SkDEBUGCODE(bool fUseGDIHasBeenCalled;) -}; - -bool SkGDIFontSetup::useGDI(HDC hdc, const SkPaint& paint) { - SkASSERT(!fUseGDIHasBeenCalled); - SkDEBUGCODE(fUseGDIHasBeenCalled = true;) - - fUseGDI = gdiCanHandleText(paint); - if (fUseGDI) { - fSavedTextColor = GetTextColor(hdc); - SetTextColor(hdc, skia::SkColorToCOLORREF(paint.getColor())); - - LOGFONT lf = {0}; - SkLOGFONTFromTypeface(paint.getTypeface(), &lf); - lf.lfHeight = -SkScalarRoundToInt(paint.getTextSize()); - fNewFont = CreateFontIndirect(&lf); - fSavedFont = (HFONT)::SelectObject(hdc, fNewFont); - fHDC = hdc; - } - return fUseGDI; -} - -SkGDIFontSetup::~SkGDIFontSetup() { - if (fUseGDI) { - ::SelectObject(fHDC, fSavedFont); - ::DeleteObject(fNewFont); - SetTextColor(fHDC, fSavedTextColor); - } -} - -static SkScalar getAscent(const SkPaint& paint) { - SkPaint::FontMetrics fm; - paint.getFontMetrics(&fm); - return fm.fAscent; -} - -// return the options int for ExtTextOut. Only valid if the paint's text -// encoding is not UTF8 (in which case ExtTextOut can't be used). -static UINT getTextOutOptions(const SkPaint& paint) { - if (SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()) { - return ETO_GLYPH_INDEX; - } else { - SkASSERT(SkPaint::kUTF16_TextEncoding == paint.getTextEncoding()); - return 0; - } -} - -static SkiaEnsureTypefaceCharactersAccessible - g_skia_ensure_typeface_characters_accessible = NULL; - -SK_API void SetSkiaEnsureTypefaceCharactersAccessible( - SkiaEnsureTypefaceCharactersAccessible func) { - // This function is supposed to be called once in process life time. - SkASSERT(g_skia_ensure_typeface_characters_accessible == NULL); - g_skia_ensure_typeface_characters_accessible = func; -} - -void EnsureTypefaceCharactersAccessible( - const SkTypeface& typeface, const wchar_t* text, unsigned int text_length) { - LOGFONT lf = {0}; - SkLOGFONTFromTypeface(&typeface, &lf); - g_skia_ensure_typeface_characters_accessible(lf, text, text_length); -} - -bool EnsureExtTextOut(HDC hdc, int x, int y, UINT options, const RECT * lprect, - LPCWSTR text, unsigned int characters, const int * lpDx, - SkTypeface* const typeface) { - bool success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); - if (!success) { - if (typeface) { - EnsureTypefaceCharactersAccessible(*typeface, - text, - characters); - success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); - if (!success) { - LOGFONT lf = {0}; - SkLOGFONTFromTypeface(typeface, &lf); - VLOG(1) << "SkFontHost::EnsureTypefaceCharactersAccessible FAILED for " - << " FaceName = " << lf.lfFaceName - << " and characters: " << base::string16(text, characters); - } - } else { - VLOG(1) << "ExtTextOut FAILED for default FaceName " - << " and characters: " << base::string16(text, characters); - } - } - return success; -} - -void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, - const void* text, - size_t byteLength, - SkScalar x, - SkScalar y, - const SkPaint& paint) { - SkGDIFontSetup setup; - bool useDrawPath = true; - - if (SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() - && setup.useGDI(hdc_, paint)) { - UINT options = getTextOutOptions(paint); - UINT count = byteLength >> 1; - useDrawPath = !EnsureExtTextOut(hdc_, SkScalarRoundToInt(x), - SkScalarRoundToInt(y + getAscent(paint)), options, 0, - reinterpret_cast<const wchar_t*>(text), count, NULL, - paint.getTypeface()); - } - - if (useDrawPath) { - SkPath path; - paint.getTextPath(text, byteLength, x, y, &path); - drawPath(draw, path, paint); - } -} - -static size_t size_utf8(const char* text) { - return SkUTF8_CountUTF8Bytes(text); -} - -static size_t size_utf16(const char* text) { - uint16_t c = *reinterpret_cast<const uint16_t*>(text); - return SkUTF16_IsHighSurrogate(c) ? 4 : 2; -} - -static size_t size_glyphid(const char* text) { - return 2; -} - -void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw, - const void* text, - size_t len, - const SkScalar pos[], - int scalarsPerPos, - const SkPoint& offset, - const SkPaint& paint) { - SkGDIFontSetup setup; - bool useDrawText = true; - - if (scalarsPerPos == 2 && len >= 2 && - SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() && - setup.useGDI(hdc_, paint)) { - int startX = SkScalarRoundToInt(pos[0] + offset.x()); - int startY = SkScalarRoundToInt(pos[1] + offset.y() + getAscent(paint)); - const int count = len >> 1; - SkAutoSTMalloc<64, INT> storage(count); - INT* advances = storage.get(); - for (int i = 0; i < count - 1; ++i) { - advances[i] = SkScalarRoundToInt(pos[2] - pos[0]); - pos += 2; - } - advances[count - 1] = 0; - useDrawText = !EnsureExtTextOut(hdc_, startX, startY, - getTextOutOptions(paint), 0, reinterpret_cast<const wchar_t*>(text), - count, advances, paint.getTypeface()); - } - - if (useDrawText) { - size_t (*bytesPerCodePoint)(const char*); - switch (paint.getTextEncoding()) { - case SkPaint::kUTF8_TextEncoding: - bytesPerCodePoint = size_utf8; - break; - case SkPaint::kUTF16_TextEncoding: - bytesPerCodePoint = size_utf16; - break; - default: - SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); - bytesPerCodePoint = size_glyphid; - break; - } - - const char* curr = reinterpret_cast<const char*>(text); - const char* stop = curr + len; - while (curr < stop) { - SkScalar x = offset.x() + pos[0]; - SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[1] : 0); - - size_t bytes = bytesPerCodePoint(curr); - drawText(draw, curr, bytes, x, y, paint); - curr += bytes; - pos += scalarsPerPos; - } - } -} - -void VectorPlatformDeviceEmf::drawTextOnPath(const SkDraw& draw, - const void* text, - size_t len, - const SkPath& path, - const SkMatrix* matrix, - const SkPaint& paint) { - // This function isn't used in the code. Verify this assumption. - SkASSERT(false); -} - -void VectorPlatformDeviceEmf::drawVertices(const SkDraw& draw, - SkCanvas::VertexMode vmode, - int vertexCount, - const SkPoint vertices[], - const SkPoint texs[], - const SkColor colors[], - SkXfermode* xmode, - const uint16_t indices[], - int indexCount, - const SkPaint& paint) { - // This function isn't used in the code. Verify this assumption. - SkASSERT(false); -} - -void VectorPlatformDeviceEmf::drawDevice(const SkDraw& draw, - SkBaseDevice* device, - int x, - int y, - const SkPaint& paint) { - // TODO(maruel): http://b/1183870 Playback the EMF buffer at printer's dpi if - // it is a vectorial device. - drawSprite(draw, device->accessBitmap(false), x, y, paint); -} - -bool VectorPlatformDeviceEmf::ApplyPaint(const SkPaint& paint) { - // Note: The goal here is to transfert the SkPaint's state to the HDC's state. - // This function does not execute the SkPaint drawing commands. These should - // be executed in drawPaint(). - - SkPaint::Style style = paint.getStyle(); - if (!paint.getAlpha()) - style = (SkPaint::Style) SkPaint::kStyleCount; - - switch (style) { - case SkPaint::kFill_Style: - if (!CreateBrush(true, paint) || - !CreatePen(false, paint)) - return false; - break; - case SkPaint::kStroke_Style: - if (!CreateBrush(false, paint) || - !CreatePen(true, paint)) - return false; - break; - case SkPaint::kStrokeAndFill_Style: - if (!CreateBrush(true, paint) || - !CreatePen(true, paint)) - return false; - break; - default: - if (!CreateBrush(false, paint) || - !CreatePen(false, paint)) - return false; - break; - } - - /* - getFlags(); - isAntiAlias(); - isDither() - isLinearText() - isSubpixelText() - isUnderlineText() - isStrikeThruText() - isFakeBoldText() - isDevKernText() - isFilterBitmap() - - // Skia's text is not used. This should be fixed. - getTextAlign() - getTextScaleX() - getTextSkewX() - getTextEncoding() - getFontMetrics() - getFontSpacing() - */ - - // BUG 1094907: Implement shaders. Shaders currently in use: - // SkShader::CreateBitmapShader - // SkGradientShader::CreateRadial - // SkGradientShader::CreateLinear - // SkASSERT(!paint.getShader()); - - // http://b/1106647 Implement loopers and mask filter. Looper currently in - // use: - // SkBlurDrawLooper is used for shadows. - // SkASSERT(!paint.getLooper()); - // SkASSERT(!paint.getMaskFilter()); - - // http://b/1165900 Implement xfermode. - // SkASSERT(!paint.getXfermode()); - - // The path effect should be processed before arriving here. - SkASSERT(!paint.getPathEffect()); - - // This isn't used in the code. Verify this assumption. - SkASSERT(!paint.getRasterizer()); - // Reuse code to load Win32 Fonts. - return true; -} - -void VectorPlatformDeviceEmf::setMatrixClip(const SkMatrix& transform, - const SkRegion& region, - const SkClipStack&) { - transform_ = transform; - LoadTransformToDC(hdc_, transform_); - clip_region_ = region; - if (!clip_region_.isEmpty()) - LoadClipRegion(); -} - -void VectorPlatformDeviceEmf::LoadClipRegion() { - SkMatrix t; - t.reset(); - LoadClippingRegionToDC(hdc_, clip_region_, t); -} - -SkBaseDevice* VectorPlatformDeviceEmf::onCreateCompatibleDevice( - const CreateInfo& info) { - SkASSERT(info.fInfo.colorType() == kN32_SkColorType); - return VectorPlatformDeviceEmf::CreateDevice( - info.fInfo.width(), info.fInfo.height(), info.fInfo.isOpaque(), NULL); -} - -bool VectorPlatformDeviceEmf::CreateBrush(bool use_brush, COLORREF color) { - SkASSERT(previous_brush_ == NULL); - // We can't use SetDCBrushColor() or DC_BRUSH when drawing to a EMF buffer. - // SetDCBrushColor() calls are not recorded at all and DC_BRUSH will use - // WHITE_BRUSH instead. - - if (!use_brush) { - // Set the transparency. - if (0 == SetBkMode(hdc_, TRANSPARENT)) { - SkASSERT(false); - return false; - } - - // Select the NULL brush. - previous_brush_ = SelectObject(GetStockObject(NULL_BRUSH)); - return previous_brush_ != NULL; - } - - // Set the opacity. - if (0 == SetBkMode(hdc_, OPAQUE)) { - SkASSERT(false); - return false; - } - - // Create and select the brush. - previous_brush_ = SelectObject(CreateSolidBrush(color)); - return previous_brush_ != NULL; -} - -bool VectorPlatformDeviceEmf::CreatePen(bool use_pen, - COLORREF color, - int stroke_width, - float stroke_miter, - DWORD pen_style) { - SkASSERT(previous_pen_ == NULL); - // We can't use SetDCPenColor() or DC_PEN when drawing to a EMF buffer. - // SetDCPenColor() calls are not recorded at all and DC_PEN will use BLACK_PEN - // instead. - - // No pen case - if (!use_pen) { - previous_pen_ = SelectObject(GetStockObject(NULL_PEN)); - return previous_pen_ != NULL; - } - - // Use the stock pen if the stroke width is 0. - if (stroke_width == 0) { - // Create a pen with the right color. - previous_pen_ = SelectObject(::CreatePen(PS_SOLID, 0, color)); - return previous_pen_ != NULL; - } - - // Load a custom pen. - LOGBRUSH brush = {0}; - brush.lbStyle = BS_SOLID; - brush.lbColor = color; - brush.lbHatch = 0; - HPEN pen = ExtCreatePen(pen_style, stroke_width, &brush, 0, NULL); - SkASSERT(pen != NULL); - previous_pen_ = SelectObject(pen); - if (previous_pen_ == NULL) - return false; - - if (!SetMiterLimit(hdc_, stroke_miter, NULL)) { - SkASSERT(false); - return false; - } - return true; -} - -void VectorPlatformDeviceEmf::Cleanup() { - if (previous_brush_) { - HGDIOBJ result = SelectObject(previous_brush_); - previous_brush_ = NULL; - if (result) { - BOOL res = DeleteObject(result); - SkASSERT(res != 0); - } - } - if (previous_pen_) { - HGDIOBJ result = SelectObject(previous_pen_); - previous_pen_ = NULL; - if (result) { - BOOL res = DeleteObject(result); - SkASSERT(res != 0); - } - } - // Remove any loaded path from the context. - AbortPath(hdc_); -} - -HGDIOBJ VectorPlatformDeviceEmf::SelectObject(HGDIOBJ object) { - HGDIOBJ result = ::SelectObject(hdc_, object); - SkASSERT(result != HGDI_ERROR); - if (result == HGDI_ERROR) - return NULL; - return result; -} - -bool VectorPlatformDeviceEmf::CreateBrush(bool use_brush, - const SkPaint& paint) { - // Make sure that for transparent color, no brush is used. - if (paint.getAlpha() == 0) { - use_brush = false; - } - - return CreateBrush(use_brush, SkColorToCOLORREF(paint.getColor())); -} - -bool VectorPlatformDeviceEmf::CreatePen(bool use_pen, const SkPaint& paint) { - // Make sure that for transparent color, no pen is used. - if (paint.getAlpha() == 0) { - use_pen = false; - } - - DWORD pen_style = PS_GEOMETRIC | PS_SOLID; - switch (paint.getStrokeJoin()) { - case SkPaint::kMiter_Join: - // Connects path segments with a sharp join. - pen_style |= PS_JOIN_MITER; - break; - case SkPaint::kRound_Join: - // Connects path segments with a round join. - pen_style |= PS_JOIN_ROUND; - break; - case SkPaint::kBevel_Join: - // Connects path segments with a flat bevel join. - pen_style |= PS_JOIN_BEVEL; - break; - default: - SkASSERT(false); - break; - } - switch (paint.getStrokeCap()) { - case SkPaint::kButt_Cap: - // Begin/end contours with no extension. - pen_style |= PS_ENDCAP_FLAT; - break; - case SkPaint::kRound_Cap: - // Begin/end contours with a semi-circle extension. - pen_style |= PS_ENDCAP_ROUND; - break; - case SkPaint::kSquare_Cap: - // Begin/end contours with a half square extension. - pen_style |= PS_ENDCAP_SQUARE; - break; - default: - SkASSERT(false); - break; - } - - return CreatePen(use_pen, - SkColorToCOLORREF(paint.getColor()), - SkScalarRoundToInt(paint.getStrokeWidth()), - paint.getStrokeMiter(), - pen_style); -} - -void VectorPlatformDeviceEmf::InternalDrawBitmap(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint) { - unsigned char alpha = paint.getAlpha(); - if (alpha == 0) - return; - - bool is_translucent; - if (alpha != 255) { - // ApplyPaint expect an opaque color. - SkPaint tmp_paint(paint); - tmp_paint.setAlpha(255); - if (!ApplyPaint(tmp_paint)) - return; - is_translucent = true; - } else { - if (!ApplyPaint(paint)) - return; - is_translucent = false; - } - int src_size_x = bitmap.width(); - int src_size_y = bitmap.height(); - if (!src_size_x || !src_size_y) - return; - - // Create a BMP v4 header that we can serialize. We use the shared "V3" - // fillter to fill the stardard items, then add in the "V4" stuff we want. - BITMAPV4HEADER bitmap_header = {0}; - FillBitmapInfoHeader(src_size_x, src_size_y, - reinterpret_cast<BITMAPINFOHEADER*>(&bitmap_header)); - bitmap_header.bV4Size = sizeof(BITMAPV4HEADER); - bitmap_header.bV4RedMask = 0x00ff0000; - bitmap_header.bV4GreenMask = 0x0000ff00; - bitmap_header.bV4BlueMask = 0x000000ff; - bitmap_header.bV4AlphaMask = 0xff000000; - - SkAutoLockPixels lock(bitmap); - SkASSERT(bitmap.colorType() == kN32_SkColorType); - const uint32_t* pixels = static_cast<const uint32_t*>(bitmap.getPixels()); - if (pixels == NULL) { - SkASSERT(false); - return; - } - - if (!is_translucent) { - int row_length = bitmap.rowBytesAsPixels(); - // There is no quick way to determine if an image is opaque. - for (int y2 = 0; y2 < src_size_y; ++y2) { - for (int x2 = 0; x2 < src_size_x; ++x2) { - if (SkColorGetA(pixels[(y2 * row_length) + x2]) != 255) { - is_translucent = true; - y2 = src_size_y; - break; - } - } - } - } - - HDC dc = BeginPlatformPaint(); - BITMAPINFOHEADER hdr = {0}; - FillBitmapInfoHeader(src_size_x, src_size_y, &hdr); - if (is_translucent) { - // The image must be loaded as a bitmap inside a device context. - HDC bitmap_dc = ::CreateCompatibleDC(dc); - void* bits = NULL; - HBITMAP hbitmap = ::CreateDIBSection( - bitmap_dc, reinterpret_cast<const BITMAPINFO*>(&hdr), - DIB_RGB_COLORS, &bits, NULL, 0); - - // static cast to a char so we can do byte ptr arithmatic to - // get the offset. - unsigned char* dest_buffer = static_cast<unsigned char *>(bits); - - // We will copy row by row to avoid having to worry about - // the row strides being different. - const int dest_row_size = hdr.biBitCount / 8 * hdr.biWidth; - for (int row = 0; row < bitmap.height(); ++row) { - int dest_offset = row * dest_row_size; - // pixels_offset in terms of pixel count. - int src_offset = row * bitmap.rowBytesAsPixels(); - memcpy(dest_buffer + dest_offset, pixels + src_offset, dest_row_size); - } - SkASSERT(hbitmap); - HGDIOBJ old_bitmap = ::SelectObject(bitmap_dc, hbitmap); - - // After some analysis of IE7's behavior, this is the thing to do. I was - // sure IE7 was doing so kind of bitmasking due to the way translucent image - // where renderered but after some windbg tracing, it is being done by the - // printer driver after all (mostly HP printers). IE7 always use AlphaBlend - // for bitmasked images. The trick seems to switch the stretching mode in - // what the driver expects. - DWORD previous_mode = GetStretchBltMode(dc); - BOOL result = SetStretchBltMode(dc, COLORONCOLOR); - SkASSERT(result); - // Note that this function expect premultiplied colors (!) - BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA}; - result = GdiAlphaBlend(dc, - x, y, // Destination origin. - src_size_x, src_size_y, // Destination size. - bitmap_dc, - 0, 0, // Source origin. - src_size_x, src_size_y, // Source size. - blend_function); - SkASSERT(result); - result = SetStretchBltMode(dc, previous_mode); - SkASSERT(result); - - ::SelectObject(bitmap_dc, static_cast<HBITMAP>(old_bitmap)); - DeleteObject(hbitmap); - DeleteDC(bitmap_dc); - } else { - int nCopied = StretchDIBits(dc, - x, y, // Destination origin. - src_size_x, src_size_y, - 0, 0, // Source origin. - src_size_x, src_size_y, // Source size. - pixels, - reinterpret_cast<const BITMAPINFO*>(&hdr), - DIB_RGB_COLORS, - SRCCOPY); - } - EndPlatformPaint(); - Cleanup(); -} - -} // namespace skia
diff --git a/skia/ext/vector_platform_device_emf_win.h b/skia/ext/vector_platform_device_emf_win.h deleted file mode 100644 index 81b92af..0000000 --- a/skia/ext/vector_platform_device_emf_win.h +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_ -#define SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "skia/ext/platform_device.h" -#include "third_party/skia/include/core/SkMatrix.h" -#include "third_party/skia/include/core/SkRegion.h" - -namespace skia { - -// A device is basically a wrapper around SkBitmap that provides a surface for -// SkCanvas to draw into. This specific device is not not backed by a surface -// and is thus unreadable. This is because the backend is completely vectorial. -// This device is a simple wrapper over a Windows device context (HDC) handle. -// TODO(robertphillips): Once Skia's SkBaseDevice is refactored to remove -// the bitmap-specific entry points, this class should derive from it. -class VectorPlatformDeviceEmf : public SkBitmapDevice, public PlatformDevice { - public: - SK_API static SkBaseDevice* CreateDevice(int width, int height, bool isOpaque, - HANDLE shared_section); - - // Factory function. The DC is kept as the output context. - static SkBaseDevice* create(HDC dc, int width, int height); - - VectorPlatformDeviceEmf(HDC dc, const SkBitmap& bitmap); - virtual ~VectorPlatformDeviceEmf(); - - // PlatformDevice methods - virtual PlatformSurface BeginPlatformPaint() override; - - // SkBaseDevice methods. - virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) override; - virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, - size_t count, const SkPoint[], - const SkPaint& paint) override; - virtual void drawRect(const SkDraw& draw, const SkRect& r, - const SkPaint& paint) override; - virtual void drawRRect(const SkDraw&, const SkRRect& rr, - const SkPaint& paint) override; - virtual void drawPath(const SkDraw& draw, const SkPath& path, - const SkPaint& paint, - const SkMatrix* prePathMatrix = NULL, - bool pathIsMutable = false) override; - virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, - const SkRect* src, const SkRect& dst, - const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) override; - virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, - const SkMatrix& matrix, - const SkPaint& paint) override; - virtual void drawSprite(const SkDraw& draw, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint) override; - virtual void drawText(const SkDraw& draw, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint) override; - virtual void drawPosText(const SkDraw& draw, const void* text, size_t len, - const SkScalar pos[], int scalarsPerPos, - const SkPoint& offset, const SkPaint& paint) override; - virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) override; - virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, - int vertexCount, - const SkPoint verts[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint) override; - virtual void drawDevice(const SkDraw& draw, SkBaseDevice*, int x, int y, - const SkPaint&) override; - - virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, - const SkClipStack&) override; - - void LoadClipRegion(); - - protected: - virtual SkBaseDevice* onCreateCompatibleDevice(const CreateInfo& info) override; - - private: - // Applies the SkPaint's painting properties in the current GDI context, if - // possible. If GDI can't support all paint's properties, returns false. It - // doesn't execute the "commands" in SkPaint. - bool ApplyPaint(const SkPaint& paint); - - // Selects a new object in the device context. It can be a pen, a brush, a - // clipping region, a bitmap or a font. Returns the old selected object. - HGDIOBJ SelectObject(HGDIOBJ object); - - // Creates a brush according to SkPaint's properties. - bool CreateBrush(bool use_brush, const SkPaint& paint); - - // Creates a pen according to SkPaint's properties. - bool CreatePen(bool use_pen, const SkPaint& paint); - - // Restores back the previous objects (pen, brush, etc) after a paint command. - void Cleanup(); - - // Creates a brush according to SkPaint's properties. - bool CreateBrush(bool use_brush, COLORREF color); - - // Creates a pen according to SkPaint's properties. - bool CreatePen(bool use_pen, COLORREF color, int stroke_width, - float stroke_miter, DWORD pen_style); - - // Draws a bitmap in the the device, using the currently loaded matrix. - void InternalDrawBitmap(const SkBitmap& bitmap, int x, int y, - const SkPaint& paint); - - // The Windows Device Context handle. It is the backend used with GDI drawing. - // This backend is write-only and vectorial. - HDC hdc_; - - // Translation assigned to the DC: we need to keep track of this separately - // so it can be updated even if the DC isn't created yet. - SkMatrix transform_; - - // The current clipping - SkRegion clip_region_; - - // Previously selected brush before the current drawing. - HGDIOBJ previous_brush_; - - // Previously selected pen before the current drawing. - HGDIOBJ previous_pen_; - - DISALLOW_COPY_AND_ASSIGN(VectorPlatformDeviceEmf); -}; - -typedef void (*SkiaEnsureTypefaceCharactersAccessible) - (const LOGFONT& font, const wchar_t* text, unsigned int text_length); - -SK_API void SetSkiaEnsureTypefaceCharactersAccessible( - SkiaEnsureTypefaceCharactersAccessible func); - -} // namespace skia - -#endif // SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_
diff --git a/skia/skia_chrome.gypi b/skia/skia_chrome.gypi index 6a2463521..d689a92 100644 --- a/skia/skia_chrome.gypi +++ b/skia/skia_chrome.gypi
@@ -77,9 +77,6 @@ 'ext/skia_utils_mac.h', 'ext/skia_utils_win.cc', 'ext/skia_utils_win.h', - 'ext/vector_canvas.h', - 'ext/vector_platform_device_emf_win.cc', - 'ext/vector_platform_device_emf_win.h', ], 'conditions': [ [ 'OS == "android" and '
diff --git a/skia/skia_test_expectations.txt b/skia/skia_test_expectations.txt index 0d92ff3..4327f6e 100644 --- a/skia/skia_test_expectations.txt +++ b/skia/skia_test_expectations.txt
@@ -48,16 +48,4 @@ # # START OVERRIDES HERE -# https://codereview.chromium.org/776673002/ -crbug.com/452219 css3/filters/effect-combined.html [ ImageOnlyFailure Pass ] -crbug.com/452219 css3/filters/effect-reference-subregion-hw.html [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/W3C-SVG-1.1/filters-comptran-01-b.svg [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/custom/feComponentTransfer-Discrete.svg [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/custom/feComponentTransfer-Gamma.svg [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/custom/feComponentTransfer-Linear.svg [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/custom/feComponentTransfer-Table.svg [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/dynamic-updates/SVGFEComponentTransferElement-dom-tableValues-attr.html [ ImageOnlyFailure Pass ] -crbug.com/452219 svg/dynamic-updates/SVGFEComponentTransferElement-svgdom-tableValues-prop.html [ ImageOnlyFailure Pass ] - - # END OVERRIDES HERE (this line ensures that the file is newline-terminated)
diff --git a/skia/skia_tests.gyp b/skia/skia_tests.gyp index fcc7347..698493d 100644 --- a/skia/skia_tests.gyp +++ b/skia/skia_tests.gyp
@@ -29,14 +29,8 @@ 'ext/refptr_unittest.cc', 'ext/skia_utils_ios_unittest.mm', 'ext/skia_utils_mac_unittest.mm', - 'ext/vector_canvas_unittest.cc', ], 'conditions': [ - ['OS != "win"', { - 'sources!': [ - 'ext/vector_canvas_unittest.cc', - ], - }], ['OS != "win" and OS != "mac"', { 'sources!': [ 'ext/platform_canvas_unittest.cc',
diff --git a/sync/BUILD.gn b/sync/BUILD.gn index df5f23a..605f7971b 100644 --- a/sync/BUILD.gn +++ b/sync/BUILD.gn
@@ -804,6 +804,7 @@ ":fake_server_jni", ":test_support_sync_fake_server", "//base", + "//testing/gtest", ] } }
diff --git a/sync/internal_api/public/util/experiments.h b/sync/internal_api/public/util/experiments.h index d2b82c62..16fa149 100644 --- a/sync/internal_api/public/util/experiments.h +++ b/sync/internal_api/public/util/experiments.h
@@ -13,29 +13,20 @@ const char kFaviconSyncTag[] = "favicon_sync"; const char kPreCommitUpdateAvoidanceTag[] = "pre_commit_update_avoidance"; -const char kGCMChannelTag[] = "gcm_channel"; const char kEnhancedBookmarksTag[] = "enhanced_bookmarks"; const char kGCMInvalidationsTag[] = "gcm_invalidations"; const char kWalletSyncTag[] = "wallet_sync"; // A structure to hold the enable status of experimental sync features. struct Experiments { - enum GCMChannelState { - UNSET, - SUPPRESSED, - ENABLED, - }; - Experiments() : favicon_sync_limit(200), - gcm_channel_state(UNSET), enhanced_bookmarks_enabled(false), gcm_invalidations_enabled(true), // By default GCM channel is enabled. wallet_sync_enabled(false) {} bool Matches(const Experiments& rhs) { return (favicon_sync_limit == rhs.favicon_sync_limit && - gcm_channel_state == rhs.gcm_channel_state && enhanced_bookmarks_enabled == rhs.enhanced_bookmarks_enabled && enhanced_bookmarks_ext_id == rhs.enhanced_bookmarks_ext_id && gcm_invalidations_enabled == rhs.gcm_invalidations_enabled && @@ -45,9 +36,6 @@ // The number of favicons that a client is permitted to sync. int favicon_sync_limit; - // Enable state of the GCM channel. - GCMChannelState gcm_channel_state; - // Enable the enhanced bookmarks sync datatype. bool enhanced_bookmarks_enabled;
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 1655a24..36c27ba 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc
@@ -970,17 +970,6 @@ // know about this. } - ReadNode gcm_channel_node(&trans); - if (gcm_channel_node.InitByClientTagLookup( - syncer::EXPERIMENTS, - syncer::kGCMChannelTag) == BaseNode::INIT_OK && - gcm_channel_node.GetExperimentsSpecifics().gcm_channel().has_enabled()) { - experiments->gcm_channel_state = - (gcm_channel_node.GetExperimentsSpecifics().gcm_channel().enabled() ? - syncer::Experiments::ENABLED : syncer::Experiments::SUPPRESSED); - found_experiment = true; - } - ReadNode enhanced_bookmarks_node(&trans); if (enhanced_bookmarks_node.InitByClientTagLookup( syncer::EXPERIMENTS, syncer::kEnhancedBookmarksTag) ==
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi index b1ef9cf..bf41fc3 100644 --- a/sync/sync_tests.gypi +++ b/sync/sync_tests.gypi
@@ -475,8 +475,12 @@ 'dependencies': [ 'sync_fake_server_jni_headers', 'test_support_sync_fake_server', + '../testing/gtest.gyp:gtest', '../base/base.gyp:base', ], + 'export_dependent_settings': [ + '../testing/gtest.gyp:gtest', + ], 'sources': [ 'test/fake_server/android/fake_server_helper_android.cc', 'test/fake_server/android/fake_server_helper_android.h',
diff --git a/sync/test/fake_server/android/fake_server_helper_android.cc b/sync/test/fake_server/android/fake_server_helper_android.cc index 725ba63..8491474 100644 --- a/sync/test/fake_server/android/fake_server_helper_android.cc +++ b/sync/test/fake_server/android/fake_server_helper_android.cc
@@ -6,11 +6,17 @@ #include <jni.h> +#include "base/android/jni_string.h" #include "base/basictypes.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "jni/FakeServerHelper_jni.h" +#include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/network_resources.h" #include "sync/test/fake_server/fake_server.h" #include "sync/test/fake_server/fake_server_network_resources.h" +#include "sync/test/fake_server/fake_server_verifier.h" +#include "testing/gtest/include/gtest/gtest.h" FakeServerHelperAndroid::FakeServerHelperAndroid(JNIEnv* env, jobject obj) { } @@ -46,6 +52,32 @@ delete fake_server_ptr; } +jboolean FakeServerHelperAndroid::VerifyEntityCountByTypeAndName( + JNIEnv* env, + jobject obj, + jlong fake_server, + jlong count, + jstring model_type_string, + jstring name) { + syncer::ModelType model_type; + if (!NotificationTypeToRealModelType(base::android::ConvertJavaStringToUTF8( + env, model_type_string), &model_type)) { + LOG(WARNING) << "Invalid ModelType string."; + return false; + } + fake_server::FakeServer* fake_server_ptr = + reinterpret_cast<fake_server::FakeServer*>(fake_server); + fake_server::FakeServerVerifier fake_server_verifier(fake_server_ptr); + testing::AssertionResult result = + fake_server_verifier.VerifyEntityCountByTypeAndName( + count, model_type, base::android::ConvertJavaStringToUTF8(env, name)); + + if (!result) + LOG(WARNING) << result.message(); + + return result; +} + // static bool FakeServerHelperAndroid::Register(JNIEnv* env) { return RegisterNativesImpl(env);
diff --git a/sync/test/fake_server/android/fake_server_helper_android.h b/sync/test/fake_server/android/fake_server_helper_android.h index 24e1d9e..dfbdb7b 100644 --- a/sync/test/fake_server/android/fake_server_helper_android.h +++ b/sync/test/fake_server/android/fake_server_helper_android.h
@@ -30,6 +30,15 @@ // CreateFakeServer). void DeleteFakeServer(JNIEnv* env, jobject obj, jlong fake_server); + // Returns true if and only if |fake_server| contains |count| entities that + // match |model_type_string| and |name|. + jboolean VerifyEntityCountByTypeAndName(JNIEnv* env, + jobject obj, + jlong fake_server, + jlong count, + jstring model_type_string, + jstring name); + private: virtual ~FakeServerHelperAndroid(); };
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 01d893f..b5fc002 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -743,6 +743,9 @@ "ppapi_unittests", "printing_unittests", "remoting_unittests", + "sbox_unittests", + "sbox_integration_tests", + "sbox_validation_tests", "ipc_tests", "sync_unit_tests", "skia_unittests", @@ -791,6 +794,9 @@ "ppapi_unittests", "printing_unittests", "remoting_unittests", + "sbox_unittests", + "sbox_integration_tests", + "sbox_validation_tests", "ipc_tests", "sync_unit_tests", "skia_unittests",
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json index 7244be8..3d5b728 100644 --- a/testing/buildbot/chromium.memory.fyi.json +++ b/testing/buildbot/chromium.memory.fyi.json
@@ -4,7 +4,12 @@ "accessibility_unittests", "app_list_unittests", "aura_unittests", - "base_unittests", + { + "test": "base_unittests", + "swarming": { + "can_use_on_swarming_builders": true + } + }, "cacheinvalidation_unittests", "cast_unittests", "cc_unittests",
diff --git a/testing/legion/__init__.py b/testing/legion/__init__.py new file mode 100644 index 0000000..50b23df --- /dev/null +++ b/testing/legion/__init__.py
@@ -0,0 +1,3 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file.
diff --git a/testing/legion/client_controller.py b/testing/legion/client_controller.py new file mode 100755 index 0000000..dd80c29 --- /dev/null +++ b/testing/legion/client_controller.py
@@ -0,0 +1,51 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""The main client_controller code. + +This code is the main entry point for the client machines and handles +registering with the host server and running the local RPC server. +""" + +import argparse +import logging +import socket +import sys +import time + +#pylint: disable=relative-import +import client_rpc_server +import common_lib + + +def main(): + print ' '.join(sys.argv) + common_lib.InitLogging() + logging.info('Client controller starting') + + parser = argparse.ArgumentParser() + parser.add_argument('--otp', + help='One time token used to authenticate with the host') + parser.add_argument('--host', + help='The ip address of the host') + parser.add_argument('--idle-timeout', type=int, + default=common_lib.DEFAULT_TIMEOUT_SECS, + help='The idle timeout for the rpc server in seconds') + args, _ = parser.parse_known_args() + + logging.info( + 'Registering with discovery server at %s using OTP %s', args.host, + args.otp) + server = common_lib.ConnectToServer(args.host).RegisterClient( + args.otp, common_lib.MY_IP) + + server = client_rpc_server.RPCServer(args.host, args.idle_timeout) + + server.serve_forever() + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/testing/legion/client_lib.py b/testing/legion/client_lib.py new file mode 100644 index 0000000..4d6a633f --- /dev/null +++ b/testing/legion/client_lib.py
@@ -0,0 +1,214 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Defines the client library.""" + +import argparse +import datetime +import logging +import os +import socket +import subprocess +import sys +import tempfile +import threading +import xmlrpclib + +#pylint: disable=relative-import +import common_lib + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) +SWARMING_DIR = os.path.join(THIS_DIR, '..', '..', 'tools/swarming_client') +ISOLATE_PY = os.path.join(SWARMING_DIR, 'isolate.py') +SWARMING_PY = os.path.join(SWARMING_DIR, 'swarming.py') + + +class Error(Exception): + pass + + +class ConnectionTimeoutError(Error): + pass + + +class ClientController(object): + """Creates, configures, and controls a client machine.""" + + _client_count = 0 + _controllers = [] + + def __init__(self, isolate_file, config_vars, dimensions, priority=100, + idle_timeout_secs=common_lib.DEFAULT_TIMEOUT_SECS, + connection_timeout_secs=common_lib.DEFAULT_TIMEOUT_SECS, + verbosity='ERROR', name=None): + assert isinstance(config_vars, dict) + assert isinstance(dimensions, dict) + type(self)._controllers.append(self) + type(self)._client_count += 1 + self.verbosity = verbosity + self._name = name or 'Client%d' % type(self)._client_count + self._priority = priority + self._isolate_file = isolate_file + self._isolated_file = isolate_file + 'd' + self._idle_timeout_secs = idle_timeout_secs + self._config_vars = config_vars + self._dimensions = dimensions + self._connect_event = threading.Event() + self._connected = False + self._ip_address = None + self._otp = self._CreateOTP() + self._rpc = None + + parser = argparse.ArgumentParser() + parser.add_argument('--isolate-server') + parser.add_argument('--swarming-server') + parser.add_argument('--client-connection-timeout-secs', + default=common_lib.DEFAULT_TIMEOUT_SECS) + args, _ = parser.parse_known_args() + + self._isolate_server = args.isolate_server + self._swarming_server = args.swarming_server + self._connection_timeout_secs = (connection_timeout_secs or + args.client_connection_timeout_secs) + + @property + def name(self): + return self._name + + @property + def otp(self): + return self._otp + + @property + def connected(self): + return self._connected + + @property + def connect_event(self): + return self._connect_event + + @property + def rpc(self): + return self._rpc + + @property + def verbosity(self): + return self._verbosity + + @verbosity.setter + def verbosity(self, level): + """Sets the verbosity level as a string. + + Either a string ('INFO', 'DEBUG', etc) or a logging level (logging.INFO, + logging.DEBUG, etc) is allowed. + """ + assert isinstance(level, (str, int)) + if isinstance(level, int): + level = logging.getLevelName(level) + self._verbosity = level #pylint: disable=attribute-defined-outside-init + + @classmethod + def ReleaseAllControllers(cls): + for controller in cls._controllers: + controller.Release() + + def _CreateOTP(self): + """Creates the OTP.""" + host_name = socket.gethostname() + test_name = os.path.basename(sys.argv[0]) + creation_time = datetime.datetime.utcnow() + otp = 'client:%s-host:%s-test:%s-creation:%s' % ( + self._name, host_name, test_name, creation_time) + return otp + + def Create(self): + """Creates the client machine.""" + logging.info('Creating %s', self.name) + self._connect_event.clear() + self._ExecuteIsolate() + self._ExecuteSwarming() + + def WaitForConnection(self): + """Waits for the client machine to connect. + + Raises: + ConnectionTimeoutError if the client doesn't connect in time. + """ + logging.info('Waiting for %s to connect with a timeout of %d seconds', + self._name, self._connection_timeout_secs) + self._connect_event.wait(self._connection_timeout_secs) + if not self._connect_event.is_set(): + raise ConnectionTimeoutError('%s failed to connect' % self.name) + + def Release(self): + """Quits the client's RPC server so it can release the machine.""" + if self._rpc is not None and self._connected: + logging.info('Releasing %s', self._name) + try: + self._rpc.Quit() + except (socket.error, xmlrpclib.Fault): + logging.error('Unable to connect to %s to call Quit', self.name) + self._rpc = None + self._connected = False + + def _ExecuteIsolate(self): + """Executes isolate.py.""" + cmd = [ + 'python', + ISOLATE_PY, + 'archive', + '--isolate', self._isolate_file, + '--isolated', self._isolated_file, + ] + + if self._isolate_server: + cmd.extend(['--isolate-server', self._isolate_server]) + for key, value in self._config_vars.iteritems(): + cmd.extend(['--config-var', key, value]) + + self._ExecuteProcess(cmd) + + def _ExecuteSwarming(self): + """Executes swarming.py.""" + cmd = [ + 'python', + SWARMING_PY, + 'trigger', + self._isolated_file, + '--priority', str(self._priority), + ] + + if self._isolate_server: + cmd.extend(['--isolate-server', self._isolate_server]) + if self._swarming_server: + cmd.extend(['--swarming', self._swarming_server]) + for key, value in self._dimensions.iteritems(): + cmd.extend(['--dimension', key, value]) + + cmd.extend([ + '--', + '--host', common_lib.MY_IP, + '--otp', self._otp, + '--verbosity', self._verbosity, + '--idle-timeout', str(self._idle_timeout_secs), + ]) + + self._ExecuteProcess(cmd) + + def _ExecuteProcess(self, cmd): + """Executes a process, waits for it to complete, and checks for success.""" + logging.debug('Running %s', ' '.join(cmd)) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + _, stderr = p.communicate() + if p.returncode != 0: + stderr.seek(0) + raise Error(stderr) + + def OnConnect(self, ip_address): + """Receives client ip address on connection.""" + self._ip_address = ip_address + self._connected = True + self._rpc = common_lib.ConnectToServer(self._ip_address) + logging.info('%s connected from %s', self._name, ip_address) + self._connect_event.set()
diff --git a/testing/legion/client_rpc_methods.py b/testing/legion/client_rpc_methods.py new file mode 100644 index 0000000..24a552e --- /dev/null +++ b/testing/legion/client_rpc_methods.py
@@ -0,0 +1,42 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Defines the client RPC methods.""" + +import logging +import subprocess +import threading + + +class RPCMethods(object): + """Class exposing RPC methods.""" + + def __init__(self, server): + self.server = server + + def Echo(self, message): + """Simple RPC method to print and return a message.""" + logging.info('Echoing %s', message) + return 'echo %s' % str(message) + + def Subprocess(self, cmd): + """Run the commands in a subprocess. + + Returns: + (returncode, stdout, stderr). + """ + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + return (p.returncode, stdout, stderr) + + def Quit(self): + """Call server.shutdown in another thread. + + This is needed because server.shutdown waits for the server to actually + quit. However the server cannot shutdown until it completes handling this + call. Calling this in the same thread results in a deadlock. + """ + t = threading.Thread(target=self.server.shutdown) + t.start()
diff --git a/testing/legion/client_rpc_server.py b/testing/legion/client_rpc_server.py new file mode 100644 index 0000000..7a5f565 --- /dev/null +++ b/testing/legion/client_rpc_server.py
@@ -0,0 +1,128 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""The client RPC server code. + +This server is an XML-RPC server which serves code from +client_rpc_methods.RPCMethods. + +This server will run until shutdown is called on the server object. This can +be achieved in 2 ways: + +- Calling the Quit RPC method defined in RPCMethods +- Not receiving any calls within the idle_timeout_secs time. +""" + +import logging +import threading +import time +import xmlrpclib +import SimpleXMLRPCServer +import SocketServer + +#pylint: disable=relative-import +import client_rpc_methods +import common_lib + + +class RequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): + """Restricts access to only specified IP address. + + This call assumes the server is RPCServer. + """ + + def do_POST(self): + """Verifies the client is authorized to perform RPCs.""" + if self.client_address[0] != self.server.authorized_address: + logging.error('Received unauthorized RPC request from %s', + self.client_address[0]) + self.send_response(403) + response = 'Forbidden' + self.send_header('Content-type', 'text/plain') + self.send_header('Content-length', str(len(response))) + self.end_headers() + self.wfile.write(response) + else: + return SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) + + +class RPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, + SocketServer.ThreadingMixIn): + """Restricts all endpoints to only specified IP addresses.""" + + def __init__(self, authorized_address, + idle_timeout_secs=common_lib.DEFAULT_TIMEOUT_SECS): + SimpleXMLRPCServer.SimpleXMLRPCServer.__init__( + self, (common_lib.SERVER_ADDRESS, common_lib.SERVER_PORT), + allow_none=True, logRequests=False, + requestHandler=RequestHandler) + + self.authorized_address = authorized_address + self.idle_timeout_secs = idle_timeout_secs + self.register_instance(client_rpc_methods.RPCMethods(self)) + + self._shutdown_requested_event = threading.Event() + self._rpc_received_event = threading.Event() + self._idle_thread = threading.Thread(target=self._CheckForIdleQuit) + + def shutdown(self): + """Shutdown the server. + + This overloaded method sets the _shutdown_requested_event to allow the + idle timeout thread to quit. + """ + self._shutdown_requested_event.set() + SimpleXMLRPCServer.SimpleXMLRPCServer.shutdown(self) + logging.info('Server shutdown complete') + + def serve_forever(self, poll_interval=0.5): + """Serve forever. + + This overloaded method starts the idle timeout thread before calling + serve_forever. This ensures the idle timer thread doesn't get started + without the server running. + + Args: + poll_interval: The interval to poll for shutdown. + """ + logging.info('RPC server starting') + self._idle_thread.start() + SimpleXMLRPCServer.SimpleXMLRPCServer.serve_forever(self, poll_interval) + + def _dispatch(self, method, params): + """Dispatch the call to the correct method with the provided params. + + This overloaded method adds logging to help trace connection and + call problems. + + Args: + method: The method name to call. + params: A tuple of parameters to pass. + + Returns: + The result of the parent class' _dispatch method. + """ + logging.debug('Calling %s%s', method, params) + self._rpc_received_event.set() + return SimpleXMLRPCServer.SimpleXMLRPCServer._dispatch(self, method, params) + + def _CheckForIdleQuit(self): + """Check for, and exit, if the server is idle for too long. + + This method must be run in a separate thread to avoid a deadlock when + calling server.shutdown. + """ + timeout = time.time() + self.idle_timeout_secs + while time.time() < timeout: + if self._shutdown_requested_event.is_set(): + # An external source called shutdown() + return + elif self._rpc_received_event.is_set(): + logging.debug('Resetting the idle timeout') + timeout = time.time() + self.idle_timeout_secs + self._rpc_received_event.clear() + time.sleep(1) + # We timed out, kill the server + logging.warning('Shutting down the server due to the idle timeout') + self.shutdown()
diff --git a/testing/legion/common_lib.py b/testing/legion/common_lib.py new file mode 100644 index 0000000..b66481e0 --- /dev/null +++ b/testing/legion/common_lib.py
@@ -0,0 +1,40 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Common library methods used by both host and client controllers.""" + +import argparse +import logging +import socket +import xmlrpclib + +LOGGING_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'WARN', 'ERROR'] +MY_IP = socket.gethostbyname(socket.gethostname()) +SERVER_ADDRESS = '' +SERVER_PORT = 31710 +DEFAULT_TIMEOUT_SECS = 20 * 60 # 30 minutes + + +def InitLogging(): + """Initialize the logging module. + + Raises: + argparse.ArgumentError if the --verbosity arg is incorrect. + """ + parser = argparse.ArgumentParser() + logging_action = parser.add_argument('--verbosity', default='ERROR') + args, _ = parser.parse_known_args() + if args.verbosity not in LOGGING_LEVELS: + raise argparse.ArgumentError( + logging_action, 'Only levels %s supported' % str(LOGGING_LEVELS)) + logging.basicConfig( + format='%(asctime)s %(filename)s:%(lineno)s %(levelname)s] %(message)s', + datefmt='%H:%M:%S', level=args.verbosity) + + +def ConnectToServer(server): + """Connect to an RPC server.""" + addr = 'http://%s:%d' % (server, SERVER_PORT) + logging.debug('Connecting to RPC server at %s', addr) + return xmlrpclib.Server(addr)
diff --git a/testing/legion/discovery_server.py b/testing/legion/discovery_server.py new file mode 100644 index 0000000..94786ce --- /dev/null +++ b/testing/legion/discovery_server.py
@@ -0,0 +1,55 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""The discovery server used to register clients. + +The discovery server is started by the host controller and allows the clients +to register themselves when they start. Authentication of the client controllers +is based on an OTP passed to the client controller binary on startup. +""" + +import logging +import threading +import xmlrpclib +import SimpleXMLRPCServer + +#pylint: disable=relative-import +import common_lib + + +class DiscoveryServer(object): + """Discovery server run on the host.""" + + def __init__(self): + self._expected_clients = {} + self._rpc_server = None + self._thread = None + + def _RegisterClientRPC(self, otp, ip): + """The RPC used by a client to register with the discovery server.""" + assert otp in self._expected_clients + cb = self._expected_clients.pop(otp) + cb(ip) + + def RegisterClientCallback(self, otp, callback): + """Registers a callback associated with an OTP.""" + assert callable(callback) + self._expected_clients[otp] = callback + + def Start(self): + """Starts the discovery server.""" + logging.debug('Starting discovery server') + self._rpc_server = SimpleXMLRPCServer.SimpleXMLRPCServer( + (common_lib.SERVER_ADDRESS, common_lib.SERVER_PORT), + allow_none=True, logRequests=False) + self._rpc_server.register_function( + self._RegisterClientRPC, 'RegisterClient') + self._thread = threading.Thread(target=self._rpc_server.serve_forever) + self._thread.start() + + def Shutdown(self): + """Shuts the discovery server down.""" + if self._thread and self._thread.is_alive(): + logging.debug('Shutting down discovery server') + self._rpc_server.shutdown()
diff --git a/testing/legion/examples/hello_world/client_test.isolate b/testing/legion/examples/hello_world/client_test.isolate new file mode 100644 index 0000000..7135ef2 --- /dev/null +++ b/testing/legion/examples/hello_world/client_test.isolate
@@ -0,0 +1,23 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'includes': [ + '../../legion.isolate' + ], + 'conditions': [ + ['multi_machine == 1', { + 'variables': { + 'command': [ + 'python', + '../../client_controller.py', + ], + 'files': [ + 'client_test.py', + 'client_test.isolate' + ], + }, + }], + ], +}
diff --git a/testing/legion/examples/hello_world/client_test.py b/testing/legion/examples/hello_world/client_test.py new file mode 100755 index 0000000..0333f7b --- /dev/null +++ b/testing/legion/examples/hello_world/client_test.py
@@ -0,0 +1,27 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""A simple client test module. + +This module is invoked by the host by calling the client controller's +Subprocess RPC method. The name is passed in as a required argument on the +command line. +""" + +import argparse +import os +import sys + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('name') + args = parser.parse_args() + print 'Hello world from', args.name + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/testing/legion/examples/hello_world/host_test.isolate b/testing/legion/examples/hello_world/host_test.isolate new file mode 100644 index 0000000..da4ee4e3 --- /dev/null +++ b/testing/legion/examples/hello_world/host_test.isolate
@@ -0,0 +1,22 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'includes': [ + '../../legion.isolate', + 'client_test.isolate' + ], + 'conditions': [ + ['multi_machine == 1', { + 'variables': { + 'command': [ + 'host_test.py', + ], + 'files': [ + 'host_test.py', + ], + }, + }], + ] +}
diff --git a/testing/legion/examples/hello_world/host_test.py b/testing/legion/examples/hello_world/host_test.py new file mode 100755 index 0000000..77eca06 --- /dev/null +++ b/testing/legion/examples/hello_world/host_test.py
@@ -0,0 +1,74 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""A simple host test module. + +This module runs on the host machine and is responsible for creating 2 +client machines, waiting for them, and running RPC calls on them. +""" + +# Map the legion directory so we can import the host controller. +import sys +sys.path.append('../../') + +import logging +import time + +import host_controller + + +class ExampleController(host_controller.HostController): + """A simple example controller for a test.""" + + def __init__(self): + super(ExampleController, self).__init__() + self.client1 = None + self.client2 = None + + def CreateClient(self): + """Create a client object and set the proper values.""" + client = self.NewClient( + isolate_file='client_test.isolate', + config_vars={'multi_machine': '1'}, + dimensions={'os': 'Linux', 'pool': 'legion'}, priority=200, + idle_timeout_secs=90, connection_timeout_secs=90, + verbosity=logging.INFO) + client.Create() + return client + + def SetUp(self): + """Create the client machines and wait until they connect. + + In this call the actual creation of the client machines is done in parallel + by the system. The WaitForConnect calls are performed in series but will + return as soon as the clients connect. + """ + self.client1 = self.CreateClient() + self.client2 = self.CreateClient() + self.client1.WaitForConnection() + self.client2.WaitForConnection() + + def Task(self): + """Main method to run the task code.""" + self.CallEcho(self.client1) + self.CallEcho(self.client2) + self.CallClientTest(self.client1) + self.CallClientTest(self.client2) + + def CallEcho(self, client): + """Call rpc.Echo on a client.""" + logging.info('Calling Echo on %s', client.name) + logging.info(self.client1.rpc.Echo(client.name)) + + def CallClientTest(self, client): + """Call client_test.py name on a client.""" + logging.info('Calling Subprocess to run "./client_test.py %s"', client.name) + retcode, stdout, stderr = client.rpc.Subprocess( + ['./client_test.py', client.name]) + logging.info('retcode: %s, stdout: %s, stderr: %s', retcode, stdout, stderr) + + +if __name__ == '__main__': + ExampleController().RunController()
diff --git a/testing/legion/host_controller.py b/testing/legion/host_controller.py new file mode 100644 index 0000000..dadcba4 --- /dev/null +++ b/testing/legion/host_controller.py
@@ -0,0 +1,70 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Defines the host controller base library. + +This module is the basis on which host controllers are built and executed. +""" + +import logging +import sys + +#pylint: disable=relative-import +import client_lib +import common_lib +import discovery_server + + +class HostController(object): + """The base host controller class.""" + + def __init__(self): + self._discovery_server = discovery_server.DiscoveryServer() + + def SetUp(self): + """Setup method used by the subclass.""" + pass + + def Task(self): + """Main task method used by the subclass.""" + pass + + def TearDown(self): + """Teardown method used by the subclass.""" + pass + + def NewClient(self, *args, **kwargs): + controller = client_lib.ClientController(*args, **kwargs) + self._discovery_server.RegisterClientCallback( + controller.otp, controller.OnConnect) + return controller + + def RunController(self): + """Main entry point for the controller.""" + print ' '.join(sys.argv) + common_lib.InitLogging() + self._discovery_server.Start() + + error = None + tb = None + try: + self.SetUp() + self.Task() + except Exception as e: + # Defer raising exceptions until after TearDown and _TearDown are called. + error = e + tb = sys.exc_info()[-1] + try: + self.TearDown() + except Exception as e: + # Defer raising exceptions until after _TearDown is called. + # Note that an error raised here will obscure any errors raised + # previously. + error = e + tb = sys.exc_info()[-1] + + self._discovery_server.Shutdown() + client_lib.ClientController.ReleaseAllControllers() + if error: + raise error, None, tb #pylint: disable=raising-bad-type
diff --git a/testing/legion/legion.isolate b/testing/legion/legion.isolate new file mode 100644 index 0000000..463764d --- /dev/null +++ b/testing/legion/legion.isolate
@@ -0,0 +1,20 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'files': [ + '__init__.py', + 'client_controller.py', + 'client_lib.py', + 'client_rpc_methods.py', + 'client_rpc_server.py', + 'common_lib.py', + 'discovery_server.py', + 'host_controller.py', + 'legion.isolate', + '../../tools/swarming_client/', + ], + }, +}
diff --git a/testing/test_env.py b/testing/test_env.py index 48cbac9..66a3721 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -124,12 +124,14 @@ return extra_env -def get_sanitizer_symbolize_command(json_path=None): +def get_sanitizer_symbolize_command(json_path=None, executable_path=None): """Construct the command to invoke offline symbolization script.""" script_path = '../tools/valgrind/asan/asan_symbolize.py' cmd = [sys.executable, script_path] if json_path is not None: cmd.append('--test-summary-json-file=%s' % json_path) + if executable_path is not None: + cmd.append('--executable-path=%s' % executable_path) return cmd @@ -149,7 +151,8 @@ return try: - symbolize_command = get_sanitizer_symbolize_command(json_path=json_path) + symbolize_command = get_sanitizer_symbolize_command( + json_path=json_path, executable_path=cmd[0]) p = subprocess.Popen(symbolize_command, stderr=subprocess.PIPE, env=env) (_, stderr) = p.communicate() except OSError as e: @@ -185,10 +188,9 @@ if asan or lsan or msan or tsan: extra_env.update(get_sanitizer_env(cmd, asan, lsan, msan, tsan)) - if lsan or tsan or (asan and sys.platform == 'win32'): - # ASan is not yet sandbox-friendly on Windows (http://crbug.com/382867). - # LSan and TSan are not sandbox-friendly. - cmd.append('--no-sandbox') + if lsan or tsan: + # LSan and TSan are not sandbox-friendly. + cmd.append('--no-sandbox') cmd = trim_cmd(cmd) @@ -208,8 +210,9 @@ # Need to pipe to the symbolizer script. p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE, stderr=sys.stdout) - p2 = subprocess.Popen(get_sanitizer_symbolize_command(), - env=env, stdin=p1.stdout) + p2 = subprocess.Popen( + get_sanitizer_symbolize_command(executable_path=cmd[0]), + env=env, stdin=p1.stdout) p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. p1.wait() p2.wait()
diff --git a/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 b/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 index e15eeb15..94c02d29 100644 --- a/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 +++ b/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1
@@ -1 +1 @@ -fd80d8d02666517d0781d3039499b4131e5d3e4e \ No newline at end of file +e73c227c9cfacfc5fecaa22ee3555b90925f96c2 \ No newline at end of file
diff --git a/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 b/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 index e2d07aa3..b415234 100644 --- a/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 +++ b/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1
@@ -1 +1 @@ -905e9e6eb9b0e11f0587177cfbaf9f7822736f34 \ No newline at end of file +05497e34b29c01dd82df76d2fbdf017d4a2c4214 \ No newline at end of file
diff --git a/third_party/binutils/README.chromium b/third_party/binutils/README.chromium index 5daa8d7..d20934b 100644 --- a/third_party/binutils/README.chromium +++ b/third_party/binutils/README.chromium
@@ -19,5 +19,11 @@ * ehframe-race.patch for http://crbug.com/161942 from upstream change https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=635aa30e3ae9735e362cfd1cda2be9f7b65b32a2 + * unlock-thin.patch for http://crbug.com/453195 from upstream change + https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=2cfbf2fece582c29df348104b28677c38a8301f4 + + * plugin-dso-fix.patch for http://crbug.com/453195 from upstream change + https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=3c537f7fdb11f02f7082749f3f21dfdd2c2025e8 + * (build-all.sh|build-one.sh|upload.sh) scripts for building the binutils binaries and uploading them to Google storage.
diff --git a/third_party/binutils/build-all.sh b/third_party/binutils/build-all.sh index fc00db19..a39984ca 100755 --- a/third_party/binutils/build-all.sh +++ b/third_party/binutils/build-all.sh
@@ -44,6 +44,8 @@ ( cd binutils-$VERSION patch -p1 < ../ehframe-race.patch + patch -p1 < ../unlock-thin.patch + patch -p1 < ../plugin-dso-fix.patch ) fi @@ -106,6 +108,10 @@ # Copy them out of the chroot cp -a "$BUILDDIR/output/$ARCHNAME" "$OUTPUTDIR" + # Copy plugin header out of the chroot + mkdir "$OUTPUTDIR/$ARCHNAME/include" + cp "$BUILDDIR/binutils-$VERSION/include/plugin-api.h" "$OUTPUTDIR/$ARCHNAME/include/" + # Clean up chroot sudo rm -rf "$BUILDDIR" done
diff --git a/third_party/binutils/plugin-dso-fix.patch b/third_party/binutils/plugin-dso-fix.patch new file mode 100644 index 0000000..55897568 --- /dev/null +++ b/third_party/binutils/plugin-dso-fix.patch
@@ -0,0 +1,97 @@ +commit 3c537f7fdb11f02f7082749f3f21dfdd2c2025e8 +Author: Peter Collingbourne <pcc@google.com> +Date: Wed Feb 4 09:47:28 2015 -0800 + + Resolve forwarding symbols in plugins. + + 2015-02-04 Peter Collingbourne <pcc@google.com> + + * plugin.cc (Pluginobj::get_symbol_resolution_info): Resolve + forwarding symbols when computing symbol resolution info for plugins. + +diff --git a/gold/plugin.cc b/gold/plugin.cc +index bde8c78..68da8e3 100644 +--- a/gold/plugin.cc ++++ b/gold/plugin.cc +@@ -914,7 +914,8 @@ is_visible_from_outside(Symbol* lsym) + // Get symbol resolution info. + + ld_plugin_status +-Pluginobj::get_symbol_resolution_info(int nsyms, ++Pluginobj::get_symbol_resolution_info(Symbol_table* symtab, ++ int nsyms, + ld_plugin_symbol* syms, + int version) const + { +@@ -943,6 +944,8 @@ Pluginobj::get_symbol_resolution_info(int nsyms, + { + ld_plugin_symbol* isym = &syms[i]; + Symbol* lsym = this->symbols_[i]; ++ if (lsym->is_forwarder()) ++ lsym = symtab->resolve_forwards(lsym); + ld_plugin_symbol_resolution res = LDPR_UNKNOWN; + + if (lsym->is_undefined()) +@@ -1511,14 +1514,16 @@ static enum ld_plugin_status + get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms) + { + gold_assert(parameters->options().has_plugins()); +- Object* obj = parameters->options().plugins()->object( ++ Plugin_manager* plugins = parameters->options().plugins(); ++ Object* obj = plugins->object( + static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle))); + if (obj == NULL) + return LDPS_ERR; + Pluginobj* plugin_obj = obj->pluginobj(); + if (plugin_obj == NULL) + return LDPS_ERR; +- return plugin_obj->get_symbol_resolution_info(nsyms, syms, 1); ++ Symbol_table* symtab = plugins->symtab(); ++ return plugin_obj->get_symbol_resolution_info(symtab, nsyms, syms, 1); + } + + // Version 2 of the above. The only difference is that this version +@@ -1528,14 +1533,16 @@ static enum ld_plugin_status + get_symbols_v2(const void* handle, int nsyms, ld_plugin_symbol* syms) + { + gold_assert(parameters->options().has_plugins()); +- Object* obj = parameters->options().plugins()->object( ++ Plugin_manager* plugins = parameters->options().plugins(); ++ Object* obj = plugins->object( + static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle))); + if (obj == NULL) + return LDPS_ERR; + Pluginobj* plugin_obj = obj->pluginobj(); + if (plugin_obj == NULL) + return LDPS_ERR; +- return plugin_obj->get_symbol_resolution_info(nsyms, syms, 2); ++ Symbol_table* symtab = plugins->symtab(); ++ return plugin_obj->get_symbol_resolution_info(symtab, nsyms, syms, 2); + } + + // Add a new (real) input file generated by a plugin. +diff --git a/gold/plugin.h b/gold/plugin.h +index ef78b84..f926879 100644 +--- a/gold/plugin.h ++++ b/gold/plugin.h +@@ -282,6 +282,10 @@ class Plugin_manager + input_objects() const + { return this->input_objects_; } + ++ Symbol_table* ++ symtab() ++ { return this->symtab_; } ++ + Layout* + layout() + { return this->layout_; } +@@ -396,7 +400,8 @@ class Pluginobj : public Object + + // Fill in the symbol resolution status for the given plugin symbols. + ld_plugin_status +- get_symbol_resolution_info(int nsyms, ++ get_symbol_resolution_info(Symbol_table* symtab, ++ int nsyms, + ld_plugin_symbol* syms, + int version) const; +
diff --git a/third_party/binutils/unlock-thin.patch b/third_party/binutils/unlock-thin.patch new file mode 100644 index 0000000..6a4b6a7 --- /dev/null +++ b/third_party/binutils/unlock-thin.patch
@@ -0,0 +1,129 @@ +commit 2cfbf2fece582c29df348104b28677c38a8301f4 +Author: Cary Coutant <ccoutant@google.com> +Date: Tue Feb 3 19:54:57 2015 -0800 + + Fix a file descriptor leak in gold. + + When an LTO linker plugin claims an external member of a thin archive, gold + does not properly unlock the file and make its file descriptor available for + reuse. This patch fixes the problem by modifying Archive::include_member to + unlock the object file via an RAII class instance, ensuring that it will be + unlocked no matter what path is taken through the function. + + gold/ + PR gold/15660 + * archive.cc (Thin_archive_object_unlocker): New class. + (Archive::include_member): Unlock external members of thin archives. + * testsuite/Makefile.am (plugin_test_1): Rename .syms files. + (plugin_test_2): Likewise. + (plugin_test_3): Likewise. + (plugin_test_4): Likewise. + (plugin_test_5): Likewise. + (plugin_test_6): Likewise. + (plugin_test_7): Likewise. + (plugin_test_8): Likewise. + (plugin_test_9): Likewise. + (plugin_test_10): Likewise. + (plugin_test_11): New test case. + * testsuite/Makefile.in: Regenerate. + * testsuite/plugin_test.c (claim_file_hook): Check for parallel .syms + file to decide whether to claim file. + (all_symbols_read_hook): Likewise. + * testsuite/plugin_test_1.sh: Adjust expected output. + * testsuite/plugin_test_2.sh: Likewise. + * testsuite/plugin_test_3.sh: Likewise. + * testsuite/plugin_test_6.sh: Likewise. + * testsuite/plugin_test_tls.sh: Likewise. + * testsuite/plugin_test_11.sh: New testcase. + +diff --git a/gold/archive.cc b/gold/archive.cc +index 69107f5..6d25980 100644 +--- a/gold/archive.cc ++++ b/gold/archive.cc +@@ -930,6 +930,32 @@ Archive::count_members() + return ret; + } + ++// RAII class to ensure we unlock the object if it's a member of a ++// thin archive. We can't use Task_lock_obj in Archive::include_member ++// because the object file is already locked when it's opened by ++// get_elf_object_for_member. ++ ++class Thin_archive_object_unlocker ++{ ++ public: ++ Thin_archive_object_unlocker(const Task *task, Object* obj) ++ : task_(task), obj_(obj) ++ { } ++ ++ ~Thin_archive_object_unlocker() ++ { ++ if (this->obj_->offset() == 0) ++ this->obj_->unlock(this->task_); ++ } ++ ++ private: ++ Thin_archive_object_unlocker(const Thin_archive_object_unlocker&); ++ Thin_archive_object_unlocker& operator=(const Thin_archive_object_unlocker&); ++ ++ const Task* task_; ++ Object* obj_; ++}; ++ + // Include an archive member in the link. OFF is the file offset of + // the member header. WHY is the reason we are including this member. + // Return true if we added the member or if we had an error, return +@@ -978,6 +1004,10 @@ Archive::include_member(Symbol_table* symtab, Layout* layout, + return unconfigured ? false : true; + } + ++ // If the object is an external member of a thin archive, ++ // unlock it when we're done here. ++ Thin_archive_object_unlocker unlocker(this->task_, obj); ++ + if (mapfile != NULL) + mapfile->report_include_archive_member(obj->name(), sym, why); + +@@ -991,31 +1021,21 @@ Archive::include_member(Symbol_table* symtab, Layout* layout, + + if (!input_objects->add_object(obj)) + { +- // If this is an external member of a thin archive, unlock the +- // file. +- if (obj->offset() == 0) +- obj->unlock(this->task_); + delete obj; ++ return true; + } +- else +- { +- { +- if (layout->incremental_inputs() != NULL) +- layout->incremental_inputs()->report_object(obj, 0, this, NULL); +- Read_symbols_data sd; +- obj->read_symbols(&sd); +- obj->layout(symtab, layout, &sd); +- obj->add_symbols(symtab, &sd, layout); +- } +- +- // If this is an external member of a thin archive, unlock the file +- // for the next task. +- if (obj->offset() == 0) +- obj->unlock(this->task_); + +- this->included_member_ = true; +- } ++ if (layout->incremental_inputs() != NULL) ++ layout->incremental_inputs()->report_object(obj, 0, this, NULL); ++ ++ { ++ Read_symbols_data sd; ++ obj->read_symbols(&sd); ++ obj->layout(symtab, layout, &sd); ++ obj->add_symbols(symtab, &sd, layout); ++ } + ++ this->included_member_ = true; + return true; + } +
diff --git a/third_party/closure_compiler/compiled_resources.gyp b/third_party/closure_compiler/compiled_resources.gyp index 51edb1a..407b120a 100644 --- a/third_party/closure_compiler/compiled_resources.gyp +++ b/third_party/closure_compiler/compiled_resources.gyp
@@ -21,6 +21,7 @@ '../../ui/file_manager/file_manager/foreground/js/metadata/compiled_resources.gyp:*', '../../ui/file_manager/gallery/js/compiled_resources.gyp:*', '../../ui/file_manager/image_loader/compiled_resources.gyp:*', + '../../ui/file_manager/video_player/js/compiled_resources.gyp:*', '../../ui/webui/resources/js/chromeos/compiled_resources.gyp:*', '../../ui/webui/resources/js/chromeos/compiled_resources.gyp:*', '../../ui/webui/resources/js/compiled_resources.gyp:*',
diff --git a/third_party/fontconfig/OWNERS b/third_party/fontconfig/OWNERS index 7e5af1db..82160d5 100644 --- a/third_party/fontconfig/OWNERS +++ b/third_party/fontconfig/OWNERS
@@ -1,3 +1,2 @@ spang@chromium.org -rjkroege@chromium.org -spang@chromium.org +dnicoara@chromium.org
diff --git a/third_party/fontconfig/chromium/empty.cc b/third_party/fontconfig/chromium/empty.cc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/fontconfig/chromium/empty.cc
diff --git a/third_party/fontconfig/fontconfig.gyp b/third_party/fontconfig/fontconfig.gyp index c3b350c..3565a7f 100644 --- a/third_party/fontconfig/fontconfig.gyp +++ b/third_party/fontconfig/fontconfig.gyp
@@ -26,6 +26,7 @@ }], ], 'sources': [ + 'chromium/empty.cc', 'src/src/fcarch.h', 'src/src/fcatomic.c', 'src/src/fcblanks.c',
diff --git a/third_party/khronos/EGL/eglext.h b/third_party/khronos/EGL/eglext.h index 3b26a79..0acc280 100644 --- a/third_party/khronos/EGL/eglext.h +++ b/third_party/khronos/EGL/eglext.h
@@ -563,6 +563,11 @@ #define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 #endif +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A +#endif /* EGL_ARM_implicit_external_sync */ + #ifdef __cplusplus } #endif
diff --git a/third_party/khronos/README.chromium b/third_party/khronos/README.chromium index 052e9d9..2ee108e 100644 --- a/third_party/khronos/README.chromium +++ b/third_party/khronos/README.chromium
@@ -33,6 +33,8 @@ EGL/eglplatform.h - Added EGLNative*Type for Mac. - Added EGLNative*Type for native linux framebuffers. +EGL/eglext.h + - Added EGL_ARM_implicit_external_sync extension tokens KHR/khrplatform.h - Modified KHRONOS_APICALL and KHRONOS_APIENTRY DEPS
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 1a150d1..84ae4ac 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc
@@ -898,6 +898,22 @@ } } +Status ChromiumEnv::NewAppendableFile(const std::string& fname, + leveldb::WritableFile** result) { + *result = NULL; + FilePath path = FilePath::FromUTF8Unsafe(fname); + scoped_ptr<base::File> f(new base::File( + path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND)); + if (!f->IsValid()) { + RecordErrorAt(kNewAppendableFile); + return MakeIOError(fname, "Unable to create appendable file", + kNewAppendableFile, f->error_details()); + } + *result = + new ChromiumWritableFile(fname, f.release(), this, this, make_backup_); + return Status::OK(); +} + uint64_t ChromiumEnv::NowMicros() { return base::TimeTicks::Now().ToInternalValue(); }
diff --git a/third_party/leveldatabase/env_chromium.h b/third_party/leveldatabase/env_chromium.h index 0e04f586..447e1df9 100644 --- a/third_party/leveldatabase/env_chromium.h +++ b/third_party/leveldatabase/env_chromium.h
@@ -131,6 +131,8 @@ leveldb::RandomAccessFile** result); virtual leveldb::Status NewWritableFile(const std::string& fname, leveldb::WritableFile** result); + virtual leveldb::Status NewAppendableFile(const std::string& fname, + leveldb::WritableFile** result); virtual leveldb::Status NewLogger(const std::string& fname, leveldb::Logger** result);
diff --git a/third_party/libevent/README.chromium b/third_party/libevent/README.chromium index be4fee3b..a3e5c6e 100644 --- a/third_party/libevent/README.chromium +++ b/third_party/libevent/README.chromium
@@ -23,3 +23,4 @@ nacl_nonsfi/event-config.h are derived from linux/ counterparts. nacl_nonsfi/random.c is also added to provide the random() function, which is missing in the newlib-based PNaCl toolchain. +8) Apply https://github.com/libevent/libevent/commit/ea6b1df
diff --git a/third_party/libevent/evdns.c b/third_party/libevent/evdns.c index da6ea19..6fa971c8 100644 --- a/third_party/libevent/evdns.c +++ b/third_party/libevent/evdns.c
@@ -55,7 +55,9 @@ #endif /* #define _POSIX_C_SOURCE 200507 */ +#if !defined(_GNU_SOURCE) #define _GNU_SOURCE +#endif #ifdef DNS_USE_CPU_CLOCK_FOR_ID #ifdef DNS_USE_OPENSSL_FOR_ID
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index d602e1e..459303a 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://code.google.com/p/webrtc/ Version: unknown -Revision: 8221 +Revision: 8277 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/third_party/libxml/libxml.gyp b/third_party/libxml/libxml.gyp index dcc75b9..1decbe9 100644 --- a/third_party/libxml/libxml.gyp +++ b/third_party/libxml/libxml.gyp
@@ -237,6 +237,7 @@ 'libraries': [ # We need dl for dlopen() and friends. '-ldl', + '-lm', ], }, }],
diff --git a/third_party/mojo/src/mojo/edk/DEPS b/third_party/mojo/src/mojo/edk/DEPS deleted file mode 100644 index 9a51b60f..0000000 --- a/third_party/mojo/src/mojo/edk/DEPS +++ /dev/null
@@ -1,7 +0,0 @@ -include_rules = [ - "-mojo", - "+mojo/edk", - "+mojo/public", - - "+third_party/ashmem", -]
diff --git a/third_party/mojo/src/mojo/edk/embedder/DEPS b/third_party/mojo/src/mojo/edk/embedder/DEPS deleted file mode 100644 index c3a0d225..0000000 --- a/third_party/mojo/src/mojo/edk/embedder/DEPS +++ /dev/null
@@ -1,11 +0,0 @@ -include_rules = [ - "+mojo/edk/system/system_impl_export.h", -] - -specific_include_rules = { - # Implementation files may freely access mojo/edk/system, but we don't want to - # leak implementation details through the headers. - ".*\.cc": [ - "+mojo/edk/system", - ] -}
diff --git a/third_party/mojo/src/mojo/edk/embedder/channel_init.cc b/third_party/mojo/src/mojo/edk/embedder/channel_init.cc index 9a0bfce..0b6d76c 100644 --- a/third_party/mojo/src/mojo/edk/embedder/channel_init.cc +++ b/third_party/mojo/src/mojo/edk/embedder/channel_init.cc
@@ -15,6 +15,9 @@ } ChannelInit::~ChannelInit() { + // TODO(vtl): This is likely leaky in common scenarios (we're on the main + // thread, which outlives the I/O thread, and we're destroyed after the I/O + // thread is destroyed. if (channel_info_) DestroyChannel(channel_info_); } @@ -22,14 +25,12 @@ ScopedMessagePipeHandle ChannelInit::Init( base::PlatformFile file, scoped_refptr<base::TaskRunner> io_thread_task_runner) { - DCHECK(!io_thread_task_runner_); // Should only init once. - io_thread_task_runner_ = io_thread_task_runner; ScopedMessagePipeHandle message_pipe = - CreateChannel( - ScopedPlatformHandle(PlatformHandle(file)), io_thread_task_runner, - base::Bind(&ChannelInit::OnCreatedChannel, weak_factory_.GetWeakPtr(), - io_thread_task_runner), - base::MessageLoop::current()->message_loop_proxy()).Pass(); + CreateChannel(ScopedPlatformHandle(PlatformHandle(file)), + io_thread_task_runner, + base::Bind(&ChannelInit::OnCreatedChannel, + weak_factory_.GetWeakPtr()), + base::MessageLoop::current()->task_runner()).Pass(); return message_pipe.Pass(); } @@ -40,7 +41,6 @@ // static void ChannelInit::OnCreatedChannel(base::WeakPtr<ChannelInit> self, - scoped_refptr<base::TaskRunner> io_thread, ChannelInfo* channel) { // If |self| was already destroyed, shut the channel down. if (!self) { @@ -48,6 +48,7 @@ return; } + DCHECK(!self->channel_info_); self->channel_info_ = channel; }
diff --git a/third_party/mojo/src/mojo/edk/embedder/channel_init.h b/third_party/mojo/src/mojo/edk/embedder/channel_init.h index 59b6694..478da41b 100644 --- a/third_party/mojo/src/mojo/edk/embedder/channel_init.h +++ b/third_party/mojo/src/mojo/edk/embedder/channel_init.h
@@ -28,7 +28,7 @@ ~ChannelInit(); // Initializes the channel. This takes ownership of |file|. Returns the - // primordial MessagePipe for the channel. + // primordial |MessagePipe| for the channel. mojo::ScopedMessagePipeHandle Init( base::PlatformFile file, scoped_refptr<base::TaskRunner> io_thread_task_runner); @@ -41,11 +41,8 @@ // established. (This is a static method that takes a weak pointer to self, // since we want to destroy the channel even if we're destroyed.) static void OnCreatedChannel(base::WeakPtr<ChannelInit> self, - scoped_refptr<base::TaskRunner> io_thread, ChannelInfo* channel); - scoped_refptr<base::TaskRunner> io_thread_task_runner_; - // If non-null the channel has been established. ChannelInfo* channel_info_;
diff --git a/third_party/mojo/src/mojo/edk/embedder/embedder.cc b/third_party/mojo/src/mojo/edk/embedder/embedder.cc index 1d12c1e..0150dcb8 100644 --- a/third_party/mojo/src/mojo/edk/embedder/embedder.cc +++ b/third_party/mojo/src/mojo/edk/embedder/embedder.cc
@@ -4,6 +4,7 @@ #include "mojo/edk/embedder/embedder.h" +#include "base/atomicops.h" #include "base/bind.h" #include "base/location.h" #include "base/logging.h" @@ -25,42 +26,25 @@ namespace { -// Helper for |CreateChannel...()|. Returns 0 on failure. Called on the channel -// creation thread. -system::ChannelId MakeChannel( - ScopedPlatformHandle platform_handle, - scoped_refptr<system::ChannelEndpoint> channel_endpoint) { - DCHECK(platform_handle.is_valid()); +// TODO(vtl): For now, we need this to be thread-safe (since theoretically we +// currently support multiple channel creation threads -- possibly one per +// channel). Eventually, we won't need it to be thread-safe (we'll require a +// single I/O thread), and eventually we won't need it at all. Remember to +// remove the base/atomicops.h include. +system::ChannelId MakeChannelId() { + // Note that |AtomicWord| is signed. + static base::subtle::AtomicWord counter = 0; - // Create and initialize a |system::Channel|. - DCHECK(internal::g_core); - scoped_refptr<system::Channel> channel = - new system::Channel(internal::g_core->platform_support()); - channel->Init(system::RawChannel::Create(platform_handle.Pass())); - channel->SetBootstrapEndpoint(channel_endpoint); - - DCHECK(internal::g_channel_manager); - return internal::g_channel_manager->AddChannel( - channel, base::MessageLoopProxy::current()); -} - -// Helper for |CreateChannel()|. Called on the channel creation thread. -void CreateChannelHelper( - ScopedPlatformHandle platform_handle, - scoped_ptr<ChannelInfo> channel_info, - scoped_refptr<system::ChannelEndpoint> channel_endpoint, - DidCreateChannelCallback callback, - scoped_refptr<base::TaskRunner> callback_thread_task_runner) { - channel_info->channel_id = - MakeChannel(platform_handle.Pass(), channel_endpoint); - - // Hand the channel back to the embedder. - if (callback_thread_task_runner) { - callback_thread_task_runner->PostTask( - FROM_HERE, base::Bind(callback, channel_info.release())); - } else { - callback.Run(channel_info.release()); - } + base::subtle::AtomicWord new_counter_value = + base::subtle::NoBarrier_AtomicIncrement(&counter, 1); + // Don't allow the counter to wrap. Note that any (strictly) positive value is + // a valid |ChannelId| (and |NoBarrier_AtomicIncrement()| returns the value + // post-increment). + CHECK_GT(new_counter_value, 0); + // Use "negative" values for these IDs, so that we'll also be able to use + // "positive" "process identifiers" (see connection_manager.h) as IDs (and + // they won't conflict). + return static_cast<system::ChannelId>(-new_counter_value); } } // namespace @@ -68,16 +52,24 @@ namespace internal { // Declared in embedder_internal.h. +PlatformSupport* g_platform_support = nullptr; system::Core* g_core = nullptr; system::ChannelManager* g_channel_manager = nullptr; } // namespace internal void Init(scoped_ptr<PlatformSupport> platform_support) { + DCHECK(platform_support); + + DCHECK(!internal::g_platform_support); + internal::g_platform_support = platform_support.release(); + DCHECK(!internal::g_core); - internal::g_core = new system::Core(platform_support.Pass()); + internal::g_core = new system::Core(internal::g_platform_support); + DCHECK(!internal::g_channel_manager); - internal::g_channel_manager = new system::ChannelManager(); + internal::g_channel_manager = + new system::ChannelManager(internal::g_platform_support); } Configuration* GetConfiguration() { @@ -99,8 +91,9 @@ ScopedMessagePipeHandle rv( MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); - *channel_info = - new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint)); + *channel_info = new ChannelInfo(MakeChannelId()); + internal::g_channel_manager->CreateChannelOnIOThread( + (*channel_info)->channel_id, platform_handle.Pass(), channel_endpoint); return rv.Pass(); } @@ -126,14 +119,16 @@ scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); if (rv.is_valid()) { - io_thread_task_runner->PostTask( - FROM_HERE, - base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), - base::Passed(&channel_info), channel_endpoint, callback, - callback_thread_task_runner)); + system::ChannelId channel_id = MakeChannelId(); + channel_info->channel_id = channel_id; + internal::g_channel_manager->CreateChannel( + channel_id, platform_handle.Pass(), channel_endpoint, + io_thread_task_runner, + base::Bind(callback, base::Unretained(channel_info.release())), + callback_thread_task_runner); } else { - (callback_thread_task_runner.get() ? callback_thread_task_runner - : io_thread_task_runner) + (callback_thread_task_runner ? callback_thread_task_runner + : io_thread_task_runner) ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); }
diff --git a/third_party/mojo/src/mojo/edk/embedder/embedder.h b/third_party/mojo/src/mojo/edk/embedder/embedder.h index 987c6879..cc0ad26 100644 --- a/third_party/mojo/src/mojo/edk/embedder/embedder.h +++ b/third_party/mojo/src/mojo/edk/embedder/embedder.h
@@ -20,13 +20,12 @@ struct Configuration; class PlatformSupport; -// Must be called first, or just after setting configuration parameters, -// to initialize the (global, singleton) system. +// Must be called first, or just after setting configuration parameters, to +// initialize the (global, singleton) system. MOJO_SYSTEM_IMPL_EXPORT void Init(scoped_ptr<PlatformSupport> platform_support); -// Returns the global configuration. In general there should be no need to -// change the configuration, but if you do so this must be done before calling -// |Init()|. +// Returns the global configuration. In general, you should not need to change +// the configuration, but if you do you must do it before calling |Init()|. MOJO_SYSTEM_IMPL_EXPORT Configuration* GetConfiguration(); // A "channel" is a connection on top of an OS "pipe", on top of which Mojo @@ -64,8 +63,6 @@ // // The destruction functions are similarly synchronous and asynchronous, // respectively, and take the |ChannelInfo*| produced by the creation functions. -// -// TODO(vtl): Figure out channel teardown. // Creates a channel; must only be called from the I/O thread. |platform_handle| // should be a handle to a connected OS "pipe". Eventually (even on failure), @@ -95,6 +92,9 @@ // should be the value provided to the callback to |CreateChannel()| (or // returned by |CreateChannelOnIOThread()|). If called from the I/O thread, this // will complete synchronously (in particular, it will post no tasks). +// TODO(vtl): If called from some other thread, it'll post tasks to the I/O +// thread. This is obviously potentially problematic if you want to shut the I/O +// thread down. MOJO_SYSTEM_IMPL_EXPORT void DestroyChannel(ChannelInfo* channel_info); // Inform the channel that it will soon be destroyed (doing so is optional).
diff --git a/third_party/mojo/src/mojo/edk/embedder/embedder_internal.h b/third_party/mojo/src/mojo/edk/embedder/embedder_internal.h index ab8388ae..536e0db 100644 --- a/third_party/mojo/src/mojo/edk/embedder/embedder_internal.h +++ b/third_party/mojo/src/mojo/edk/embedder/embedder_internal.h
@@ -19,12 +19,14 @@ class Core; // Repeat a typedef in mojo/edk/system/channel_manager.h, to avoid including it. -typedef uintptr_t ChannelId; +typedef uint64_t ChannelId; } // namespace system namespace embedder { +class PlatformSupport; + // This is a type that's opaque to users of the embedder API (which only // gives/takes |ChannelInfo*|s). We make it a struct to make it // template-friendly. @@ -37,6 +39,9 @@ namespace internal { +// Instance of |PlatformSupport| to use. +extern PlatformSupport* g_platform_support; + // Instance of |Core| used by the system functions (|Mojo...()|). extern system::Core* g_core;
diff --git a/third_party/mojo/src/mojo/edk/embedder/embedder_unittest.cc b/third_party/mojo/src/mojo/edk/embedder/embedder_unittest.cc index ed4ea2e..fd1c04cd 100644 --- a/third_party/mojo/src/mojo/edk/embedder/embedder_unittest.cc +++ b/third_party/mojo/src/mojo/edk/embedder/embedder_unittest.cc
@@ -44,7 +44,7 @@ ScopedPlatformHandle platform_handle) : io_thread_task_runner_(io_thread_task_runner), bootstrap_message_pipe_(MOJO_HANDLE_INVALID), - did_create_channel_event_(true, false), + did_create_channel_event_(true, false), // Manual reset. channel_info_(nullptr) { bootstrap_message_pipe_ = CreateChannel(platform_handle.Pass(), io_thread_task_runner_, @@ -58,7 +58,11 @@ // Destructor: Shuts down the channel. (As noted above, for this to happen, // the I/O thread must be alive and pumping messages.) - ~ScopedTestChannel() { DestroyChannel(channel_info_); } + ~ScopedTestChannel() { + // |WaitForChannelCreationCompletion()| must be called before destruction. + CHECK(did_create_channel_event_.IsSignaled()); + DestroyChannel(channel_info_); + } // Waits for channel creation to be completed. void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
diff --git a/third_party/mojo/src/mojo/edk/embedder/test_embedder.cc b/third_party/mojo/src/mojo/edk/embedder/test_embedder.cc index defab41..3412626 100644 --- a/third_party/mojo/src/mojo/edk/embedder/test_embedder.cc +++ b/third_party/mojo/src/mojo/edk/embedder/test_embedder.cc
@@ -54,6 +54,11 @@ bool rv = system::internal::ShutdownCheckNoLeaks(internal::g_core); delete internal::g_core; internal::g_core = nullptr; + + CHECK(internal::g_platform_support); + delete internal::g_platform_support; + internal::g_platform_support = nullptr; + return rv; }
diff --git a/third_party/mojo/src/mojo/edk/js/DEPS b/third_party/mojo/src/mojo/edk/js/DEPS deleted file mode 100644 index c350edf8..0000000 --- a/third_party/mojo/src/mojo/edk/js/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+base", - "+gin", - "+v8", -]
diff --git a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp.mojom b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp.mojom index 69f67b6..688b22b3 100644 --- a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp.mojom +++ b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp.mojom
@@ -44,8 +44,9 @@ BackPointerResponse(EchoArgsList arg); }; -[Client=CppSide] interface JsSide { + SetCppSide(CppSide cpp); + Ping(); Echo(int32 numIterations, EchoArgs arg); BitFlip(EchoArgs arg);
diff --git a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.cc b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.cc index 1da70c2..3675f97 100644 --- a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.cc +++ b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.cc
@@ -193,11 +193,11 @@ // run_loop(). class CppSideConnection : public js_to_cpp::CppSide { public: - CppSideConnection() : - run_loop_(NULL), - js_side_(NULL), - mishandled_messages_(0) { - } + CppSideConnection() + : run_loop_(nullptr), + js_side_(nullptr), + mishandled_messages_(0), + binding_(this) {} ~CppSideConnection() override {} void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; } @@ -206,6 +206,12 @@ void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; } js_to_cpp::JsSide* js_side() { return js_side_; } + void Bind(InterfaceRequest<js_to_cpp::CppSide> request) { + binding_.Bind(request.Pass()); + // Keep the pipe open even after validation errors. + binding_.internal_router()->EnableTestingMode(); + } + // js_to_cpp::CppSide: void StartTest() override { NOTREACHED(); } @@ -229,6 +235,7 @@ base::RunLoop* run_loop_; js_to_cpp::JsSide* js_side_; int mishandled_messages_; + mojo::Binding<js_to_cpp::CppSide> binding_; private: DISALLOW_COPY_AND_ASSIGN(CppSideConnection); @@ -363,21 +370,22 @@ void RunTest(const std::string& test, CppSideConnection* cpp_side) { cpp_side->set_run_loop(&run_loop_); - MessagePipe pipe; - js_to_cpp::JsSidePtr js_side = - MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass()); - js_side.set_client(cpp_side); - - js_side.internal_state()->router_for_testing()->EnableTestingMode(); + js_to_cpp::JsSidePtr js_side; + auto js_side_proxy = GetProxy(&js_side); cpp_side->set_js_side(js_side.get()); + js_to_cpp::CppSidePtr cpp_side_ptr; + cpp_side->Bind(GetProxy(&cpp_side_ptr)); + + js_side->SetCppSide(cpp_side_ptr.Pass()); gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode, gin::ArrayBufferAllocator::SharedInstance()); gin::IsolateHolder instance; MojoRunnerDelegate delegate; gin::ShellRunner runner(&delegate, instance.isolate()); - delegate.Start(&runner, pipe.handle1.release().value(), test); + delegate.Start(&runner, js_side_proxy.PassMessagePipe().release().value(), + test); run_loop_.Run(); }
diff --git a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.js b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.js index 140ad4c0..ddecc4b 100644 --- a/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.js +++ b/third_party/mojo/src/mojo/edk/js/tests/js_to_cpp_tests.js
@@ -5,11 +5,13 @@ define('mojo/edk/js/tests/js_to_cpp_tests', [ 'console', 'mojo/edk/js/tests/js_to_cpp.mojom', + 'mojo/public/js/bindings', 'mojo/public/js/connection', 'mojo/public/js/connector', 'mojo/public/js/core', -], function (console, jsToCpp, connection, connector, core) { - var retainedConnection; +], function (console, jsToCpp, bindings, connection, connector, core) { + var retainedJsSide; + var retainedJsSideStub; var sampleData; var sampleMessage; var BAD_VALUE = 13; @@ -25,6 +27,11 @@ JsSideConnection.prototype = Object.create(jsToCpp.JsSide.stubClass.prototype); + JsSideConnection.prototype.setCppSide = function(cppSide) { + this.cppSide_ = cppSide; + this.cppSide_.startTest(); + }; + JsSideConnection.prototype.ping = function (arg) { this.cppSide_.pingResponse(); }; @@ -203,13 +210,7 @@ }, null); } - function createCppSideConnection(handle, stubClass, proxyClass) { - var c = new connection.Connection(handle, stubClass, proxyClass); - c.local.cppSide_ = c.remote; - return c; - } - - return function(handle) { + return function(jsSideRequestHandle) { var i; sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); for (i = 0; i < sampleData.length; ++i) { @@ -219,8 +220,9 @@ for (i = 0; i < sampleMessage.length; ++i) { sampleMessage[i] = 255 - i; } - retainedConnection = createCppSideConnection( - handle, JsSideConnection,jsToCpp.CppSide.proxyClass); - retainedConnection.remote.startTest(); + retainedJsSideStub = + connection.bindHandleToStub(jsSideRequestHandle, jsToCpp.JsSide); + retainedJsSide = new JsSideConnection; + bindings.StubBindings(retainedJsSideStub).delegate = retainedJsSide; }; });
diff --git a/third_party/mojo/src/mojo/edk/system/BUILD.gn b/third_party/mojo/src/mojo/edk/system/BUILD.gn index 12fa225..d9dc9302 100644 --- a/third_party/mojo/src/mojo/edk/system/BUILD.gn +++ b/third_party/mojo/src/mojo/edk/system/BUILD.gn
@@ -123,6 +123,14 @@ allow_circular_includes_from = [ "../embedder" ] } +group("tests") { + testonly = true + deps = [ + ":mojo_system_unittests", + ":mojo_message_pipe_perftests", + ] +} + mojo_edk_source_set("test_utils") { testonly = true @@ -137,7 +145,6 @@ ] } -# GYP version: mojo/edk/mojo_edk.gyp:mojo_system_unittests test("mojo_system_unittests") { sources = [ "../test/multiprocess_test_helper_unittest.cc", @@ -184,7 +191,6 @@ allow_circular_includes_from = [ "../embedder:embedder_unittests" ] } -# GYP version: mojo/edk/mojo_edk.gyp:mojo_message_pipe_perftests test("mojo_message_pipe_perftests") { sources = [ "message_pipe_perftest.cc",
diff --git a/third_party/mojo/src/mojo/edk/system/DEPS b/third_party/mojo/src/mojo/edk/system/DEPS deleted file mode 100644 index 4ef4138e4..0000000 --- a/third_party/mojo/src/mojo/edk/system/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+crypto", -]
diff --git a/third_party/mojo/src/mojo/edk/system/channel.h b/third_party/mojo/src/mojo/edk/system/channel.h index 39618590..93ba87a 100644 --- a/third_party/mojo/src/mojo/edk/system/channel.h +++ b/third_party/mojo/src/mojo/edk/system/channel.h
@@ -54,8 +54,7 @@ : public base::RefCountedThreadSafe<Channel>, public RawChannel::Delegate { public: - // |platform_support| (typically owned by |Core|) must remain alive until - // after |Shutdown()| is called. + // |platform_support| must remain alive until after |Shutdown()| is called. explicit Channel(embedder::PlatformSupport* platform_support); // This must be called on the creation thread before any other methods are @@ -65,7 +64,9 @@ // Sets the channel manager associated with this channel. This should be set // at most once and only called before |WillShutdownSoon()| (and - // |Shutdown()|). + // |Shutdown()|). (This is called by the channel manager when adding a + // channel; this should not be called before the channel is managed by the + // channel manager.) void SetChannelManager(ChannelManager* channel_manager); // This must be called on the creation thread before destruction (which can
diff --git a/third_party/mojo/src/mojo/edk/system/channel_manager.cc b/third_party/mojo/src/mojo/edk/system/channel_manager.cc index 4e58f89..c2fe8a5 100644 --- a/third_party/mojo/src/mojo/edk/system/channel_manager.cc +++ b/third_party/mojo/src/mojo/edk/system/channel_manager.cc
@@ -5,8 +5,10 @@ #include "mojo/edk/system/channel_manager.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/location.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/task_runner.h" namespace mojo { namespace system { @@ -26,7 +28,8 @@ } // namespace -ChannelManager::ChannelManager() { +ChannelManager::ChannelManager(embedder::PlatformSupport* platform_support) + : platform_support_(platform_support) { } ChannelManager::~ChannelManager() { @@ -35,24 +38,57 @@ ShutdownChannelHelper(map_elem.second); } -ChannelId ChannelManager::AddChannel( - scoped_refptr<Channel> channel, - scoped_refptr<base::TaskRunner> channel_thread_task_runner) { - ChannelId channel_id = GetChannelId(channel.get()); +void ChannelManager::CreateChannelOnIOThread( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint) { + DCHECK_NE(channel_id, kInvalidChannelId); + DCHECK(platform_handle.is_valid()); + DCHECK(bootstrap_channel_endpoint); + + // Create and initialize a |system::Channel|. + scoped_refptr<system::Channel> channel = + new system::Channel(platform_support_); + channel->Init(system::RawChannel::Create(platform_handle.Pass())); + channel->SetBootstrapEndpoint(bootstrap_channel_endpoint); { base::AutoLock locker(lock_); - DCHECK(channel_infos_.find(channel_id) == channel_infos_.end()); + CHECK(channel_infos_.find(channel_id) == channel_infos_.end()); channel_infos_[channel_id] = - ChannelInfo(channel, channel_thread_task_runner); + ChannelInfo(channel, base::MessageLoopProxy::current()); } channel->SetChannelManager(this); +} - return channel_id; +void ChannelManager::CreateChannel( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint, + scoped_refptr<base::TaskRunner> io_thread_task_runner, + base::Closure callback, + scoped_refptr<base::TaskRunner> callback_thread_task_runner) { + DCHECK(io_thread_task_runner); + DCHECK(!callback.is_null()); + // (|callback_thread_task_runner| may be null.) + + io_thread_task_runner->PostTask( + FROM_HERE, + base::Bind(&ChannelManager::CreateChannelHelper, base::Unretained(this), + channel_id, base::Passed(&platform_handle), + bootstrap_channel_endpoint, callback, + callback_thread_task_runner)); +} + +scoped_refptr<Channel> ChannelManager::GetChannel(ChannelId channel_id) const { + base::AutoLock locker(lock_); + auto it = channel_infos_.find(channel_id); + DCHECK(it != channel_infos_.end()); + return it->second.channel; } void ChannelManager::WillShutdownChannel(ChannelId channel_id) { - GetChannelInfo(channel_id).channel->WillShutdownSoon(); + GetChannel(channel_id)->WillShutdownSoon(); } void ChannelManager::ShutdownChannel(ChannelId channel_id) { @@ -67,11 +103,18 @@ ShutdownChannelHelper(channel_info); } -ChannelInfo ChannelManager::GetChannelInfo(ChannelId channel_id) { - base::AutoLock locker(lock_); - auto it = channel_infos_.find(channel_id); - DCHECK(it != channel_infos_.end()); - return it->second; +void ChannelManager::CreateChannelHelper( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint, + base::Closure callback, + scoped_refptr<base::TaskRunner> callback_thread_task_runner) { + CreateChannelOnIOThread(channel_id, platform_handle.Pass(), + bootstrap_channel_endpoint); + if (callback_thread_task_runner) + callback_thread_task_runner->PostTask(FROM_HERE, callback); + else + callback.Run(); } } // namespace system
diff --git a/third_party/mojo/src/mojo/edk/system/channel_manager.h b/third_party/mojo/src/mojo/edk/system/channel_manager.h index bb6371b..35a4f27 100644 --- a/third_party/mojo/src/mojo/edk/system/channel_manager.h +++ b/third_party/mojo/src/mojo/edk/system/channel_manager.h
@@ -11,35 +11,71 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "base/task_runner.h" +#include "mojo/edk/embedder/scoped_platform_handle.h" #include "mojo/edk/system/channel.h" #include "mojo/edk/system/channel_info.h" +namespace base { +class TaskRunner; +} + namespace mojo { + +namespace embedder { +class PlatformSupport; +} + namespace system { // IDs for |Channel|s managed by a |ChannelManager|. (IDs should be thought of // as specific to a given |ChannelManager|.) 0 is never a valid ID. -// -// Note: We currently just use the pointer of the |Channel| casted to a -// |uintptr_t|, but we reserve the right to change this. -typedef uintptr_t ChannelId; +typedef uint64_t ChannelId; + +const ChannelId kInvalidChannelId = 0; // This class manages and "owns" |Channel|s (which typically connect to other -// processes) for a given process. This class is thread-safe. +// processes) for a given process. This class is thread-safe, except as +// specifically noted. class MOJO_SYSTEM_IMPL_EXPORT ChannelManager { public: - ChannelManager(); + // |*platform_support| must remain alive longer than this object. + explicit ChannelManager(embedder::PlatformSupport* platform_support); ~ChannelManager(); - // Adds |channel| to the set of |Channel|s managed by this |ChannelManager|; - // |channel_thread_task_runner| should be the task runner for |channel|'s - // creation (a.k.a. I/O) thread. |channel| should either already be - // initialized. It should not be managed by any |ChannelManager| yet. Returns - // the ID for the added channel. - ChannelId AddChannel( - scoped_refptr<Channel> channel, - scoped_refptr<base::TaskRunner> channel_thread_task_runner); + // Creates a |Channel| and adds it to the set of channels managed by this + // |ChannelManager|. |channel_id| should be a valid |ChannelId| (i.e., + // nonzero) not "assigned" to any other |Channel| being managed by this + // |ChannelManager|. + // TODO(vtl): Currently, this should be called on any I/O thread (which will + // become the new channel's "channel thread"). Eventually, the channel manager + // will have an assigned I/O thread, on which this must be called. + // TODO(vtl): Probably this should return a message pipe dispatcher (for the + // bootstrap message pipe) instead. + void CreateChannelOnIOThread( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint); + + // Like |CreateChannelOnIOThread()|, but may be called from any thread. On + // completion, will call |callback| ("on" |io_thread_task_runner| if + // |callback_thread_task_runner| is null else by posting to using + // |callback_thread_task_runner|). Note: This will always post a task to the + // I/O thread, even if |io_thread_task_runner| is the task runner for the + // current thread. + // TODO(vtl): The |io_thread_task_runner| argument is temporary (we should use + // the channel manager's I/O thread). + // TODO(vtl): Probably this should return a message pipe dispatcher (for the + // bootstrap message pipe) instead. + void CreateChannel( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint, + scoped_refptr<base::TaskRunner> io_thread_task_runner, + base::Closure callback, + scoped_refptr<base::TaskRunner> callback_thread_task_runner); + + // Gets the |Channel| with the given ID (which must exist). + scoped_refptr<Channel> GetChannel(ChannelId channel_id) const; // Informs the channel manager (and thus channel) that it will be shutdown // soon (by calling |ShutdownChannel()|). Calling this is optional (and may in @@ -50,28 +86,26 @@ // Shuts down the channel specified by the given ID. It is up to the caller to // guarantee that this is only called once per channel (that was added using - // |AddChannel()|). If called from the chanel's creation thread (i.e., - // |base::MessageLoopProxy::current()| is the channel thread's |TaskRunner|), - // this will complete synchronously. + // |CreateChannelOnIOThread()|). If called from the channel's creation thread + // (i.e., |base::MessageLoopProxy::current()| is the channel thread's + // |TaskRunner|), this will complete synchronously. void ShutdownChannel(ChannelId channel_id); private: - // Gets the ID for a given channel. - // - // Note: This is currently a static method and thus may be called under - // |lock_|. If this is ever made non-static (i.e., made specific to a given - // |ChannelManager|), those call sites may have to changed. - static ChannelId GetChannelId(const Channel* channel) { - return reinterpret_cast<ChannelId>(channel); - } + void CreateChannelHelper( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle, + scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint, + base::Closure callback, + scoped_refptr<base::TaskRunner> callback_thread_task_runner); - // Gets the |ChannelInfo| for the channel specified by the given ID. (This - // should *not* be called under lock.) - ChannelInfo GetChannelInfo(ChannelId channel_id); + embedder::PlatformSupport* const platform_support_; // Note: |Channel| methods should not be called under |lock_|. - base::Lock lock_; // Protects the members below. + mutable base::Lock lock_; // Protects the members below. + // TODO(vtl): Once we give the |ChannelManager| one single I/O thread, we can + // get rid of |ChannelInfo| (and just have ref pointers to |Channel|s). base::hash_map<ChannelId, ChannelInfo> channel_infos_; DISALLOW_COPY_AND_ASSIGN(ChannelManager);
diff --git a/third_party/mojo/src/mojo/edk/system/channel_manager_unittest.cc b/third_party/mojo/src/mojo/edk/system/channel_manager_unittest.cc index 52f3f0e..c5aa503 100644 --- a/third_party/mojo/src/mojo/edk/system/channel_manager_unittest.cc +++ b/third_party/mojo/src/mojo/edk/system/channel_manager_unittest.cc
@@ -17,6 +17,8 @@ #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/edk/embedder/simple_platform_support.h" #include "mojo/edk/system/channel.h" +#include "mojo/edk/system/channel_endpoint.h" +#include "mojo/edk/system/message_pipe_dispatcher.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { @@ -42,19 +44,20 @@ }; TEST_F(ChannelManagerTest, Basic) { - ChannelManager cm; - - // Hang on to a ref to the |Channel|, so that we can check that the - // |ChannelManager| takes/releases refs to it. - scoped_refptr<Channel> ch(new Channel(platform_support())); - ASSERT_TRUE(ch->HasOneRef()); + ChannelManager cm(platform_support()); embedder::PlatformChannelPair channel_pair; - ch->Init(RawChannel::Create(channel_pair.PassServerHandle())); - ChannelId id = cm.AddChannel(ch, base::MessageLoopProxy::current()); - EXPECT_NE(id, 0u); - // |ChannelManager| should take a ref. + scoped_refptr<ChannelEndpoint> cep; + scoped_refptr<MessagePipeDispatcher> d = + MessagePipeDispatcher::CreateRemoteMessagePipe(&cep); + const ChannelId id = 1; + cm.CreateChannelOnIOThread(id, channel_pair.PassServerHandle(), cep); + cep = nullptr; + + scoped_refptr<Channel> ch = cm.GetChannel(id); + EXPECT_TRUE(ch); + // |ChannelManager| should have a ref. EXPECT_FALSE(ch->HasOneRef()); cm.WillShutdownChannel(id); @@ -65,30 +68,34 @@ // On the "I/O" thread, so shutdown should happen synchronously. // |ChannelManager| should have given up its ref. EXPECT_TRUE(ch->HasOneRef()); + + EXPECT_EQ(MOJO_RESULT_OK, d->Close()); } TEST_F(ChannelManagerTest, TwoChannels) { - ChannelManager cm; - - // Hang on to a ref to each |Channel|, so that we can check that the - // |ChannelManager| takes/releases refs to them. - scoped_refptr<Channel> ch1(new Channel(platform_support())); - ASSERT_TRUE(ch1->HasOneRef()); - scoped_refptr<Channel> ch2(new Channel(platform_support())); - ASSERT_TRUE(ch2->HasOneRef()); + ChannelManager cm(platform_support()); embedder::PlatformChannelPair channel_pair; - ch1->Init(RawChannel::Create(channel_pair.PassServerHandle())); - ch2->Init(RawChannel::Create(channel_pair.PassClientHandle())); - ChannelId id1 = cm.AddChannel(ch1, base::MessageLoopProxy::current()); - EXPECT_NE(id1, 0u); - EXPECT_FALSE(ch1->HasOneRef()); + scoped_refptr<ChannelEndpoint> cep1; + scoped_refptr<MessagePipeDispatcher> d1 = + MessagePipeDispatcher::CreateRemoteMessagePipe(&cep1); + const ChannelId id1 = 1; + cm.CreateChannelOnIOThread(id1, channel_pair.PassServerHandle(), cep1); + cep1 = nullptr; - ChannelId id2 = cm.AddChannel(ch2, base::MessageLoopProxy::current()); - EXPECT_NE(id2, 0u); - EXPECT_NE(id2, id1); - EXPECT_FALSE(ch2->HasOneRef()); + scoped_refptr<ChannelEndpoint> cep2; + scoped_refptr<MessagePipeDispatcher> d2 = + MessagePipeDispatcher::CreateRemoteMessagePipe(&cep2); + const ChannelId id2 = 2; + cm.CreateChannelOnIOThread(id2, channel_pair.PassClientHandle(), cep2); + cep2 = nullptr; + + scoped_refptr<Channel> ch1 = cm.GetChannel(id1); + EXPECT_TRUE(ch1); + + scoped_refptr<Channel> ch2 = cm.GetChannel(id2); + EXPECT_TRUE(ch2); // Calling |WillShutdownChannel()| multiple times (on |id1|) is okay. cm.WillShutdownChannel(id1); @@ -100,45 +107,47 @@ EXPECT_TRUE(ch1->HasOneRef()); cm.ShutdownChannel(id2); EXPECT_TRUE(ch2->HasOneRef()); + + EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); + EXPECT_EQ(MOJO_RESULT_OK, d2->Close()); } class OtherThread : public base::SimpleThread { public: - // Note: We rely on the main thread keeping *exactly one* reference to - // |channel|. + // Note: There should be no other refs to the channel identified by + // |channel_id| outside the channel manager. OtherThread(scoped_refptr<base::TaskRunner> task_runner, ChannelManager* channel_manager, - Channel* channel, + ChannelId channel_id, base::Closure quit_closure) : base::SimpleThread("other_thread"), task_runner_(task_runner), channel_manager_(channel_manager), - channel_(channel), + channel_id_(channel_id), quit_closure_(quit_closure) {} ~OtherThread() override {} private: void Run() override { - // See comment above constructor. - ASSERT_TRUE(channel_->HasOneRef()); + // TODO(vtl): Once we have a way of creating a channel from off the I/O + // thread, do that here instead. - ChannelId id = channel_manager_->AddChannel(make_scoped_refptr(channel_), - task_runner_); - EXPECT_NE(id, 0u); - // |ChannelManager| should take a ref. - EXPECT_FALSE(channel_->HasOneRef()); + // You can use any unique, nonzero value as the ID. + scoped_refptr<Channel> ch = channel_manager_->GetChannel(channel_id_); + // |ChannelManager| should have a ref. + EXPECT_FALSE(ch->HasOneRef()); - channel_manager_->WillShutdownChannel(id); + channel_manager_->WillShutdownChannel(channel_id_); // |ChannelManager| should still have a ref. - EXPECT_FALSE(channel_->HasOneRef()); + EXPECT_FALSE(ch->HasOneRef()); - channel_manager_->ShutdownChannel(id); + channel_manager_->ShutdownChannel(channel_id_); // This doesn't happen synchronously, so we "wait" until it does. - // TODO(vtl): Possibly |Channel| should provide some notification of being + // TODO(vtl): Probably |Channel| should provide some notification of being // shut down. base::TimeTicks start_time(base::TimeTicks::Now()); for (;;) { - if (channel_->HasOneRef()) + if (ch->HasOneRef()) break; // Check, instead of assert, since if things go wrong, dying is more @@ -153,29 +162,32 @@ scoped_refptr<base::TaskRunner> task_runner_; ChannelManager* channel_manager_; - Channel* channel_; + ChannelId channel_id_; base::Closure quit_closure_; DISALLOW_COPY_AND_ASSIGN(OtherThread); }; TEST_F(ChannelManagerTest, CallsFromOtherThread) { - ChannelManager cm; - - // Hang on to a ref to the |Channel|, so that we can check that the - // |ChannelManager| takes/releases refs to it. - scoped_refptr<Channel> ch(new Channel(platform_support())); - ASSERT_TRUE(ch->HasOneRef()); + ChannelManager cm(platform_support()); embedder::PlatformChannelPair channel_pair; - ch->Init(RawChannel::Create(channel_pair.PassServerHandle())); + + scoped_refptr<ChannelEndpoint> cep; + scoped_refptr<MessagePipeDispatcher> d = + MessagePipeDispatcher::CreateRemoteMessagePipe(&cep); + const ChannelId id = 1; + cm.CreateChannelOnIOThread(id, channel_pair.PassServerHandle(), cep); + cep = nullptr; base::RunLoop run_loop; - OtherThread thread(base::MessageLoopProxy::current(), &cm, ch.get(), + OtherThread thread(base::MessageLoopProxy::current(), &cm, id, run_loop.QuitClosure()); thread.Start(); run_loop.Run(); thread.Join(); + + EXPECT_EQ(MOJO_RESULT_OK, d->Close()); } } // namespace
diff --git a/third_party/mojo/src/mojo/edk/system/connection_manager_unittest.cc b/third_party/mojo/src/mojo/edk/system/connection_manager_unittest.cc index f46c386..2894c656 100644 --- a/third_party/mojo/src/mojo/edk/system/connection_manager_unittest.cc +++ b/third_party/mojo/src/mojo/edk/system/connection_manager_unittest.cc
@@ -58,6 +58,11 @@ return true; } +bool IsValidSlaveProcessIdentifier(ProcessIdentifier process_identifier) { + return process_identifier != kInvalidProcessIdentifier && + process_identifier != kMasterProcessIdentifier; +} + class TestSlaveInfo : public embedder::SlaveInfo { public: explicit TestSlaveInfo(const std::string& name) : name_(name) {} @@ -200,13 +205,15 @@ EXPECT_TRUE(slave1.AllowConnect(connection_id)); EXPECT_TRUE(slave2.AllowConnect(connection_id)); - ProcessIdentifier peer1; + ProcessIdentifier peer1 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h1; EXPECT_TRUE(slave1.Connect(connection_id, &peer1, &h1)); + EXPECT_TRUE(IsValidSlaveProcessIdentifier(peer1)); EXPECT_TRUE(h1.is_valid()); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_TRUE(slave2.Connect(connection_id, &peer2, &h2)); + EXPECT_TRUE(IsValidSlaveProcessIdentifier(peer2)); EXPECT_TRUE(h2.is_valid()); // TODO(vtl): If/when I add the ability to get one's own process identifier, @@ -285,9 +292,10 @@ EXPECT_TRUE(slave2.AllowConnect(connection_id)); EXPECT_TRUE(slave1.CancelConnect(connection_id)); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_FALSE(slave2.Connect(connection_id, &peer2, &h2)); + EXPECT_EQ(kInvalidProcessIdentifier, peer2); EXPECT_FALSE(h2.is_valid()); slave1.Shutdown(); @@ -320,9 +328,10 @@ master_process_delegate().RunUntilNotified(); EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls()); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_FALSE(slave2.Connect(connection_id, &peer2, &h2)); + EXPECT_EQ(kInvalidProcessIdentifier, peer2); EXPECT_FALSE(h2.is_valid()); slave2.Shutdown(); @@ -343,13 +352,15 @@ // Currently, the connect-to-self case is signalled by the master not sending // back a handle. - ProcessIdentifier peer1; + ProcessIdentifier peer1 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h1; EXPECT_TRUE(slave.Connect(connection_id, &peer1, &h1)); + EXPECT_TRUE(IsValidSlaveProcessIdentifier(peer1)); EXPECT_FALSE(h1.is_valid()); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_TRUE(slave.Connect(connection_id, &peer2, &h2)); + EXPECT_TRUE(IsValidSlaveProcessIdentifier(peer2)); EXPECT_FALSE(h2.is_valid()); EXPECT_EQ(peer1, peer2); @@ -374,10 +385,10 @@ EXPECT_TRUE(slave1.AllowConnect(connection_id)); EXPECT_TRUE(slave2.AllowConnect(connection_id)); - ProcessIdentifier peer1; + ProcessIdentifier peer1 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h1; EXPECT_TRUE(slave1.Connect(connection_id, &peer1, &h1)); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_TRUE(slave2.Connect(connection_id, &peer2, &h2)); @@ -395,9 +406,9 @@ h1.reset(); h2.reset(); - ProcessIdentifier second_peer2; + ProcessIdentifier second_peer2 = kInvalidProcessIdentifier; EXPECT_TRUE(slave2.Connect(connection_id, &second_peer2, &h2)); - ProcessIdentifier second_peer1; + ProcessIdentifier second_peer1 = kInvalidProcessIdentifier; EXPECT_TRUE(slave1.Connect(connection_id, &second_peer1, &h1)); EXPECT_EQ(peer1, second_peer1); @@ -421,13 +432,15 @@ EXPECT_TRUE(master.AllowConnect(connection_id)); EXPECT_TRUE(slave.AllowConnect(connection_id)); - ProcessIdentifier master_peer; + ProcessIdentifier master_peer = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle master_h; EXPECT_TRUE(master.Connect(connection_id, &master_peer, &master_h)); + EXPECT_TRUE(IsValidSlaveProcessIdentifier(master_peer)); EXPECT_TRUE(master_h.is_valid()); - ProcessIdentifier slave_peer; + ProcessIdentifier slave_peer = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle slave_h; EXPECT_TRUE(slave.Connect(connection_id, &slave_peer, &slave_h)); + EXPECT_EQ(kMasterProcessIdentifier, slave_peer); EXPECT_TRUE(slave_h.is_valid()); EXPECT_NE(master_peer, slave_peer); @@ -447,13 +460,15 @@ // Currently, the connect-to-self case is signalled by the master not sending // back a handle. - ProcessIdentifier peer1; + ProcessIdentifier peer1 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h1; EXPECT_TRUE(master.Connect(connection_id, &peer1, &h1)); + EXPECT_EQ(kMasterProcessIdentifier, peer1); EXPECT_FALSE(h1.is_valid()); - ProcessIdentifier peer2; + ProcessIdentifier peer2 = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h2; EXPECT_TRUE(master.Connect(connection_id, &peer2, &h2)); + EXPECT_EQ(kMasterProcessIdentifier, peer2); EXPECT_FALSE(h2.is_valid()); EXPECT_EQ(peer1, peer2); @@ -474,9 +489,10 @@ EXPECT_TRUE(slave.AllowConnect(connection_id)); EXPECT_TRUE(master.CancelConnect(connection_id)); - ProcessIdentifier peer; + ProcessIdentifier peer = kInvalidProcessIdentifier; embedder::ScopedPlatformHandle h; EXPECT_FALSE(slave.Connect(connection_id, &peer, &h)); + EXPECT_EQ(kInvalidProcessIdentifier, peer); EXPECT_FALSE(h.is_valid()); slave.Shutdown();
diff --git a/third_party/mojo/src/mojo/edk/system/core.cc b/third_party/mojo/src/mojo/edk/system/core.cc index 6189e50..4460088d 100644 --- a/third_party/mojo/src/mojo/edk/system/core.cc +++ b/third_party/mojo/src/mojo/edk/system/core.cc
@@ -78,8 +78,8 @@ // held. // TODO(vtl): This should take a |scoped_ptr<PlatformSupport>| as a parameter. -Core::Core(scoped_ptr<embedder::PlatformSupport> platform_support) - : platform_support_(platform_support.Pass()) { +Core::Core(embedder::PlatformSupport* platform_support) + : platform_support_(platform_support) { } Core::~Core() { @@ -469,7 +469,7 @@ return result; scoped_refptr<SharedBufferDispatcher> dispatcher; - result = SharedBufferDispatcher::Create(platform_support(), validated_options, + result = SharedBufferDispatcher::Create(platform_support_, validated_options, num_bytes, &dispatcher); if (result != MOJO_RESULT_OK) { DCHECK(!dispatcher);
diff --git a/third_party/mojo/src/mojo/edk/system/core.h b/third_party/mojo/src/mojo/edk/system/core.h index 0ff9c018..7833193c 100644 --- a/third_party/mojo/src/mojo/edk/system/core.h +++ b/third_party/mojo/src/mojo/edk/system/core.h
@@ -39,7 +39,9 @@ // --------------------------------------------------------------------------- // These methods are only to be used by via the embedder API (and internally): - explicit Core(scoped_ptr<embedder::PlatformSupport> platform_support); + + // |*platform_support| must outlive this object. + explicit Core(embedder::PlatformSupport* platform_support); virtual ~Core(); // Adds |dispatcher| to the handle table, returning the handle for it. Returns @@ -59,12 +61,19 @@ base::Callback<void(MojoResult)> callback); embedder::PlatformSupport* platform_support() const { - return platform_support_.get(); + return platform_support_; } // --------------------------------------------------------------------------- - // System calls implementation: + // The following methods are essentially implementations of the Mojo Core + // functions of the Mojo API, with the C interface translated to C++ by + // "mojo/edk/embedder/entrypoints.cc". The best way to understand the contract + // of these methods is to look at the header files defining the corresponding + // API functions, referenced below. + + // These methods correspond to the API functions defined in + // "mojo/public/c/system/functions.h": MojoTimeTicks GetTimeTicksNow(); MojoResult Close(MojoHandle handle); MojoResult Wait(MojoHandle handle, @@ -77,6 +86,9 @@ MojoDeadline deadline, UserPointer<uint32_t> result_index, UserPointer<MojoHandleSignalsState> signals_states); + + // These methods correspond to the API functions defined in + // "mojo/public/c/system/message_pipe.h": MojoResult CreateMessagePipe( UserPointer<const MojoCreateMessagePipeOptions> options, UserPointer<MojoHandle> message_pipe_handle0, @@ -93,6 +105,9 @@ UserPointer<MojoHandle> handles, UserPointer<uint32_t> num_handles, MojoReadMessageFlags flags); + + // These methods correspond to the API functions defined in + // "mojo/public/c/system/data_pipe.h": MojoResult CreateDataPipe( UserPointer<const MojoCreateDataPipeOptions> options, UserPointer<MojoHandle> data_pipe_producer_handle, @@ -117,6 +132,9 @@ MojoReadDataFlags flags); MojoResult EndReadData(MojoHandle data_pipe_consumer_handle, uint32_t num_bytes_read); + + // These methods correspond to the API functions defined in + // "mojo/public/c/system/buffer.h": MojoResult CreateSharedBuffer( UserPointer<const MojoCreateSharedBufferOptions> options, uint64_t num_bytes, @@ -146,7 +164,7 @@ uint32_t* result_index, HandleSignalsState* signals_states); - const scoped_ptr<embedder::PlatformSupport> platform_support_; + embedder::PlatformSupport* const platform_support_; // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we // had them).
diff --git a/third_party/mojo/src/mojo/edk/system/core_test_base.cc b/third_party/mojo/src/mojo/edk/system/core_test_base.cc index b81a051..7196886d 100644 --- a/third_party/mojo/src/mojo/edk/system/core_test_base.cc +++ b/third_party/mojo/src/mojo/edk/system/core_test_base.cc
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "mojo/edk/embedder/simple_platform_support.h" #include "mojo/edk/system/configuration.h" #include "mojo/edk/system/core.h" #include "mojo/edk/system/dispatcher.h" @@ -173,7 +172,7 @@ } void CoreTestBase::SetUp() { - core_ = new Core(make_scoped_ptr(new embedder::SimplePlatformSupport())); + core_ = new Core(&platform_support_); } void CoreTestBase::TearDown() {
diff --git a/third_party/mojo/src/mojo/edk/system/core_test_base.h b/third_party/mojo/src/mojo/edk/system/core_test_base.h index c2b5ee2..26b7925 100644 --- a/third_party/mojo/src/mojo/edk/system/core_test_base.h +++ b/third_party/mojo/src/mojo/edk/system/core_test_base.h
@@ -5,9 +5,9 @@ #ifndef MOJO_EDK_SYSTEM_CORE_TEST_BASE_H_ #define MOJO_EDK_SYSTEM_CORE_TEST_BASE_H_ -#include "base/compiler_specific.h" #include "base/macros.h" #include "base/synchronization/lock.h" +#include "mojo/edk/embedder/simple_platform_support.h" #include "mojo/public/c/system/types.h" #include "testing/gtest/include/gtest/gtest.h" @@ -38,6 +38,7 @@ Core* core() { return core_; } private: + embedder::SimplePlatformSupport platform_support_; Core* core_; DISALLOW_COPY_AND_ASSIGN(CoreTestBase);
diff --git a/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc b/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc index b78dfb61..4d7deae 100644 --- a/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc +++ b/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc
@@ -20,9 +20,14 @@ namespace mojo { namespace system { -const ProcessIdentifier kFirstProcessIdentifier = 1; -const ProcessIdentifier kMasterProcessIdentifier = - static_cast<ProcessIdentifier>(-1); +const ProcessIdentifier kFirstSlaveProcessIdentifier = 2; + +static_assert(kMasterProcessIdentifier != kInvalidProcessIdentifier, + "Bad master process identifier"); +static_assert(kFirstSlaveProcessIdentifier != kInvalidProcessIdentifier, + "Bad first slave process identifier"); +static_assert(kMasterProcessIdentifier != kFirstSlaveProcessIdentifier, + "Master and first slave process identifiers are the same"); // MasterConnectionManager::Helper --------------------------------------------- @@ -218,7 +223,7 @@ : creation_thread_task_runner_(base::MessageLoop::current()->task_runner()), master_process_delegate_(), private_thread_("MasterConnectionManagerPrivateThread"), - next_process_identifier_(kFirstProcessIdentifier) { + next_process_identifier_(kFirstSlaveProcessIdentifier) { DCHECK(creation_thread_task_runner_); AssertOnCreationThread(); // Just make sure this assertion works correctly. }
diff --git a/third_party/mojo/src/mojo/edk/system/master_connection_manager.h b/third_party/mojo/src/mojo/edk/system/master_connection_manager.h index dcec9c2a..978d9fe5 100644 --- a/third_party/mojo/src/mojo/edk/system/master_connection_manager.h +++ b/third_party/mojo/src/mojo/edk/system/master_connection_manager.h
@@ -30,6 +30,9 @@ namespace system { +// The master process will always have this "process identifier". +const ProcessIdentifier kMasterProcessIdentifier = 1; + // The |ConnectionManager| implementation for the master process. // // Objects of this class must be created, initialized (via |Init()|), shut down
diff --git a/third_party/mojo/src/mojo/edk/test/BUILD.gn b/third_party/mojo/src/mojo/edk/test/BUILD.gn index b130440..3a15663 100644 --- a/third_party/mojo/src/mojo/edk/test/BUILD.gn +++ b/third_party/mojo/src/mojo/edk/test/BUILD.gn
@@ -76,6 +76,20 @@ # Public SDK test targets follow. These targets are not defined within the # public SDK itself as running the unittests requires the EDK. +# TODO(vtl): These don't really belong here. (They should be converted to +# apptests, but even apart from that these targets belong somewhere else.) + +group("public_tests") { + testonly = true + deps = [ + ":mojo_public_application_unittests", + ":mojo_public_bindings_unittests", + ":mojo_public_environment_unittests", + ":mojo_public_system_perftests", + ":mojo_public_system_unittests", + ":mojo_public_utility_unittests", + ] +} test("mojo_public_application_unittests") { deps = [
diff --git a/third_party/mojo/src/mojo/public/DEPS b/third_party/mojo/src/mojo/public/DEPS deleted file mode 100644 index 0c679b9..0000000 --- a/third_party/mojo/src/mojo/public/DEPS +++ /dev/null
@@ -1,6 +0,0 @@ -include_rules = [ - "-base", - "-build", - "-mojo", - "+mojo/public", -]
diff --git a/third_party/mojo/src/mojo/public/VERSION b/third_party/mojo/src/mojo/public/VERSION index 55ad309..63d6820 100644 --- a/third_party/mojo/src/mojo/public/VERSION +++ b/third_party/mojo/src/mojo/public/VERSION
@@ -1 +1 @@ -126532ce21c5c3c55a1e1693731411cb60169efd \ No newline at end of file +8d45c89c30b230843c5bd6dd0693a555750946c0 \ No newline at end of file
diff --git a/third_party/mojo/src/mojo/public/c/DEPS b/third_party/mojo/src/mojo/public/c/DEPS deleted file mode 100644 index 5272770..0000000 --- a/third_party/mojo/src/mojo/public/c/DEPS +++ /dev/null
@@ -1,16 +0,0 @@ -include_rules = [ - # Require explicit dependencies in each directory. - "-mojo/public", - # But everyone can depend on the C system headers. - "+mojo/public/c/system", -] - -specific_include_rules = { - r".*_(unit|perf)test\.cc": [ - "+testing", - # Our test harness is C++, so allow the use of C++: - "+mojo/public/cpp/system", - "+mojo/public/cpp/test_support", - "+mojo/public/cpp/utility", - ], -}
diff --git a/third_party/mojo/src/mojo/public/c/gles2/DEPS b/third_party/mojo/src/mojo/public/c/gles2/DEPS deleted file mode 100644 index 3887457..0000000 --- a/third_party/mojo/src/mojo/public/c/gles2/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/c/environment", -]
diff --git a/third_party/mojo/src/mojo/public/c/system/buffer.h b/third_party/mojo/src/mojo/public/c/system/buffer.h index 97bc340..45d2c2d7 100644 --- a/third_party/mojo/src/mojo/public/c/system/buffer.h +++ b/third_party/mojo/src/mojo/public/c/system/buffer.h
@@ -169,9 +169,9 @@ MojoMapBufferFlags flags); // Unmaps a buffer pointer that was mapped by |MojoMapBuffer()|. |buffer| must -// have been the result of |MojoMapBuffer()| (not some pointer strictly inside +// have been the result of |MojoMapBuffer()| (not some other pointer inside // the mapped memory), and the entire mapping will be removed (partial unmapping -// is not supported). A mapping may only be unmapped exactly once. +// is not supported). A mapping may only be unmapped once. // // Returns: // |MOJO_RESULT_OK| on success.
diff --git a/third_party/mojo/src/mojo/public/c/system/data_pipe.h b/third_party/mojo/src/mojo/public/c/system/data_pipe.h index 089ead3..86126c1 100644 --- a/third_party/mojo/src/mojo/public/c/system/data_pipe.h +++ b/third_party/mojo/src/mojo/public/c/system/data_pipe.h
@@ -81,8 +81,8 @@ // elements. // |MOJO_READ_DATA_FLAG_QUERY| - Query the number of elements available to // read. For use with |MojoReadData()| only. Mutually exclusive with -// |MOJO_READ_DATA_FLAG_DISCARD| and |MOJO_READ_DATA_FLAG_ALL_OR_NONE| is -// ignored if this flag is set. +// |MOJO_READ_DATA_FLAG_DISCARD|, and |MOJO_READ_DATA_FLAG_ALL_OR_NONE| +// is ignored if this flag is set. // |MOJO_READ_DATA_FLAG_PEEK| - Read elements without removing them. For use // with |MojoReadData()| only. Mutually exclusive with // |MOJO_READ_DATA_FLAG_DISCARD| and |MOJO_READ_DATA_FLAG_QUERY|. @@ -264,8 +264,8 @@ // available to future reads. // // If flags has |MOJO_READ_DATA_FLAG_DISCARD| set, it discards up to -// |*num_bytes| (which again be a multiple of the element size) bytes of data, -// setting |*num_bytes| to the amount actually discarded. If flags has +// |*num_bytes| (which again must be a multiple of the element size) bytes of +// data, setting |*num_bytes| to the amount actually discarded. If flags has // |MOJO_READ_DATA_FLAG_ALL_OR_NONE|, it will either discard exactly // |*num_bytes| bytes of data or none. In this case, |MOJO_READ_DATA_FLAG_QUERY| // must not be set, and |elements| is ignored (and should typically be set to
diff --git a/third_party/mojo/src/mojo/public/c/system/functions.h b/third_party/mojo/src/mojo/public/c/system/functions.h index 5e0a0c41..c53a4ed0 100644 --- a/third_party/mojo/src/mojo/public/c/system/functions.h +++ b/third_party/mojo/src/mojo/public/c/system/functions.h
@@ -9,8 +9,6 @@ #ifndef MOJO_PUBLIC_C_SYSTEM_FUNCTIONS_H_ #define MOJO_PUBLIC_C_SYSTEM_FUNCTIONS_H_ -// Note: This header should be compilable as C. - #include "mojo/public/c/system/system_export.h" #include "mojo/public/c/system/types.h" @@ -25,9 +23,12 @@ // operation's success/failure. E.g., a separate |flags| parameter may control // whether a given "in/out" parameter is used for input, output, or both.) -// Platform-dependent monotonically increasing tick count representing "right -// now." The resolution of this clock is ~1-15ms. Resolution varies depending -// on hardware/operating system configuration. +// Returns the time, in microseconds, since some undefined point in the past. +// The values are only meaningful relative to other values that were obtained +// from the same device without an intervening system restart. Such values are +// guaranteed to be monotonically-increasing with the passage of real time. +// Although the units are microseconds, the resolution of the clock may vary and +// is typically in the range of ~1-15 ms. MOJO_SYSTEM_EXPORT MojoTimeTicks MojoGetTimeTicksNow(void); // Closes the given |handle|. @@ -71,7 +72,7 @@ // end of a message pipe and the other end is closed). // // If there are multiple waiters (on different threads, obviously) waiting on -// the same handle and signal, and that signal becomes is satisfied, all waiters +// the same handle and signal, and that signal becomes satisfied, all waiters // will be awoken. MOJO_SYSTEM_EXPORT MojoResult MojoWait(MojoHandle handle,
diff --git a/third_party/mojo/src/mojo/public/c/system/message_pipe.h b/third_party/mojo/src/mojo/public/c/system/message_pipe.h index 97d8887..d42c3fc 100644 --- a/third_party/mojo/src/mojo/public/c/system/message_pipe.h +++ b/third_party/mojo/src/mojo/public/c/system/message_pipe.h
@@ -90,8 +90,6 @@ // |*options| is invalid). // |MOJO_RESULT_RESOURCE_EXHAUSTED| if a process/system/quota/etc. limit has // been reached. -// -// TODO(vtl): Add an options struct pointer argument. MOJO_SYSTEM_EXPORT MojoResult MojoCreateMessagePipe( const struct MojoCreateMessagePipeOptions* options, // Optional. MojoHandle* message_pipe_handle0, // Out. @@ -118,7 +116,7 @@ // latter case). // |MOJO_RESULT_FAILED_PRECONDITION| if the other endpoint has been closed. // Note that closing an endpoint is not necessarily synchronous (e.g., -// across processes), so this function may be succeed even if the other +// across processes), so this function may succeed even if the other // endpoint has been closed (in which case the message would be dropped). // |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|. // |MOJO_RESULT_BUSY| if some handle to be sent is currently in use. @@ -133,37 +131,37 @@ uint32_t num_handles, MojoWriteMessageFlags flags); -// Reads a message from the message pipe endpoint given by -// |message_pipe_handle|; also usable to query the size of the next message or -// discard the next message. |bytes|/|*num_bytes| indicate the buffer/buffer -// size to receive the message data (if any) and |handles|/|*num_handles| -// indicate the buffer/maximum handle count to receive the attached handles (if -// any). +// Reads the next message from a message pipe, or indicates the size of the +// message if it cannot fit in the provided buffers. The message will be read +// in its entirety or not at all; if it is not, it will remain enqueued unless +// the |MOJO_READ_MESSAGE_FLAG_MAY_DISCARD| flag was passed. At most one +// message will be consumed from the queue, and the return value will indicate +// whether a message was successfully read. // -// |num_bytes| and |num_handles| are optional "in-out" parameters. If non-null, -// on return |*num_bytes| and |*num_handles| will usually indicate the number -// of bytes and number of attached handles in the "next" message, respectively, -// whether that message was read or not. (If null, the number of bytes/handles -// is treated as zero.) +// |num_bytes| and |num_handles| are optional in/out parameters that on input +// must be set to the sizes of the |bytes| and |handles| arrays, and on output +// will be set to the actual number of bytes or handles contained in the +// message (even if the message was not retrieved due to being too large). +// Either |num_bytes| or |num_handles| may be null if the message is not +// expected to contain the corresponding type of data, but such a call would +// fail with |MOJO_RESULT_RESOURCE_EXHAUSTED| if the message in fact did +// contain that type of data. // -// If |bytes| is null, then |*num_bytes| must be zero, and similarly for -// |handles| and |*num_handles|. -// -// Partial reads are NEVER done. Either a full read is done and |MOJO_RESULT_OK| -// returned, or the read is NOT done and |MOJO_RESULT_RESOURCE_EXHAUSTED| is -// returned (if |MOJO_READ_MESSAGE_FLAG_MAY_DISCARD| was set, the message is -// also discarded in this case). +// |bytes| and |handles| will receive the contents of the message, if it is +// retrieved. Either or both may be null, in which case the corresponding size +// parameter(s) must also be set to zero or passed as null. // // Returns: // |MOJO_RESULT_OK| on success (i.e., a message was actually read). // |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid. // |MOJO_RESULT_FAILED_PRECONDITION| if the other endpoint has been closed. -// |MOJO_RESULT_RESOURCE_EXHAUSTED| if one of the buffers to receive the -// message/attached handles (|bytes|/|*num_bytes| or -// |handles|/|*num_handles|) was too small. (TODO(vtl): Reconsider this -// error code; should distinguish this from the hitting-system-limits -// case.) +// |MOJO_RESULT_RESOURCE_EXHAUSTED| if the message was too large to fit in the +// provided buffer(s). The message will have been left in the queue or +// discarded, depending on flags. // |MOJO_RESULT_SHOULD_WAIT| if no message was available to be read. +// +// TODO(vtl): Reconsider the |MOJO_RESULT_RESOURCE_EXHAUSTED| error code; should +// distinguish this from the hitting-system-limits case. MOJO_SYSTEM_EXPORT MojoResult MojoReadMessage(MojoHandle message_pipe_handle, void* bytes, // Optional out.
diff --git a/third_party/mojo/src/mojo/public/c/system/tests/core_unittest.cc b/third_party/mojo/src/mojo/public/c/system/tests/core_unittest.cc index 2f3ef62..71e61f4 100644 --- a/third_party/mojo/src/mojo/public/c/system/tests/core_unittest.cc +++ b/third_party/mojo/src/mojo/public/c/system/tests/core_unittest.cc
@@ -109,6 +109,9 @@ EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); EXPECT_EQ(kSignalAll, state.satisfiable_signals); + // Last parameter is optional. + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_WRITABLE, 0, NULL)); + // Try to read. buffer_size = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
diff --git a/third_party/mojo/src/mojo/public/c/system/types.h b/third_party/mojo/src/mojo/public/c/system/types.h index a88b024..9f85fbb 100644 --- a/third_party/mojo/src/mojo/public/c/system/types.h +++ b/third_party/mojo/src/mojo/public/c/system/types.h
@@ -17,7 +17,8 @@ // TODO(vtl): Notes: Use of undefined flags will lead to undefined behavior // (typically they'll be ignored), not necessarily an error. -// |MojoTimeTicks|: Used to specify time ticks. Value is in microseconds. +// |MojoTimeTicks|: A time delta, in microseconds, the meaning of which is +// source-dependent. typedef int64_t MojoTimeTicks;
diff --git a/third_party/mojo/src/mojo/public/cpp/DEPS b/third_party/mojo/src/mojo/public/cpp/DEPS deleted file mode 100644 index 74acd7c..0000000 --- a/third_party/mojo/src/mojo/public/cpp/DEPS +++ /dev/null
@@ -1,18 +0,0 @@ -include_rules = [ - # Require explicit dependencies in each directory. - "-mojo/public", - # But everyone can depend on the C and C++ system headers. - "+mojo/public/c/system", - "+mojo/public/cpp/system", - # Ditto for the C environment headers (but not the C++ environment, since it - # has dependencies of its own). - "+mojo/public/c/environment", -] - -specific_include_rules = { - r".*_(unit|perf)test\.cc": [ - "+testing", - "+mojo/public/cpp/test_support", - "+mojo/public/cpp/utility", - ], -}
diff --git a/third_party/mojo/src/mojo/public/cpp/README.md b/third_party/mojo/src/mojo/public/cpp/README.md index 8f03d98..4404c24 100644 --- a/third_party/mojo/src/mojo/public/cpp/README.md +++ b/third_party/mojo/src/mojo/public/cpp/README.md
@@ -8,7 +8,7 @@ wrappers provide increased convenience and/or type-safety. Other subdirectories provide support (static) libraries of various sorts. In -this case, the organization is to have the public interface for the library in +this case, the organization is to have the public interface for the library defined in header files in the subdirectory itself and the implementation of the library at a lower level, under a lib (sub)subdirectory. A developer should be able to substitute their own implementation of any such support library, and
diff --git a/third_party/mojo/src/mojo/public/cpp/application/DEPS b/third_party/mojo/src/mojo/public/cpp/application/DEPS deleted file mode 100644 index 503eebc..0000000 --- a/third_party/mojo/src/mojo/public/cpp/application/DEPS +++ /dev/null
@@ -1,11 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/bindings", - "+mojo/public/cpp/environment", - "+mojo/public/interfaces/application", - "+mojo/public/interfaces/service_provider", -] -specific_include_rules = { - r"application_test_base\.h": [ - "+testing/gtest/include/gtest", - ], -} \ No newline at end of file
diff --git a/third_party/mojo/src/mojo/public/cpp/application/application_impl.h b/third_party/mojo/src/mojo/public/cpp/application/application_impl.h index bb92307f..46d368d 100644 --- a/third_party/mojo/src/mojo/public/cpp/application/application_impl.h +++ b/third_party/mojo/src/mojo/public/cpp/application/application_impl.h
@@ -79,20 +79,15 @@ // Block until the Application is initialized, if it is not already. void WaitForInitialize(); - // Unbinds the Shell and Application connections. Must be called after - // Initialize. + // Unbinds the Shell and Application connections. Can be used to re-bind the + // handles to another implementation of ApplicationImpl, for instance when + // running apptests. void UnbindConnections(InterfaceRequest<Application>* application_request, ShellPtr* shell); // Quits the main run loop for this application. static void Terminate(); - protected: - // Application implementation. - void AcceptConnection(const String& requestor_url, - InterfaceRequest<ServiceProvider> services, - ServiceProviderPtr exposed_services) override; - private: class ShellPtrWatcher; @@ -103,11 +98,15 @@ Terminate(); } + // Application implementation. + void AcceptConnection(const String& requestor_url, + InterfaceRequest<ServiceProvider> services, + ServiceProviderPtr exposed_services) override; + void RequestQuit() override; typedef std::vector<internal::ServiceRegistry*> ServiceRegistryList; - bool initialized_; ServiceRegistryList incoming_service_registries_; ServiceRegistryList outgoing_service_registries_; ApplicationDelegate* delegate_;
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/DEPS b/third_party/mojo/src/mojo/public/cpp/application/lib/DEPS deleted file mode 100644 index a04ed0f..0000000 --- a/third_party/mojo/src/mojo/public/cpp/application/lib/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/utility", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc index 4d1f8dc..c66dbb5 100644 --- a/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc +++ b/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc
@@ -26,8 +26,7 @@ ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate, InterfaceRequest<Application> request) - : initialized_(false), - delegate_(delegate), + : delegate_(delegate), binding_(this, request.Pass()), shell_watch_(nullptr) { }
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc index 72058a4..ba6dd3f 100644 --- a/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc +++ b/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc
@@ -42,7 +42,7 @@ void WaitForInitialize() { // Initialize is always the first call made on Application. - binding_.WaitForIncomingMethodCall(); + MOJO_CHECK(binding_.WaitForIncomingMethodCall()); } private:
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/service_registry.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/service_registry.cc index d934a16..01c6c70e 100644 --- a/third_party/mojo/src/mojo/public/cpp/application/lib/service_registry.cc +++ b/third_party/mojo/src/mojo/public/cpp/application/lib/service_registry.cc
@@ -18,8 +18,10 @@ InterfaceRequest<ServiceProvider> local_services) : application_impl_(application_impl), url_(url), - local_binding_(this, local_services.Pass()), + local_binding_(this), remote_service_provider_(remote_services.Pass()) { + if (local_services.is_pending()) + local_binding_.Bind(local_services.Pass()); } ServiceRegistry::ServiceRegistry()
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/DEPS b/third_party/mojo/src/mojo/public/cpp/bindings/DEPS deleted file mode 100644 index 2a0496e..0000000 --- a/third_party/mojo/src/mojo/public/cpp/bindings/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/environment", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/lib/DEPS b/third_party/mojo/src/mojo/public/cpp/bindings/lib/DEPS deleted file mode 100644 index b809b58..0000000 --- a/third_party/mojo/src/mojo/public/cpp/bindings/lib/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/bindings", - "+mojo/public/cpp/environment", - "+mojo/public/cpp/system", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/string.h b/third_party/mojo/src/mojo/public/cpp/bindings/string.h index ba0d8fa81..e0ed4ba 100644 --- a/third_party/mojo/src/mojo/public/cpp/bindings/string.h +++ b/third_party/mojo/src/mojo/public/cpp/bindings/string.h
@@ -13,6 +13,9 @@ namespace mojo { +// A UTF-8 encoded character string that can be null. Provides functions that +// are similar to std::string, along with access to the underlying std::string +// object. class String { public: typedef internal::String_Data Data_;
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/struct_ptr.h b/third_party/mojo/src/mojo/public/cpp/bindings/struct_ptr.h index a420fa5..04a8130f 100644 --- a/third_party/mojo/src/mojo/public/cpp/bindings/struct_ptr.h +++ b/third_party/mojo/src/mojo/public/cpp/bindings/struct_ptr.h
@@ -25,6 +25,7 @@ } // namespace internal +// Smart pointer wrapping a mojom structure with move-only semantics. template <typename Struct> class StructPtr { MOJO_MOVE_ONLY_TYPE(StructPtr)
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/DEPS b/third_party/mojo/src/mojo/public/cpp/bindings/tests/DEPS deleted file mode 100644 index b99d520..0000000 --- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/environment", - "+mojo/public/interfaces/bindings/tests", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/environment/DEPS b/third_party/mojo/src/mojo/public/cpp/environment/DEPS deleted file mode 100644 index 04346d9..0000000 --- a/third_party/mojo/src/mojo/public/cpp/environment/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/bindings/callback.h", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/environment/lib/DEPS b/third_party/mojo/src/mojo/public/cpp/environment/lib/DEPS deleted file mode 100644 index 1889e1f..0000000 --- a/third_party/mojo/src/mojo/public/cpp/environment/lib/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/environment", - "+mojo/public/cpp/utility", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/test_support/DEPS b/third_party/mojo/src/mojo/public/cpp/test_support/DEPS deleted file mode 100644 index 6dc53942..0000000 --- a/third_party/mojo/src/mojo/public/cpp/test_support/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/c/test_support", -]
diff --git a/third_party/mojo/src/mojo/public/cpp/utility/DEPS b/third_party/mojo/src/mojo/public/cpp/utility/DEPS deleted file mode 100644 index a9dfbd1..0000000 --- a/third_party/mojo/src/mojo/public/cpp/utility/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/bindings/callback.h" -]
diff --git a/third_party/mojo/src/mojo/public/cpp/utility/run_loop.h b/third_party/mojo/src/mojo/public/cpp/utility/run_loop.h index 5ebe63e..4673eaa 100644 --- a/third_party/mojo/src/mojo/public/cpp/utility/run_loop.h +++ b/third_party/mojo/src/mojo/public/cpp/utility/run_loop.h
@@ -15,6 +15,8 @@ class RunLoopHandler; +// Watches handles for signals and calls event handlers when they occur. Also +// executes delayed tasks. This class should only be used by a single thread. class RunLoop { public: RunLoop(); @@ -31,8 +33,17 @@ // created. static RunLoop* current(); - // Registers a RunLoopHandler for the specified handle. Only one handler can - // be registered for a specified handle. + // Registers a RunLoopHandler for the specified handle. It is an error to + // register more than one handler for a handle, and crashes the process. + // + // The handler's OnHandleReady() method is invoked after one of the signals in + // |handle_signals| occurs. Note that the handler remains registered until + // explicitly removed or an error occurs. + // + // The handler's OnHandleError() method is invoked if the deadline elapses, an + // error is detected, or the RunLoop is being destroyed. The handler is + // automatically unregistered before calling OnHandleError(), so it will not + // receive any further notifications. void AddHandler(RunLoopHandler* handler, const Handle& handle, MojoHandleSignals handle_signals,
diff --git a/third_party/mojo/src/mojo/public/dart/DEPS b/third_party/mojo/src/mojo/public/dart/DEPS deleted file mode 100644 index 53d0007..0000000 --- a/third_party/mojo/src/mojo/public/dart/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+dart", - "+base", -] \ No newline at end of file
diff --git a/third_party/mojo/src/mojo/public/dart/core.dart b/third_party/mojo/src/mojo/public/dart/core.dart index ecd671d..6cdbe26 100644 --- a/third_party/mojo/src/mojo/public/dart/core.dart +++ b/third_party/mojo/src/mojo/public/dart/core.dart
@@ -16,6 +16,5 @@ part 'src/handle.dart'; part 'src/handle_watcher.dart'; part 'src/message_pipe.dart'; -part 'src/timer_impl.dart'; part 'src/timer_queue.dart'; part 'src/types.dart';
diff --git a/third_party/mojo/src/mojo/public/dart/rules.gni b/third_party/mojo/src/mojo/public/dart/rules.gni new file mode 100644 index 0000000..aea59e3 --- /dev/null +++ b/third_party/mojo/src/mojo/public/dart/rules.gni
@@ -0,0 +1,112 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Rules to generate python packaged applications for Dart + +import("../mojo_sdk.gni") + +template("dart_package") { + action(target_name) { + script = rebase_path("mojo/public/tools/gn/zip.py", ".", mojo_root) + + inputs = invoker.sources + + deps = [] + zip_inputs = [] + + if (defined(invoker.deps)) { + deps += invoker.deps + foreach(d, invoker.deps) { + dep_name = get_label_info(d, "name") + dep_target_out_dir = get_label_info(d, "target_out_dir") + zip_inputs += [ "$dep_target_out_dir/$dep_name.dartzip" ] + } + } + + if (defined(invoker.datadeps)) { + datadeps = invoker.datadeps + } + + output = "$target_out_dir/$target_name.dartzip" + outputs = [ + output, + ] + + rebase_base_dir = + rebase_path(get_label_info(":$target_name", "dir"), root_build_dir) + rebase_inputs = rebase_path(inputs, root_build_dir) + rebase_zip_inputs = rebase_path(zip_inputs, root_build_dir) + rebase_output = rebase_path(output, root_build_dir) + args = [ + "--base-dir=$rebase_base_dir", + "--inputs=$rebase_inputs", + "--zip-inputs=$rebase_zip_inputs", + "--output=$rebase_output", + ] + } +} + +# Use this template to generate a .mojo dart application. One of the source +# files should be named main.dart and contain a main function as the +# entry point. Dependencies of dart_packaged_application targets should be +# either mojom targets (and specified using the mojom_deps variable) or +# dart_package targets. +template("dart_packaged_application") { + package_name = "${target_name}_package" + package_output = "$target_out_dir/$package_name.dartzip" + + if (defined(invoker.output_name)) { + mojo_output = "$root_out_dir/" + invoker.output_name + ".mojo" + } else { + mojo_output = "$root_out_dir/" + target_name + ".mojo" + } + + dart_package(package_name) { + sources = invoker.sources + if (defined(invoker.deps)) { + deps = invoker.deps + } + if (defined(invoker.mojom_deps)) { + mojom_deps = invoker.mojom_deps + } + if (defined(invoker.datadeps)) { + datadeps = invoker.datadeps + } + } + + action(target_name) { + script = rebase_path("mojo/public/tools/prepend.py", ".", mojo_root) + + input = package_output + inputs = [ + input, + ] + + output = mojo_output + outputs = [ + output, + ] + + deps = [ + ":$package_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.mojom_deps)) { + deps += invoker.mojom_deps + } + if (defined(invoker.datadeps)) { + datadeps = invoker.datadeps + } + + rebase_input = rebase_path(input, root_build_dir) + rebase_output = rebase_path(output, root_build_dir) + args = [ + "--input=$rebase_input", + "--output=$rebase_output", + "--line=#!mojo mojo:dart_content_handler", + ] + } +}
diff --git a/third_party/mojo/src/mojo/public/dart/src/application.dart b/third_party/mojo/src/mojo/public/dart/src/application.dart index 55002f5e..2819625a 100644 --- a/third_party/mojo/src/mojo/public/dart/src/application.dart +++ b/third_party/mojo/src/mojo/public/dart/src/application.dart
@@ -33,7 +33,7 @@ void requestQuit() => _application._requestQuitAndClose(); - void close() => shell.close(); + void close({bool nodefer: false}) => shell.close(); } // TODO(zra): Better documentation and examples.
diff --git a/third_party/mojo/src/mojo/public/dart/src/codec.dart b/third_party/mojo/src/mojo/public/dart/src/codec.dart index 7ad8370..268daee 100644 --- a/third_party/mojo/src/mojo/public/dart/src/codec.dart +++ b/third_party/mojo/src/mojo/public/dart/src/codec.dart
@@ -18,6 +18,12 @@ bool isArrayNullable(int nullability) => (nullability & kArrayNullable) > 0; bool isElementNullable(int nullability) => (nullability & kElementNullable) > 0; +class MojoCodecError { + final String message; + MojoCodecError(this.message); + String toString() => message; +} + class _EncoderBuffer { ByteData buffer; List<core.MojoHandle> handles; @@ -88,7 +94,7 @@ void encodeUint8(int value, int offset) { if (value < 0) { - throw '$kErrorUnsigned: $val'; + throw new MojoCodecError('$kErrorUnsigned: $val'); } _buffer.buffer.setUint8(_base + offset, value); } @@ -98,7 +104,7 @@ void encodeUint16(int value, int offset) { if (value < 0) { - throw '$kErrorUnsigned: $val'; + throw new MojoCodecError('$kErrorUnsigned: $val'); } _buffer.buffer.setUint16(_base + offset, value, Endianness.LITTLE_ENDIAN); } @@ -108,7 +114,7 @@ void encodeUint32(int value, int offset) { if (value < 0) { - throw '$kErrorUnsigned: $val'; + throw new MojoCodecError('$kErrorUnsigned: $val'); } _buffer.buffer.setUint32(_base + offset, value, Endianness.LITTLE_ENDIAN); } @@ -118,7 +124,7 @@ void encodeUint64(int value, int offset) { if (value < 0) { - throw '$kErrorUnsigned: $val'; + throw new MojoCodecError('$kErrorUnsigned: $val'); } _buffer.buffer.setUint64(_base + offset, value, Endianness.LITTLE_ENDIAN); } @@ -176,14 +182,16 @@ void encodeNullPointer(int offset, bool nullable) { if (!nullable) { - throw 'Trying to encode a null pointer for a non-nullable type'; + throw new MojoCodecError( + 'Trying to encode a null pointer for a non-nullable type'); } _buffer.buffer.setUint64(_base + offset, 0, Endianness.LITTLE_ENDIAN); } void encodeInvalideHandle(int offset, bool nullable) { if (!nullable) { - throw 'Trying to encode a null pointer for a non-nullable type'; + throw new MojoCodecError( + 'Trying to encode a null pointer for a non-nullable type'); } _buffer.buffer.setInt32(_base + offset, -1, Endianness.LITTLE_ENDIAN); } @@ -207,7 +215,8 @@ int elementSize, int length, int offset, int expectedLength) { if ((expectedLength != kUnspecifiedArrayLength) && (expectedLength != length)) { - throw 'Trying to encode a fixed array of incorrect length'; + throw new MojoCodecError( + 'Trying to encode a fixed array of incorrect length'); } return encoderForArrayByTotalSize(length * elementSize, length, offset); } @@ -226,7 +235,8 @@ } if ((expectedLength != kUnspecifiedArrayLength) && (expectedLength != value.length)) { - throw 'Trying to encode a fixed array of incorrect size.'; + throw new MojoCodecError( + 'Trying to encode a fixed array of incorrect size.'); } var bytes = new Uint8List((value.length + 7) ~/ kAlignment); for (int i = 0; i < bytes.length; ++i) { @@ -411,34 +421,34 @@ } void appendInt8Array(List<int> value) => - appendBytes(new Uint8List.view(new Int8List.fromList(value))); + appendBytes(new Uint8List.view(new Int8List.fromList(value).buffer)); void appendUint8Array(List<int> value) => appendBytes(new Uint8List.fromList(value)); void appendInt16Array(List<int> value) => - appendBytes(new Uint8List.view(new Int16List.fromList(value))); + appendBytes(new Uint8List.view(new Int16List.fromList(value).buffer)); void appendUint16Array(List<int> value) => - appendBytes(new Uint8List.view(new Uint16List.fromList(value))); + appendBytes(new Uint8List.view(new Uint16List.fromList(value).buffer)); void appendInt32Array(List<int> value) => - appendBytes(new Uint8List.view(new Int32List.fromList(value))); + appendBytes(new Uint8List.view(new Int32List.fromList(value).buffer)); void appendUint32Array(List<int> value) => - appendBytes(new Uint8List.view(new Uint32List.fromList(value))); + appendBytes(new Uint8List.view(new Uint32List.fromList(value).buffer)); void appendInt64Array(List<int> value) => - appendBytes(new Uint8List.view(new Int64List.fromList(value))); + appendBytes(new Uint8List.view(new Int64List.fromList(value).buffer)); void appendUint64Array(List<int> value) => - appendBytes(new Uint8List.view(new Uint64List.fromList(value))); + appendBytes(new Uint8List.view(new Uint64List.fromList(value).buffer)); void appendFloatArray(List<int> value) => - appendBytes(new Uint8List.view(new Float32List.fromList(value))); + appendBytes(new Uint8List.view(new Float32List.fromList(value).buffer)); void appendDoubleArray(List<int> value) => - appendBytes(new Uint8List.view(new Float64List.fromList(value))); + appendBytes(new Uint8List.view(new Float64List.fromList(value).buffer)); Encoder encoderForMap(int offset) { encodePointerToNextUnclaimed(offset); @@ -447,16 +457,59 @@ } +class _Validator { + final int _maxMemory; + final int _numberOfHandles; + int _minNextClaimedHandle = 0; + int _minNextMemory = 0; + + _Validator(this._maxMemory, this._numberOfHandles); + + void claimHandle(int handle) { + if (handle < _minNextClaimedHandle) { + throw new MojoCodecError('Trying to access handle out of order.'); + } + if (handle >= _numberOfHandles) { + throw new MojoCodecError('Trying to access non present handle.'); + } + _minNextClaimedHandle = handle + 1; + } + + void claimMemory(int start, int end) { + if ((start % kAlignment) != 0) { + throw new MojoCodecError('Incorrect starting alignment: $start.'); + } + if (start < _minNextMemory) { + throw new MojoCodecError('Trying to access memory out of order.'); + } + if (end < start) { + throw new MojoCodecError('Incorrect memory range.'); + } + if (end > _maxMemory) { + throw new MojoCodecError('Trying to access out of range memory.'); + } + _minNextMemory = align(end); + } +} + + class Decoder { + _Validator _validator; Message _message; int _base = 0; - Decoder(this._message, [this._base = 0]); + Decoder(this._message, [this._base = 0, this._validator = null]) { + if (_validator == null) { + _validator = new _Validator( + _message.buffer.lengthInBytes, _message.handles.length); + } + } - Decoder getDecoderAtPosition(int offset) => new Decoder(_message, offset); + Decoder getDecoderAtPosition(int offset) => + new Decoder(_message, offset, _validator); - factory Decoder.atOffset(Decoder d, int offset) => - new Decoder(d._message, offset); + factory Decoder.atOffset(Decoder d, int offset, _Validator validator) => + new Decoder(d._message, offset, validator); ByteData get _buffer => _message.buffer; List<core.MojoHandle> get _handles => _message.handles; @@ -487,10 +540,12 @@ int index = decodeInt32(offset); if (index == -1) { if (!nullable) { - throw 'Trying to decode an invalid handle from a non-nullable type.'; + throw new MojoCodecError( + 'Trying to decode an invalid handle from a non-nullable type.'); } return new core.MojoHandle(core.MojoHandle.INVALID); } + _validator.claimHandle(index); return _handles[index]; } @@ -524,17 +579,26 @@ int pointerOffset = decodeUint64(offset); if (pointerOffset == 0) { if (!nullable) { - throw 'Trying to decode a null pointer for a non-nullable type'; + throw new MojoCodecError( + 'Trying to decode a null pointer for a non-nullable type'); } return null; } int newPosition = (basePosition + pointerOffset); - return new Decoder.atOffset(this, newPosition); + return new Decoder.atOffset(this, newPosition, _validator); } DataHeader decodeDataHeader() { + _validator.claimMemory(_base, _base + DataHeader.kHeaderSize); int size = decodeUint32(DataHeader.kSizeOffset); int numFields = decodeUint32(DataHeader.kNumFieldsOffset); + if (size < 0) { + throw new MojoCodecError('Negative size.'); + } + if (numFields < 0) { + throw new MojoCodecError('Negative number of fields.'); + } + _validator.claimMemory(_base + DataHeader.kHeaderSize, _base + size); return new DataHeader(size, numFields); } @@ -542,11 +606,13 @@ DataHeader decodeDataHeaderForBoolArray(int expectedLength) { var header = decodeDataHeader(); if (header.size < DataHeader.kHeaderSize + (header.numFields + 7) ~/ 8) { - throw 'Array header is incorrect'; + throw new MojoCodecError('Array header is incorrect'); } if ((expectedLength != kUnspecifiedArrayLength) && (header.numFields != expectedLength)) { - throw 'Incorrect array length'; + throw new MojoCodecError( + 'Incorrect array length. Expected $expectedLength, but got ' + '${header.numFields}.'); } return header; } @@ -576,11 +642,14 @@ DataHeader decodeDataHeaderForArray(int elementSize, int expectedLength) { var header = decodeDataHeader(); if (header.size < DataHeader.kHeaderSize + header.numFields * elementSize) { - throw 'Array header is incorrect: $header, elementSize = $elementSize'; + throw new MojoCodecError( + 'Array header is incorrect: $header, elementSize = $elementSize'); } if ((expectedLength != kUnspecifiedArrayLength) && (header.numFields != expectedLength)) { - throw 'Incorrect array length.'; + throw new MojoCodecError( + 'Incorrect array length. Expected $expectedLength, but got ' + '${header.numFields}'); } return header; } @@ -588,11 +657,11 @@ DataHeader decodeDataHeaderForPointerArray(int expectedLength) => decodeDataHeaderForArray(kPointerSize, expectedLength); - List<int> decodeArray(Function arrayViewer, - int elementSize, - int offset, - int nullability, - int expectedLength) { + List decodeArray(Function arrayViewer, + int elementSize, + int offset, + int nullability, + int expectedLength) { Decoder d = decodePointer(offset, isArrayNullable(nullability)); if (d == null) { return null; @@ -728,4 +797,17 @@ } return _stringOfUtf8(bytes); } + + DataHeader decodeDataHeaderForMap() { + var header = decodeDataHeader(); + if (header.size != kMapStructHeader.size) { + throw new MojoCodecError( + 'Incorrect header for map. The size is incorrect.'); + } + if (header.numFields != kMapStructHeader.numFields) { + throw new MojoCodecError( + 'Incorrect header for map. The number of fields is incorrect.'); + } + return header; + } }
diff --git a/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart b/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart index 3d14f6c..da688d4 100644 --- a/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart +++ b/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart
@@ -19,11 +19,6 @@ // The MojoHandleWatcher sends a stream of events to application isolates that // register Mojo handles with it. Application isolates make the following calls: // -// Start() - Starts up the MojoHandleWatcher isolate. Should be called only once -// per VM process. -// -// Stop() - Causes the MojoHandleWatcher isolate to exit. -// // add(handle, port, signals) - Instructs the MojoHandleWatcher isolate to add // 'handle' to the set of handles it watches, and to notify the calling // isolate only for the events specified by 'signals' using the send port @@ -291,7 +286,9 @@ return new MojoResult(result); } - static Future<Isolate> Start() { + // Starts up the MojoHandleWatcher isolate. Should be called only once + // per VM process. + static Future<Isolate> _start() { // Make a control message pipe, MojoMessagePipe pipe = new MojoMessagePipe(); int consumerHandle = pipe.endpoints[0].handle.h; @@ -305,7 +302,9 @@ return Isolate.spawn(_handleWatcherIsolate, consumerHandle); } - static void Stop() { + // Causes the MojoHandleWatcher isolate to exit. Should be called only + // once per VM process. + static void _stop() { // Create a port for notification that the handle watcher has shutdown. var shutdownReceivePort = new ReceivePort(); var shutdownSendPort = shutdownReceivePort.sendPort; @@ -339,7 +338,7 @@ return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); } - static MojoResult timer(SendPort port, int deadline) { + static MojoResult timer(Object ignored, SendPort port, int deadline) { // The deadline will be unwrapped before sending to the handle watcher. return _sendControlData( new MojoHandle(deadline), port, _encodeCommand(TIMER));
diff --git a/third_party/mojo/src/mojo/public/dart/src/message.dart b/third_party/mojo/src/mojo/public/dart/src/message.dart index 2cdda8a..918d219 100644 --- a/third_party/mojo/src/mojo/public/dart/src/message.dart +++ b/third_party/mojo/src/mojo/public/dart/src/message.dart
@@ -35,12 +35,18 @@ MessageHeader.fromMessage(Message message) { var decoder = new Decoder(message); _header = decoder.decodeDataHeader(); + if (_header.size < kSimpleMessageSize) { + throw new MojoCodecError( + 'Incorrect message size. Got: ${_header.size} ' + 'wanted $kSimpleMessageSize'); + } type = decoder.decodeUint32(kMessageTypeOffset); flags = decoder.decodeUint32(kMessageFlagsOffset); if (mustHaveRequestId(flags)) { if (_header.size < kMessageWithRequestIdSize) { - throw 'Incorrect message size. Got: ${_header.size} ' + - 'wanted $kMessageWithRequestIdSize'; + throw new MojoCodecError( + 'Incorrect message size. Got: ${_header.size} ' + 'wanted $kMessageWithRequestIdSize'); } requestId = decoder.decodeUint64(kMessageRequestIdOffset); } else { @@ -63,6 +69,35 @@ ServiceMessage get serviceMessage => new ServiceMessage(this); String toString() => "MessageHeader($_header, $type, $flags, $requestId)"; + + bool validateHeaderFlags(expectedFlags) => + (flags & (kMessageExpectsResponse | kMessageIsResponse)) == expectedFlags; + + bool validateHeader(int expectedType, int expectedFlags) => + (type == expectedType) && validateHeaderFlags(expectedFlags); + + static void _validateDataHeader(DataHeader dataHeader) { + if (dataHeader.numFields < kSimpleMessageNumFields) { + throw 'Incorrect number of fields, expecting at least ' + '$kSimpleMessageNumFields, but got: ${dataHeader.numFields}.'; + } + if (dataHeader.size < kSimpleMessageSize) { + throw 'Incorrect message size, expecting at least $kSimpleMessageSize, ' + 'but got: ${dataHeader.size}'; + } + if ((dataHeader.numFields == kSimpleMessageSize) && + (dataHeader.size != kSimpleMessageSize)) { + throw 'Incorrect message size for a message with $kSimpleMessageNumFields' + ' fields, expecting $kSimpleMessageSize, ' + 'but got ${dataHeader.size}'; + } + if ((dataHeader.numFields == kMessageWithRequestIdNumFields) && + (dataHeader.size != kMessageWithRequestIdSize)) { + throw 'Incorrect message size for a message with ' + '$kMessageWithRequestIdNumFields fields, expecting ' + '$kMessageWithRequestIdSize, but got ${dataHeader.size}'; + } + } }
diff --git a/third_party/mojo/src/mojo/public/dart/src/message_pipe.dart b/third_party/mojo/src/mojo/public/dart/src/message_pipe.dart index 325be42..7733d33 100644 --- a/third_party/mojo/src/mojo/public/dart/src/message_pipe.dart +++ b/third_party/mojo/src/mojo/public/dart/src/message_pipe.dart
@@ -49,9 +49,11 @@ return status; } + int dataLengthInBytes = (data == null) ? 0 : data.lengthInBytes; + // If numBytes has the default value, use the full length of the data. - int dataNumBytes = (numBytes == -1) ? data.lengthInBytes : numBytes; - if (dataNumBytes > data.lengthInBytes) { + int dataNumBytes = (numBytes == -1) ? dataLengthInBytes : numBytes; + if (dataNumBytes > dataLengthInBytes) { status = MojoResult.INVALID_ARGUMENT; return status; }
diff --git a/third_party/mojo/src/mojo/public/dart/src/proxy.dart b/third_party/mojo/src/mojo/public/dart/src/proxy.dart index f662f3ae..1186232 100644 --- a/third_party/mojo/src/mojo/public/dart/src/proxy.dart +++ b/third_party/mojo/src/mojo/public/dart/src/proxy.dart
@@ -47,8 +47,8 @@ var header = new MessageHeader(name); var serviceMessage = message.serializeWithHeader(header); endpoint.write(serviceMessage.buffer, - serviceMessage.buffer.lengthInBytes, - serviceMessage.handles); + serviceMessage.buffer.lengthInBytes, + serviceMessage.handles); if (!endpoint.status.isOk) { throw "message pipe write failed"; } @@ -66,8 +66,8 @@ var header = new MessageHeader.withRequestId(name, flags, id); var serviceMessage = message.serializeWithHeader(header); endpoint.write(serviceMessage.buffer, - serviceMessage.buffer.lengthInBytes, - serviceMessage.handles); + serviceMessage.buffer.lengthInBytes, + serviceMessage.handles); if (!endpoint.status.isOk) { throw "message pipe write failed"; }
diff --git a/third_party/mojo/src/mojo/public/dart/src/service_provider.dart b/third_party/mojo/src/mojo/public/dart/src/service_provider.dart index deac6bc7..6b07f2e 100644 --- a/third_party/mojo/src/mojo/public/dart/src/service_provider.dart +++ b/third_party/mojo/src/mojo/public/dart/src/service_provider.dart
@@ -30,10 +30,11 @@ _proxy.connectToService(name, pipe.endpoints[1]); } - close() { + close({bool nodefer : false}) { if (_proxy != null) { _proxy.close(); _proxy = null; } + super.close(nodefer: nodefer); } }
diff --git a/third_party/mojo/src/mojo/public/dart/src/stub.dart b/third_party/mojo/src/mojo/public/dart/src/stub.dart index b4ab293..8238736 100644 --- a/third_party/mojo/src/mojo/public/dart/src/stub.dart +++ b/third_party/mojo/src/mojo/public/dart/src/stub.dart
@@ -20,6 +20,9 @@ // Query how many bytes are available. var result = endpoint.query(); assert(result.status.isOk || result.status.isResourceExhausted); + if (result.bytesRead == 0) { + throw new MojoCodecError('Unexpected empty message.'); + } // Read the data and view as a message. var bytes = new ByteData(result.bytesRead); @@ -41,7 +44,7 @@ response.buffer.lengthInBytes, response.handles); if (!endpoint.status.isOk) { - throw "message pipe write failed: ${endpoint.status}"; + throw 'message pipe write failed: ${endpoint.status}'; } if (_isClosing && (_outstandingResponseFutures == 0)) { // This was the final response future for which we needed to send @@ -63,9 +66,12 @@ throw 'Unexpected write signal in client.'; } - void close() { + // NB: |nodefer| should only be true when calling close() while handling an + // exception thrown from handleRead(), e.g. when we receive a malformed + // message. + void close({bool nodefer : false}) { if (!isOpen) return; - if (isInHandler || (_outstandingResponseFutures > 0)) { + if (!nodefer && (isInHandler || (_outstandingResponseFutures > 0))) { // Either close() is being called from within handleRead() or // handleWrite(), or close() is being called while there are outstanding // response futures. Defer the actual close until all response futures
diff --git a/third_party/mojo/src/mojo/public/dart/src/timer_impl.dart b/third_party/mojo/src/mojo/public/dart/src/timer_impl.dart deleted file mode 100644 index 61fee6d..0000000 --- a/third_party/mojo/src/mojo/public/dart/src/timer_impl.dart +++ /dev/null
@@ -1,333 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This code is adapted from the Timer implementation in the standalone Dart VM -// for use in the Mojo embedder. - -part of core; - -// Timer heap implemented as a array-based binary heap[0]. -// This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n)) -// `add`. -// -// To ensure the timers are ordered by insertion time, the _Timer class has a -// `_id` field set when added to the heap. -// -// [0] http://en.wikipedia.org/wiki/Binary_heap -class _TimerHeap { - List<_Timer> _list; - int _used = 0; - - _TimerHeap([int initSize = 7]) - : _list = new List<_Timer>(initSize); - - bool get isEmpty => _used == 0; - bool get isNotEmpty => _used > 0; - - _Timer get first => _list[0]; - - bool isFirst(_Timer timer) => timer._indexOrNext == 0; - - void add(_Timer timer) { - if (_used == _list.length) { - _resize(); - } - timer._indexOrNext = _used++; - _list[timer._indexOrNext] = timer; - _bubbleUp(timer); - } - - _Timer removeFirst() { - var f = first; - remove(f); - return f; - } - - void remove(_Timer timer) { - _used--; - timer._id = -1; - if (isEmpty) { - _list[0] = null; - timer._indexOrNext = null; - return; - } - var last = _list[_used]; - if (!identical(last, timer)) { - last._indexOrNext = timer._indexOrNext; - _list[last._indexOrNext] = last; - if (last._compareTo(timer) < 0) { - _bubbleUp(last); - } else { - _bubbleDown(last); - } - } - _list[_used] = null; - timer._indexOrNext = null; - } - - void _resize() { - var newList = new List(_list.length * 2 + 1); - newList.setRange(0, _used, _list); - _list = newList; - } - - void _bubbleUp(_Timer timer) { - while (!isFirst(timer)) { - Timer parent = _parent(timer); - if (timer._compareTo(parent) < 0) { - _swap(timer, parent); - } else { - break; - } - } - } - - void _bubbleDown(_Timer timer) { - while (true) { - int leftIndex = _leftChildIndex(timer._indexOrNext); - int rightIndex = _rightChildIndex(timer._indexOrNext); - _Timer newest = timer; - if (leftIndex < _used && _list[leftIndex]._compareTo(newest) < 0) { - newest = _list[leftIndex]; - } - if (rightIndex < _used && _list[rightIndex]._compareTo(newest) < 0) { - newest = _list[rightIndex]; - } - if (identical(newest, timer)) { - // We are where we should be, break. - break; - } - _swap(newest, timer); - } - } - - void _swap(_Timer first, _Timer second) { - int tmp = first._indexOrNext; - first._indexOrNext = second._indexOrNext; - second._indexOrNext = tmp; - _list[first._indexOrNext] = first; - _list[second._indexOrNext] = second; - } - - Timer _parent(_Timer timer) => _list[_parentIndex(timer._indexOrNext)]; - Timer _leftChild(_Timer timer) => _list[_leftChildIndex(timer._indexOrNext)]; - Timer _rightChild(_Timer timer) => - _list[_rightChildIndex(timer._indexOrNext)]; - - static int _parentIndex(int index) => (index - 1) ~/ 2; - static int _leftChildIndex(int index) => 2 * index + 1; - static int _rightChildIndex(int index) => 2 * index + 2; -} - -class _Timer implements Timer { - // Disables the timer. - static const int _NO_TIMER = -1; - - // Timers are ordered by wakeup time. - static _TimerHeap _heap = new _TimerHeap(); - static _Timer _firstZeroTimer; - static _Timer _lastZeroTimer; - static int _idCount = 0; - - static RawReceivePort _receivePort; - static SendPort _sendPort; - static bool _handlingCallbacks = false; - - Function _callback; - int _milliSeconds; - int _wakeupTime = 0; - var _indexOrNext; - int _id = -1; - - static Timer _createTimer(void callback(Timer timer), - int milliSeconds, - bool repeating) { - _Timer timer = new _Timer._internal(); - timer._callback = callback; - if (milliSeconds > 0) { - // Add one because DateTime.now() is assumed to round down - // to nearest millisecond, not up, so that time + duration is before - // duration milliseconds from now. Using micosecond timers like - // Stopwatch allows detecting that the timer fires early. - timer._wakeupTime = - new DateTime.now().millisecondsSinceEpoch + 1 + milliSeconds; - } - timer._milliSeconds = repeating ? milliSeconds : -1; - if (timer._addTimerToHeap()) { - // The new timer is the first in queue. Update event handler. - _notifyEventHandler(); - } - return timer; - } - - factory _Timer(int milliSeconds, void callback(Timer timer)) { - return _createTimer(callback, milliSeconds, false); - } - - factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) { - return _createTimer(callback, milliSeconds, true); - } - - _Timer._internal() {} - - bool get _isInHeap => _id >= 0; - - void _clear() { - _callback = null; - } - - int _compareTo(_Timer other) { - int c = _wakeupTime - other._wakeupTime; - if (c != 0) return c; - return _id - other._id; - } - - bool get _repeating => _milliSeconds >= 0; - - bool get isActive => _callback != null; - - // Cancels a set timer. The timer is removed from the timer list and if - // the given timer is the earliest timer the native timer is reset. - void cancel() { - _clear(); - if (!_isInHeap) return; - assert(_wakeupTime != 0); - bool update = (_firstZeroTimer == null) && _heap.isFirst(this); - _heap.remove(this); - if (update) { - _notifyEventHandler(); - } - } - - void _advanceWakeupTime() { - assert(_milliSeconds >= 0); - _wakeupTime += _milliSeconds; - } - - // Adds a timer to the timer list. Timers with the same wakeup time are - // enqueued in order and notified in FIFO order. - bool _addTimerToHeap() { - if (_wakeupTime == 0) { - if (_firstZeroTimer == null) { - _lastZeroTimer = this; - _firstZeroTimer = this; - return true; - } else { - _lastZeroTimer._indexOrNext = this; - _lastZeroTimer = this; - return false; - } - } else { - _id = _idCount++; - _heap.add(this); - return _firstZeroTimer == null && _heap.isFirst(this); - } - } - - - static void _notifyEventHandler() { - if (_handlingCallbacks) { - // While we are already handling callbacks we will not notify the event - // handler. _handleTimeout will call _notifyEventHandler once all pending - // timers are processed. - return; - } - - if (_firstZeroTimer == null && _heap.isEmpty) { - // No pending timers: Close the receive port and let the event handler - // know. - if (_receivePort != null) { - MojoHandleWatcher.timer(_sendPort, _NO_TIMER); - _shutdownTimerHandler(); - } - } else { - if (_receivePort == null) { - // Create a receive port and register a message handler for the timer - // events. - _createTimerHandler(); - } - if (_firstZeroTimer != null) { - _sendPort.send(null); - } else { - MojoHandleWatcher.timer(_sendPort, _heap.first._wakeupTime); - } - } - } - - static void _handleTimeout(_) { - int currentTime = new DateTime.now().millisecondsSinceEpoch; - // Collect all pending timers. - var timer = _firstZeroTimer; - var nextTimer = _lastZeroTimer; - _firstZeroTimer = null; - _lastZeroTimer = null; - while (_heap.isNotEmpty && _heap.first._wakeupTime <= currentTime) { - var next = _heap.removeFirst(); - if (timer == null) { - nextTimer = next; - timer = next; - } else { - nextTimer._indexOrNext = next; - nextTimer = next; - } - } - - // Trigger all of the pending timers. New timers added as part of the - // callbacks will be enqueued now and notified in the next spin at the - // earliest. - _handlingCallbacks = true; - try { - while (timer != null) { - var next = timer._indexOrNext; - timer._indexOrNext = null; - // One of the timers in the pending_timers list can cancel - // one of the later timers which will set the callback to - // null. - if (timer._callback != null) { - var callback = timer._callback; - if (!timer._repeating) { - // Mark timer as inactive. - timer._callback = null; - } - callback(timer); - // Re-insert repeating timer if not canceled. - if (timer._repeating && timer._callback != null) { - timer._advanceWakeupTime(); - timer._addTimerToHeap(); - } - } - timer = next; - } - } finally { - _handlingCallbacks = false; - _notifyEventHandler(); - } - } - - // Creates a receive port and registers the timer handler on that - // receive port. - static void _createTimerHandler() { - if(_receivePort == null) { - _receivePort = new RawReceivePort(_handleTimeout); - _sendPort = _receivePort.sendPort; - } - } - - static void _shutdownTimerHandler() { - _receivePort.close(); - _receivePort = null; - _sendPort = null; - } -} - -// Provide a closure which will allocate a Timer object to be able to hook -// up the Timer interface in dart:isolate with the implementation here. -_getTimerFactoryClosure() { - return (int milliSeconds, void callback(Timer timer), bool repeating) { - if (repeating) { - return new _Timer.periodic(milliSeconds, callback); - } - return new _Timer(milliSeconds, callback); - }; -}
diff --git a/third_party/mojo/src/mojo/public/go/bindings/decoder.go b/third_party/mojo/src/mojo/public/go/bindings/decoder.go index 2dccd0ad..3f3cce9 100644 --- a/third_party/mojo/src/mojo/public/go/bindings/decoder.go +++ b/third_party/mojo/src/mojo/public/go/bindings/decoder.go
@@ -185,6 +185,7 @@ if err := ensureElementBitSizeAndCapacity(d.state(), 8); err != nil { return 0, err } + d.state().alignOffsetToBytes() value := d.buf[d.state().offset] d.state().skipBytes(1) d.state().elementsProcessed++ @@ -202,6 +203,7 @@ if err := ensureElementBitSizeAndCapacity(d.state(), 16); err != nil { return 0, err } + d.state().alignOffsetToBytes() d.state().offset = align(d.state().offset, 2) value := binary.LittleEndian.Uint16(d.buf[d.state().offset:]) d.state().skipBytes(2) @@ -220,6 +222,7 @@ if err := ensureElementBitSizeAndCapacity(d.state(), 32); err != nil { return 0, err } + d.state().alignOffsetToBytes() d.state().offset = align(d.state().offset, 4) value := binary.LittleEndian.Uint32(d.buf[d.state().offset:]) d.state().skipBytes(4) @@ -238,6 +241,7 @@ if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { return 0, err } + d.state().alignOffsetToBytes() d.state().offset = align(d.state().offset, 8) value := binary.LittleEndian.Uint64(d.buf[d.state().offset:]) d.state().skipBytes(8) @@ -300,16 +304,59 @@ if newEnd%8 != 0 { return 0, fmt.Errorf("incorrect pointer data alignment: %d", newEnd) } - d.claimData(d.end - int(newEnd)) + d.claimData(int(newEnd) - d.end) return pointer, nil } -// ReadMessagePipeHandle reads a message pipe handle. -func (d *Decoder) ReadMessagePipeHandle() (system.MessagePipeHandle, error) { +// ReadUntypedHandle reads an untyped handle. +func (d *Decoder) ReadUntypedHandle() (system.UntypedHandle, error) { handleIndex, err := d.ReadUint32() if err != nil { return nil, err } - untypedHandle, err := d.claimHandle(int(handleIndex)) - return untypedHandle.ToMessagePipeHandle(), err + if handleIndex == ^uint32(0) { + return &InvalidHandle{}, nil + } + return d.claimHandle(int(handleIndex)) +} + +// ReadHandle reads a handle. +func (d *Decoder) ReadHandle() (system.Handle, error) { + return d.ReadUntypedHandle() +} + +// ReadMessagePipeHandle reads a message pipe handle. +func (d *Decoder) ReadMessagePipeHandle() (system.MessagePipeHandle, error) { + if handle, err := d.ReadUntypedHandle(); err != nil { + return nil, err + } else { + return handle.ToMessagePipeHandle(), nil + } +} + +// ReadConsumerHandle reads a data pipe consumer handle. +func (d *Decoder) ReadConsumerHandle() (system.ConsumerHandle, error) { + if handle, err := d.ReadUntypedHandle(); err != nil { + return nil, err + } else { + return handle.ToConsumerHandle(), nil + } +} + +// ReadProducerHandle reads a data pipe producer handle. +func (d *Decoder) ReadProducerHandle() (system.ProducerHandle, error) { + if handle, err := d.ReadUntypedHandle(); err != nil { + return nil, err + } else { + return handle.ToProducerHandle(), nil + } +} + +// ReadSharedBufferHandle reads a shared buffer handle. +func (d *Decoder) ReadSharedBufferHandle() (system.SharedBufferHandle, error) { + if handle, err := d.ReadUntypedHandle(); err != nil { + return nil, err + } else { + return handle.ToSharedBufferHandle(), nil + } }
diff --git a/third_party/mojo/src/mojo/public/go/bindings/encoder.go b/third_party/mojo/src/mojo/public/go/bindings/encoder.go index 210d9b0..5ea1a50c 100644 --- a/third_party/mojo/src/mojo/public/go/bindings/encoder.go +++ b/third_party/mojo/src/mojo/public/go/bindings/encoder.go
@@ -36,6 +36,13 @@ elementsProcessed uint32 } +func (s *encodingState) alignOffsetToBytes() { + if s.bitOffset > 0 { + s.offset++ + s.bitOffset = 0 + } +} + func (s *encodingState) skipBits(count uint32) { s.bitOffset += count s.offset += int(s.bitOffset >> 3) // equal to s.bitOffset / 8 @@ -63,16 +70,6 @@ stateStack []encodingState } -func align(size, alignment int) int { - return ((size - 1) | (alignment - 1)) + 1 -} - -// bytesForBits returns minimum number of bytes required to store provided -// number of bits. -func bytesForBits(bits uint64) int { - return int((bits + 7) / 8) -} - func ensureElementBitSizeAndCapacity(state *encodingState, bitSize uint32) error { if state == nil { return fmt.Errorf("empty state stack") @@ -213,6 +210,7 @@ if err := ensureElementBitSizeAndCapacity(e.state(), 8); err != nil { return err } + e.state().alignOffsetToBytes() e.buf[e.state().offset] = value e.state().skipBytes(1) e.state().elementsProcessed++ @@ -229,6 +227,7 @@ if err := ensureElementBitSizeAndCapacity(e.state(), 16); err != nil { return err } + e.state().alignOffsetToBytes() e.state().offset = align(e.state().offset, 2) binary.LittleEndian.PutUint16(e.buf[e.state().offset:], value) e.state().skipBytes(2) @@ -246,6 +245,7 @@ if err := ensureElementBitSizeAndCapacity(e.state(), 32); err != nil { return err } + e.state().alignOffsetToBytes() e.state().offset = align(e.state().offset, 4) binary.LittleEndian.PutUint32(e.buf[e.state().offset:], value) e.state().skipBytes(4) @@ -263,6 +263,7 @@ if err := ensureElementBitSizeAndCapacity(e.state(), 64); err != nil { return err } + e.state().alignOffsetToBytes() e.state().offset = align(e.state().offset, 8) binary.LittleEndian.PutUint64(e.buf[e.state().offset:], value) e.state().skipBytes(8)
diff --git a/third_party/mojo/src/mojo/public/go/bindings/invalid_handle.go b/third_party/mojo/src/mojo/public/go/bindings/invalid_handle.go new file mode 100644 index 0000000..1acc645 --- /dev/null +++ b/third_party/mojo/src/mojo/public/go/bindings/invalid_handle.go
@@ -0,0 +1,97 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package bindings + +import ( + "mojo/public/go/system" +) + +// InvalidHandle is a handle that will always be invalid. +type InvalidHandle struct { +} + +func (h *InvalidHandle) Close() system.MojoResult { + return system.MOJO_RESULT_INVALID_ARGUMENT +} + +func (h *InvalidHandle) IsValid() bool { + return false +} + +func (h *InvalidHandle) NativeHandle() system.MojoHandle { + return system.MOJO_HANDLE_INVALID +} + +func (h *InvalidHandle) ReleaseNativeHandle() system.MojoHandle { + return system.MOJO_HANDLE_INVALID +} + +func (h *InvalidHandle) ToUntypedHandle() system.UntypedHandle { + return h +} + +func (h *InvalidHandle) Wait(signals system.MojoHandleSignals, deadline system.MojoDeadline) (system.MojoResult, system.MojoHandleSignalsState) { + return system.MOJO_RESULT_INVALID_ARGUMENT, system.MojoHandleSignalsState{} +} + +func (h *InvalidHandle) ToConsumerHandle() system.ConsumerHandle { + return h +} + +func (h *InvalidHandle) ToProducerHandle() system.ProducerHandle { + return h +} + +func (h *InvalidHandle) ToMessagePipeHandle() system.MessagePipeHandle { + return h +} + +func (h *InvalidHandle) ToSharedBufferHandle() system.SharedBufferHandle { + return h +} + +func (h *InvalidHandle) ReadData(flags system.MojoReadDataFlags) (system.MojoResult, []byte) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil +} + +func (h *InvalidHandle) BeginReadData(numBytes int, flags system.MojoReadDataFlags) (system.MojoResult, []byte) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil +} + +func (h *InvalidHandle) EndReadData(numBytesRead int) system.MojoResult { + return system.MOJO_RESULT_INVALID_ARGUMENT +} + +func (h *InvalidHandle) WriteData(data []byte, flags system.MojoWriteDataFlags) (system.MojoResult, int) { + return system.MOJO_RESULT_INVALID_ARGUMENT, 0 +} + +func (h *InvalidHandle) BeginWriteData(numBytes int, flags system.MojoWriteDataFlags) (system.MojoResult, []byte) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil +} + +func (h *InvalidHandle) EndWriteData(numBytesWritten int) system.MojoResult { + return system.MOJO_RESULT_INVALID_ARGUMENT +} + +func (h *InvalidHandle) ReadMessage(flags system.MojoReadMessageFlags) (system.MojoResult, []byte, []system.UntypedHandle) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil, nil +} + +func (h *InvalidHandle) WriteMessage(bytes []byte, handles []system.UntypedHandle, flags system.MojoWriteMessageFlags) system.MojoResult { + return system.MOJO_RESULT_INVALID_ARGUMENT +} + +func (h *InvalidHandle) DuplicateBufferHandle(opts *system.DuplicateBufferHandleOptions) (system.MojoResult, system.SharedBufferHandle) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil +} + +func (h *InvalidHandle) MapBuffer(offset uint64, numBytes int, flags system.MojoMapBufferFlags) (system.MojoResult, []byte) { + return system.MOJO_RESULT_INVALID_ARGUMENT, nil +} + +func (h *InvalidHandle) UnmapBuffer(buffer []byte) system.MojoResult { + return system.MOJO_RESULT_INVALID_ARGUMENT +}
diff --git a/third_party/mojo/src/mojo/public/go/bindings/util.go b/third_party/mojo/src/mojo/public/go/bindings/util.go new file mode 100644 index 0000000..8d51ddb7 --- /dev/null +++ b/third_party/mojo/src/mojo/public/go/bindings/util.go
@@ -0,0 +1,20 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package bindings + +func align(size, alignment int) int { + return ((size - 1) | (alignment - 1)) + 1 +} + +// bytesForBits returns minimum number of bytes required to store provided +// number of bits. +func bytesForBits(bits uint64) int { + return int((bits + 7) / 8) +} + +// StringPointer converts provided string to *string. +func StringPointer(s string) *string { + return &s +}
diff --git a/third_party/mojo/src/mojo/public/interfaces/bindings/tests/test_structs.mojom b/third_party/mojo/src/mojo/public/interfaces/bindings/tests/test_structs.mojom index 40fa9a6..dc4f05e 100644 --- a/third_party/mojo/src/mojo/public/interfaces/bindings/tests/test_structs.mojom +++ b/third_party/mojo/src/mojo/public/interfaces/bindings/tests/test_structs.mojom
@@ -22,7 +22,7 @@ // Used to verify that struct fields which don't specify a default are // initialized to: false for bool, 0 for numbers, and null for strings, -// handles, and structs. The "?" nullable suffix shouldn't have any +// handles, and structs. The "?" nullable suffix shouldn't have any // impact on initial field values. struct NoDefaultFieldValues { @@ -58,7 +58,7 @@ }; // Used to verify that struct fields with an explicit default value -// are initialized correctly. The "?" nullable suffix shouldn't have any +// are initialized correctly. The "?" nullable suffix shouldn't have any // impact on initial field values. struct DefaultFieldValues { @@ -140,6 +140,18 @@ map<string, array<map<string, string>>> f8; }; +// Used to verify that various array types can be encoded and decoded +// successfully. + +struct ArrayValueTypes { + array<int8> f0; + array<int16> f1; + array<int32> f2; + array<int64> f3; + array<float> f4; + array<double> f5; +}; + // Used to verify that various float and double values can be encoded and // decoded correctly. @@ -189,18 +201,18 @@ const int32 V13 = 1234567890; const int32 V14 = 2147483647; - // The limits for JavaScript integers are +/- (2^53 - 1). + // The limits for JavaScript integers are +/- (2^53 - 1). const int64 V15 = -9007199254740991; // Number.MIN_SAFE_INTEGER const int64 V16 = -1; const int64 V17 = 0; const int64 V18 = 1234567890123456; const int64 V19 = 9007199254740991; // Number.MAX_SAFE_INTEGER - int8 f0 = V0; + int8 f0 = V0; int8 f1 = V1; - int8 f2 = V2; - int8 f3 = V3; - int8 f4 = V4; + int8 f2 = V2; + int8 f3 = V3; + int8 f4 = V4; int16 f5 = V5; int16 f6 = V6; @@ -237,14 +249,14 @@ const uint32 V7 = 1234567890; const uint32 V8 = 0xFFFFFFFF; - // The limits for JavaScript integers are +/- (2^53 - 1). + // The limits for JavaScript integers are +/- (2^53 - 1). const uint64 V9 = 0; const uint64 V10 = 1234567890123456; const uint64 V11 = 9007199254740991; // Number.MAX_SAFE_INTEGER - uint8 f0 = V0; + uint8 f0 = V0; uint8 f1 = V1; - uint8 f2 = V2; + uint8 f2 = V2; uint16 f3 = V3; uint16 f4 = V4;
diff --git a/third_party/mojo/src/mojo/public/tests/DEPS b/third_party/mojo/src/mojo/public/tests/DEPS deleted file mode 100644 index 0669117..0000000 --- a/third_party/mojo/src/mojo/public/tests/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+mojo", -]
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl index 952c0dc..a73ad8e3 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
@@ -17,7 +17,7 @@ {{interface|name}}.unbound() : stub = new {{interface|name}}Stub.unbound(); - void close() => stub.close(); + void close({bool nodefer : false}) => stub.close(nodefer: nodefer); StreamSubscription<int> listen() => stub.listen(); @@ -76,7 +76,7 @@ {%- endif %} {%- endfor %} default: - throw new Exception("Unexpected message name"); + throw new bindings.MojoCodecError("Unexpected message name"); break; } } @@ -183,7 +183,7 @@ break; {%- endfor %} default: - throw new Exception("Unexpected message name"); + throw new bindings.MojoCodecError("Unexpected message name"); break; } return null;
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/struct_definition.tmpl b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/struct_definition.tmpl index f5b62a9..f65298f 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/struct_definition.tmpl +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/struct_definition.tmpl
@@ -50,12 +50,13 @@ List<{{kind.key_kind|dart_type}}> keys{{level}}; List<{{kind.value_kind|dart_type}}> values{{level}}; { - {{decode('keys'~level, kind.key_kind|array, 'DataHeader.HEADER_SIZE', 0, level+1)|indent(4)}} + {{decode('keys'~level, kind.key_kind|array, 'bindings.DataHeader.kHeaderSize', 0, level+1)|indent(4)}} } { {{decode('values'~level, kind.value_kind|array('keys'~level~'.length'), 'bindings.DataHeader.kHeaderSize + bindings.kPointerSize', 0, level+1)|indent(4)}} } - {{variable}} = new Map<{{kind.key_kind|dart_type}}, {{kind.value_kind|dart_type}}>.fromIterables(keys, values); + {{variable}} = new Map<{{kind.key_kind|dart_type}}, {{kind.value_kind|dart_type}}>.fromIterables( + keys{{level}}, values{{level}}); {%- else %} var si{{level+1}} = decoder{{level+1}}.decodeDataHeaderForPointerArray({{kind|array_expected_length}}); {{variable}} = new {{kind|dart_type}}(si{{level+1}}.numFields); @@ -105,11 +106,13 @@ return null; } {{struct|name}} result = new {{struct|name}}(); -{%- if not struct.bytes %} - decoder0.decodeDataHeader(); -{%- else %} + var mainDataHeader = decoder0.decodeDataHeader(); -{%- endif %} + if ((mainDataHeader.size < kStructSize) || + (mainDataHeader.numFields < {{struct.packed.packed_fields|length}})) { + throw new bindings.MojoCodecError('Malformed header'); + } + {%- for byte in struct.bytes %} {%- for packed_field in byte.packed_fields %} if (mainDataHeader.numFields > {{packed_field.ordinal}}) {
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/go_templates/source.tmpl b/third_party/mojo/src/mojo/public/tools/bindings/generators/go_templates/source.tmpl new file mode 100644 index 0000000..8c58c4c --- /dev/null +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/go_templates/source.tmpl
@@ -0,0 +1,11 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is autogenerated by: +// mojo/public/tools/bindings/mojom_bindings_generator.py +// For: +// {{module.path}} +// + +package {{package}}
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py index 3251095..d971b53d 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py
@@ -69,9 +69,9 @@ _spec_to_decode_method = { mojom.BOOL.spec: 'decodeBool', - mojom.DCPIPE.spec: 'decodeHandle', + mojom.DCPIPE.spec: 'decodeConsumerHandle', mojom.DOUBLE.spec: 'decodeDouble', - mojom.DPPIPE.spec: 'decodeHandle', + mojom.DPPIPE.spec: 'decodeProducerHandle', mojom.FLOAT.spec: 'decodeFloat', mojom.HANDLE.spec: 'decodeHandle', mojom.INT16.spec: 'decodeInt16', @@ -95,9 +95,9 @@ _spec_to_encode_method = { mojom.BOOL.spec: 'encodeBool', - mojom.DCPIPE.spec: 'encodeHandle', + mojom.DCPIPE.spec: 'encodeConsumerHandle', mojom.DOUBLE.spec: 'encodeDouble', - mojom.DPPIPE.spec: 'encodeHandle', + mojom.DPPIPE.spec: 'encodeProducerHandle', mojom.FLOAT.spec: 'encodeFloat', mojom.HANDLE.spec: 'encodeHandle', mojom.INT16.spec: 'encodeInt16',
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_go_generator.py b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_go_generator.py new file mode 100644 index 0000000..3f7c938 --- /dev/null +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_go_generator.py
@@ -0,0 +1,51 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +'''Generates Go source files from a mojom.Module.''' + +import os + +from mojom.generate.template_expander import UseJinja + +import mojom.generate.generator as generator +import mojom.generate.module as mojom + +def GetPackage(module): + if module.namespace: + return module.namespace.split('.')[-1] + return 'mojom' + +def GetPackagePath(module): + path = 'mojom' + for i in module.namespace.split('.'): + path = os.path.join(path, i) + return path + +class Generator(generator.Generator): + go_filters = {} + + def GetParameters(self): + return { + 'package': GetPackage(self.module), + } + + @UseJinja('go_templates/source.tmpl', filters=go_filters) + def GenerateSource(self): + return self.GetParameters() + + def GenerateFiles(self, args): + self.Write(self.GenerateSource(), os.path.join("go", "src", "gen", + GetPackagePath(self.module), '%s.go' % self.module.name)) + + def GetJinjaParameters(self): + return { + 'lstrip_blocks': True, + 'trim_blocks': True, + } + + def GetGlobals(self): + return { + 'namespace': self.module.namespace, + 'module': self.module, + }
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_java_generator.py b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_java_generator.py index 276d5af..ad8980dd 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_java_generator.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_java_generator.py
@@ -15,6 +15,7 @@ from jinja2 import contextfilter +import mojom.fileutil as fileutil import mojom.generate.generator as generator import mojom.generate.module as mojom from mojom.generate.template_expander import UseJinja @@ -212,7 +213,7 @@ return 'encode(%s)' % ', '.join(params) def GetPackage(module): - if 'JavaPackage' in module.attributes: + if module.attributes and 'JavaPackage' in module.attributes: return ParseStringAttribute(module.attributes['JavaPackage']) # Default package. if module.namespace: @@ -356,7 +357,7 @@ False, generator.GetStructFromMethod(method)) def GetConstantsMainEntityName(module): - if 'JavaConstantsClassName' in module.attributes: + if module.attributes and 'JavaConstantsClassName' in module.attributes: return ParseStringAttribute(module.attributes['JavaConstantsClassName']) # This constructs the name of the embedding classes for module level constants # by extracting the mojom's filename and prepending it to Constants. @@ -471,12 +472,7 @@ return exports def DoGenerateFiles(self): - if not os.path.exists(self.output_dir): - try: - os.makedirs(self.output_dir) - except: - # Ignore errors on directory creation. - pass + fileutil.EnsureDirectoryExists(self.output_dir) # Keep this above the others as .GetStructs() changes the state of the # module, annotating structs with required information.
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/mojom.gni b/third_party/mojo/src/mojo/public/tools/bindings/mojom.gni index 6fc89c1..3e0ca4f 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/mojom.gni +++ b/third_party/mojo/src/mojo/public/tools/bindings/mojom.gni
@@ -73,6 +73,7 @@ "$generator_root/generators/dart_templates/module.lib.tmpl", "$generator_root/generators/dart_templates/module_definition.tmpl", "$generator_root/generators/dart_templates/struct_definition.tmpl", + "$generator_root/generators/go_templates/source.tmpl", "$generator_root/generators/java_templates/constant_definition.tmpl", "$generator_root/generators/java_templates/constants.java.tmpl", "$generator_root/generators/java_templates/enum.java.tmpl", @@ -93,6 +94,7 @@ "$generator_root/generators/python_templates/module.py.tmpl", "$generator_root/generators/mojom_cpp_generator.py", "$generator_root/generators/mojom_dart_generator.py", + "$generator_root/generators/mojom_go_generator.py", "$generator_root/generators/mojom_js_generator.py", "$generator_root/generators/mojom_java_generator.py", "$generator_root/generators/mojom_python_generator.py", @@ -117,6 +119,7 @@ ] generator_dart_outputs = [ "{{source_gen_dir}}/{{source_name_part}}.mojom.dart" ] + generator_dart_zip_output = "$target_out_dir/$target_name.dartzip" generator_java_outputs = [ "{{source_gen_dir}}/{{source_name_part}}.mojom.srcjar" ] generator_js_outputs = [ "{{source_gen_dir}}/{{source_name_part}}.mojom.js" ] @@ -209,7 +212,10 @@ if (defined(invoker.deps)) { deps += invoker.deps } - data_deps = [ ":${target_name}_python" ] + data_deps = [ + ":${target_name}_python", + ":${target_name}_dart", + ] if (defined(invoker.mojo_sdk_deps)) { foreach(sdk_dep, invoker.mojo_sdk_deps) { # Check that the SDK dep was not mistakenly given as an absolute path. @@ -277,6 +283,42 @@ ] } + action("${target_name}_dart") { + script = rebase_path("mojo/public/tools/gn/zip.py", ".", mojo_root) + + inputs = process_file_template(invoker.sources, generator_dart_outputs) + + deps = [] + zip_inputs = [] + + foreach(d, all_deps) { + # Resolve the name, so that a target //mojo/something becomes + # //mojo/something:something and we can append "_dart" to get the dart + # dependency name. + full_name = get_label_info(d, "label_no_toolchain") + dep_name = get_label_info(d, "name") + dep_target_out_dir = get_label_info(d, "target_out_dir") + deps += [ "${full_name}_dart" ] + zip_inputs += [ "$dep_target_out_dir/$dep_name.dartzip" ] + } + + output = generator_dart_zip_output + outputs = [ + output, + ] + + rebase_base_dir = rebase_path("$root_build_dir/gen/", root_build_dir) + rebase_inputs = rebase_path(inputs, root_build_dir) + rebase_zip_inputs = rebase_path(zip_inputs, root_build_dir) + rebase_output = rebase_path(output, root_build_dir) + args = [ + "--base-dir=$rebase_base_dir", + "--inputs=$rebase_inputs", + "--zip-inputs=$rebase_zip_inputs", + "--output=$rebase_output", + ] + } + if (is_android) { import("//build/config/android/rules.gni")
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/mojom_bindings_generator.py b/third_party/mojo/src/mojo/public/tools/bindings/mojom_bindings_generator.py index 2d1802c..0498838 100755 --- a/third_party/mojo/src/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -34,6 +34,7 @@ "pylib")) from mojom.error import Error +import mojom.fileutil as fileutil from mojom.generate.data import OrderedModuleFromData from mojom.parse.parser import Parse from mojom.parse.translate import Translate @@ -50,9 +51,12 @@ if generator_name.lower() == "c++": generator_name = os.path.join(script_dir, "generators", "mojom_cpp_generator.py") - if generator_name.lower() == "dart": + elif generator_name.lower() == "dart": generator_name = os.path.join(script_dir, "generators", "mojom_dart_generator.py") + elif generator_name.lower() == "go": + generator_name = os.path.join(script_dir, "generators", + "mojom_go_generator.py") elif generator_name.lower() == "javascript": generator_name = os.path.join(script_dir, "generators", "mojom_js_generator.py") @@ -191,7 +195,7 @@ help="output directory for generated files") parser.add_argument("-g", "--generators", dest="generators_string", metavar="GENERATORS", - default="c++,dart,javascript,java,python", + default="c++,dart,go,javascript,java,python", help="comma-separated list of generators") parser.add_argument("--debug_print_intermediate", action="store_true", help="print the intermediate representation") @@ -204,8 +208,7 @@ generator_modules = LoadGenerators(args.generators_string) - if not os.path.exists(args.output_dir): - os.makedirs(args.output_dir) + fileutil.EnsureDirectoryExists(args.output_dir) processor = MojomProcessor(lambda filename: filename in args.filename) for filename in args.filename:
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/fileutil.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/fileutil.py new file mode 100644 index 0000000..b321e9f --- /dev/null +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/fileutil.py
@@ -0,0 +1,18 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import errno +import os.path + +def EnsureDirectoryExists(path, always_try_to_create=False): + """A wrapper for os.makedirs that does not error if the directory already + exists. A different process could be racing to create this directory.""" + + if not os.path.exists(path) or always_try_to_create: + try: + os.makedirs(path) + except OSError as e: + # There may have been a race to create this directory. + if e.errno != errno.EEXIST: + raise
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/data.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/data.py index 6d34a403..3a41593 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/data.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/data.py
@@ -42,6 +42,10 @@ rv.__index__ = index return rv +def AddOptional(dictionary, key, value): + if value is not None: + dictionary[key] = value; + builtin_values = frozenset([ "double.INFINITY", "double.NEGATIVE_INFINITY", @@ -186,15 +190,19 @@ return import_item def StructToData(struct): - return { + data = { istr(0, 'name'): struct.name, - istr(1, 'fields'): map(FieldToData, struct.fields) + istr(1, 'fields'): map(FieldToData, struct.fields), + # TODO(yzshen): EnumToData() and ConstantToData() are missing. + istr(2, 'enums'): [], + istr(3, 'constants'): [] } + AddOptional(data, istr(4, 'attributes'), struct.attributes) + return data def StructFromData(module, data): struct = mojom.Struct(module=module) struct.name = data['name'] - struct.attributes = data['attributes'] struct.spec = 'x:' + module.namespace + '.' + struct.name module.kinds[struct.spec] = struct struct.enums = map(lambda enum: @@ -203,13 +211,16 @@ ConstantFromData(module, constant, struct), data['constants']) # Stash fields data here temporarily. struct.fields_data = data['fields'] + struct.attributes = data.get('attributes') return struct def UnionToData(union): - return { + data = { istr(0, 'name'): union.name, istr(1, 'fields'): map(FieldToData, union.fields) } + AddOptional(data, istr(2, 'attributes'), union.attributes) + return data def UnionFromData(module, data): union = mojom.Union(module=module) @@ -218,6 +229,7 @@ module.kinds[union.spec] = union # Stash fields data here temporarily. union.fields_data = data['fields'] + union.attributes = data.get('attributes') return union def FieldToData(field): @@ -225,10 +237,9 @@ istr(0, 'name'): field.name, istr(1, 'kind'): KindToData(field.kind) } - if field.ordinal != None: - data[istr(2, 'ordinal')] = field.ordinal - if field.default != None: - data[istr(3, 'default')] = field.default + AddOptional(data, istr(2, 'ordinal'), field.ordinal) + AddOptional(data, istr(3, 'default'), field.default) + AddOptional(data, istr(4, 'attributes'), field.attributes) return data def FieldFromData(module, data, struct): @@ -239,6 +250,7 @@ field.ordinal = data.get('ordinal') field.default = FixupExpression( module, data.get('default'), (module.namespace, struct.name), field.kind) + field.attributes = data.get('attributes') return field def ParameterToData(parameter): @@ -246,10 +258,9 @@ istr(0, 'name'): parameter.name, istr(1, 'kind'): parameter.kind.spec } - if parameter.ordinal != None: - data[istr(2, 'ordinal')] = parameter.ordinal - if parameter.default != None: - data[istr(3, 'default')] = parameter.default + AddOptional(data, istr(2, 'ordinal'), parameter.ordinal) + AddOptional(data, istr(3, 'default'), parameter.default) + AddOptional(data, istr(4, 'attributes'), parameter.attributes) return data def ParameterFromData(module, data, interface): @@ -259,6 +270,7 @@ module.kinds, data['kind'], (module.namespace, interface.name)) parameter.ordinal = data.get('ordinal') parameter.default = data.get('default') + parameter.attributes = data.get('attributes') return parameter def MethodToData(method): @@ -266,36 +278,39 @@ istr(0, 'name'): method.name, istr(1, 'parameters'): map(ParameterToData, method.parameters) } - if method.ordinal != None: - data[istr(2, 'ordinal')] = method.ordinal - if method.response_parameters != None: - data[istr(3, 'response_parameters')] = map( + if method.response_parameters is not None: + data[istr(2, 'response_parameters')] = map( ParameterToData, method.response_parameters) + AddOptional(data, istr(3, 'ordinal'), method.ordinal) + AddOptional(data, istr(4, 'attributes'), method.attributes) return data def MethodFromData(module, data, interface): method = mojom.Method(interface, data['name'], ordinal=data.get('ordinal')) - method.default = data.get('default') method.parameters = map(lambda parameter: ParameterFromData(module, parameter, interface), data['parameters']) if data.has_key('response_parameters'): method.response_parameters = map( lambda parameter: ParameterFromData(module, parameter, interface), data['response_parameters']) + method.attributes = data.get('attributes') return method def InterfaceToData(interface): - return { + data = { istr(0, 'name'): interface.name, - istr(1, 'client'): interface.client, - istr(2, 'methods'): map(MethodToData, interface.methods) + istr(1, 'methods'): map(MethodToData, interface.methods), + # TODO(yzshen): EnumToData() and ConstantToData() are missing. + istr(2, 'enums'): [], + istr(3, 'constants'): [] } + AddOptional(data, istr(4, 'attributes'), interface.attributes) + return data def InterfaceFromData(module, data): interface = mojom.Interface(module=module) interface.name = data['name'] interface.spec = 'x:' + module.namespace + '.' + interface.name - interface.client = data['client'] if data.has_key('client') else None module.kinds[interface.spec] = interface interface.enums = map(lambda enum: EnumFromData(module, enum, interface), data['enums']) @@ -303,6 +318,7 @@ ConstantFromData(module, constant, interface), data['constants']) # Stash methods data here temporarily. interface.methods_data = data['methods'] + interface.attributes = data.get('attributes') return interface def EnumFieldFromData(module, enum, data, parent_kind): @@ -314,10 +330,11 @@ # vice versa? if parent_kind: field.value = FixupExpression( - module, data['value'], (module.namespace, parent_kind.name), enum) + module, data.get('value'), (module.namespace, parent_kind.name), enum) else: field.value = FixupExpression( - module, data['value'], (module.namespace, ), enum) + module, data.get('value'), (module.namespace, ), enum) + field.attributes = data.get('attributes') value = mojom.EnumValue(module, enum, field) module.values[value.GetSpec()] = value return field @@ -330,10 +347,11 @@ name = parent_kind.name + '.' + name enum.spec = 'x:%s.%s' % (module.namespace, name) enum.parent_kind = parent_kind - enum.fields = map( lambda field: EnumFieldFromData(module, enum, field, parent_kind), data['fields']) + enum.attributes = data.get('attributes') + module.kinds[enum.spec] = enum return enum @@ -353,13 +371,20 @@ return constant def ModuleToData(module): - return { + data = { istr(0, 'name'): module.name, istr(1, 'namespace'): module.namespace, - istr(2, 'structs'): map(StructToData, module.structs), - istr(3, 'interfaces'): map(InterfaceToData, module.interfaces), + # TODO(yzshen): Imports information is missing. + istr(2, 'imports'): [], + istr(3, 'structs'): map(StructToData, module.structs), istr(4, 'unions'): map(UnionToData, module.unions), + istr(5, 'interfaces'): map(InterfaceToData, module.interfaces), + # TODO(yzshen): EnumToData() and ConstantToData() are missing. + istr(6, 'enums'): [], + istr(7, 'constants'): [] } + AddOptional(data, istr(8, 'attributes'), module.attributes) + return data def ModuleFromData(data): module = mojom.Module() @@ -371,12 +396,12 @@ module.name = data['name'] module.namespace = data['namespace'] - module.attributes = data['attributes'] # Imports must come first, because they add to module.kinds which is used # by by the others. module.imports = map( lambda import_data: ImportFromData(module, import_data), data['imports']) + module.attributes = data.get('attributes') # First pass collects kinds. module.enums = map(
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/generator.py index af14ead..401c399 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/generator.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -9,6 +9,7 @@ import re import module as mojom +import mojom.fileutil as fileutil import pack def GetStructFromMethod(method): @@ -50,8 +51,7 @@ def WriteFile(contents, full_path): # Make sure the containing directory exists. full_dir = os.path.dirname(full_path) - if not os.path.exists(full_dir): - os.makedirs(full_dir) + fileutil.EnsureDirectoryExists(full_dir) # Dump the data to disk. with open(full_path, "w+") as f:
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/module.py index 8e52924f..8a0f56ba 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/module.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -130,6 +130,10 @@ ) +ATTRIBUTE_MIN_VERSION = 'MinVersion' +ATTRIBUTE_CLIENT = 'Client' + + class NamedValue(object): def __init__(self, module, parent_kind, name): self.module = module @@ -174,11 +178,18 @@ class Field(object): - def __init__(self, name=None, kind=None, ordinal=None, default=None): + def __init__(self, name=None, kind=None, ordinal=None, default=None, + attributes=None): self.name = name self.kind = kind self.ordinal = ordinal self.default = default + self.attributes = attributes + + @property + def min_version(self): + return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ + if self.attributes else None class Struct(ReferenceKind): @@ -186,8 +197,9 @@ ReferenceKind.AddSharedProperty('module') ReferenceKind.AddSharedProperty('imported_from') ReferenceKind.AddSharedProperty('fields') + ReferenceKind.AddSharedProperty('attributes') - def __init__(self, name=None, module=None): + def __init__(self, name=None, module=None, attributes=None): if name is not None: spec = 'x:' + name else: @@ -197,9 +209,10 @@ self.module = module self.imported_from = None self.fields = [] + self.attributes = attributes - def AddField(self, name, kind, ordinal=None, default=None): - field = Field(name, kind, ordinal, default) + def AddField(self, name, kind, ordinal=None, default=None, attributes=None): + field = Field(name, kind, ordinal, default, attributes) self.fields.append(field) return field @@ -209,8 +222,9 @@ ReferenceKind.AddSharedProperty('module') ReferenceKind.AddSharedProperty('imported_from') ReferenceKind.AddSharedProperty('fields') + ReferenceKind.AddSharedProperty('attributes') - def __init__(self, name=None, module=None): + def __init__(self, name=None, module=None, attributes=None): if name is not None: spec = 'x:' + name else: @@ -220,9 +234,10 @@ self.module = module self.imported_from = None self.fields = [] + self.attributes = attributes - def AddField(self, name, kind, ordinal=None): - field = Field(name, kind, ordinal, default=None) + def AddField(self, name, kind, ordinal=None, attributes=None): + field = Field(name, kind, ordinal, None, attributes) self.fields.append(field) return field @@ -287,42 +302,57 @@ class Parameter(object): - def __init__(self, name=None, kind=None, ordinal=None, default=None): + def __init__(self, name=None, kind=None, ordinal=None, default=None, + attributes=None): self.name = name self.ordinal = ordinal self.kind = kind self.default = default + self.attributes = attributes + + @property + def min_version(self): + return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ + if self.attributes else None class Method(object): - def __init__(self, interface, name, ordinal=None): + def __init__(self, interface, name, ordinal=None, attributes=None): self.interface = interface self.name = name self.ordinal = ordinal self.parameters = [] self.response_parameters = None + self.attributes = attributes - def AddParameter(self, name, kind, ordinal=None, default=None): - parameter = Parameter(name, kind, ordinal, default) + def AddParameter(self, name, kind, ordinal=None, default=None, + attributes=None): + parameter = Parameter(name, kind, ordinal, default, attributes) self.parameters.append(parameter) return parameter - def AddResponseParameter(self, name, kind, ordinal=None, default=None): + def AddResponseParameter(self, name, kind, ordinal=None, default=None, + attributes=None): if self.response_parameters == None: self.response_parameters = [] - parameter = Parameter(name, kind, ordinal, default) + parameter = Parameter(name, kind, ordinal, default, attributes) self.response_parameters.append(parameter) return parameter + @property + def min_version(self): + return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ + if self.attributes else None + class Interface(ReferenceKind): ReferenceKind.AddSharedProperty('module') ReferenceKind.AddSharedProperty('name') ReferenceKind.AddSharedProperty('imported_from') - ReferenceKind.AddSharedProperty('client') ReferenceKind.AddSharedProperty('methods') + ReferenceKind.AddSharedProperty('attributes') - def __init__(self, name=None, client=None, module=None): + def __init__(self, name=None, module=None, attributes=None): if name is not None: spec = 'x:' + name else: @@ -331,23 +361,33 @@ self.module = module self.name = name self.imported_from = None - self.client = client self.methods = [] + self.attributes = attributes - def AddMethod(self, name, ordinal=None): - method = Method(self, name, ordinal=ordinal) + def AddMethod(self, name, ordinal=None, attributes=None): + method = Method(self, name, ordinal, attributes) self.methods.append(method) return method + @property + def client(self): + return self.attributes.get(ATTRIBUTE_CLIENT) if self.attributes else None + class EnumField(object): - def __init__(self, name=None, value=None): + def __init__(self, name=None, value=None, attributes=None): self.name = name self.value = value + self.attributes = attributes + + @property + def min_version(self): + return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ + if self.attributes else None class Enum(Kind): - def __init__(self, name=None, module=None): + def __init__(self, name=None, module=None, attributes=None): self.module = module self.name = name self.imported_from = None @@ -357,10 +397,11 @@ spec = None Kind.__init__(self, spec) self.fields = [] + self.attributes = attributes class Module(object): - def __init__(self, name=None, namespace=None): + def __init__(self, name=None, namespace=None, attributes=None): self.name = name self.path = name self.namespace = namespace @@ -368,19 +409,20 @@ self.unions = [] self.interfaces = [] self.kinds = {} + self.attributes = attributes - def AddInterface(self, name): - interface = Interface(name, module=self) + def AddInterface(self, name, attributes=None): + interface = Interface(name, self, attributes) self.interfaces.append(interface) return interface - def AddStruct(self, name): - struct = Struct(name, module=self) + def AddStruct(self, name, attributes=None): + struct = Struct(name, self, attributes) self.structs.append(struct) return struct - def AddUnion(self, name): - union = Union(name, module=self) + def AddUnion(self, name, attributes=None): + union = Union(name, self, attributes) self.unions.append(union) return union
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/pack.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/pack.py index 8f7bb3b..37d79eb 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/pack.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
@@ -65,6 +65,7 @@ self.size = self.GetSizeForKind(field.kind) self.offset = None self.bit = None + self.min_version = None # Returns the pad necessary to reserve space for alignment of |size|. @@ -103,6 +104,47 @@ ordinal += 1 src_fields.sort(key=lambda field: field.ordinal) + # Set |min_version| for each field. + # + # TODO(yzshen): We are in the middle of converting the |num_fields| field in + # encoded structs to |version|. In order to make code using |num_fields| and + # |version| work together, for structs without any [MinVersion] annotation, + # each field will be treated as if [MinVersion=ordinal+1] is set: + # + # struct Foo { + # int32 field_0; + # int32 field_1; + # } + # + # is treated as: + # + # struct Foo { + # [MinVersion=1] int32 field_0; + # [MinVersion=2] int32 field_1; + # } + # + # This way |num_fields| is the same value as |version|. + # + # This trick needs to be removed once the conversion is done. + + if any(packed_field.field.min_version is not None + for packed_field in src_fields): + # This struct has fields that explicitly set [MinVersion]. Assume that it + # is only handled by code that understands versioning. + next_min_version = 0 + for packed_field in src_fields: + if packed_field.field.min_version is None: + assert next_min_version == 0 + else: + assert packed_field.field.min_version >= next_min_version + next_min_version = packed_field.field.min_version + packed_field.min_version = next_min_version + else: + next_min_version = 1 + for packed_field in src_fields: + packed_field.min_version = next_min_version + next_min_version += 1 + src_field = src_fields[0] src_field.offset = 0 src_field.bit = 0
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/parse/translate.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/parse/translate.py index 88bd269..8fbc86d 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/parse/translate.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
@@ -55,9 +55,13 @@ return map_to_kind[kind] return 'x:' + kind +def _AddOptional(dictionary, key, value): + if value is not None: + dictionary[key] = value; + def _AttributeListToDict(attribute_list): if attribute_list is None: - return {} + return None assert isinstance(attribute_list, ast.AttributeList) # TODO(vtl): Check for duplicate keys here. return dict([(attribute.key, attribute.value) @@ -66,12 +70,17 @@ def _EnumToDict(enum): def EnumValueToDict(enum_value): assert isinstance(enum_value, ast.EnumValue) - return {'name': enum_value.name, - 'value': enum_value.value} + data = {'name': enum_value.name} + _AddOptional(data, 'value', enum_value.value) + _AddOptional(data, 'attributes', + _AttributeListToDict(enum_value.attribute_list)) + return data assert isinstance(enum, ast.Enum) - return {'name': enum.name, + data = {'name': enum.name, 'fields': map(EnumValueToDict, enum.enum_value_list)} + _AddOptional(data, 'attributes', _AttributeListToDict(enum.attribute_list)) + return data def _ConstToDict(const): assert isinstance(const, ast.Const) @@ -88,71 +97,90 @@ def StructToDict(struct): def StructFieldToDict(struct_field): assert isinstance(struct_field, ast.StructField) - return {'name': struct_field.name, - 'kind': _MapKind(struct_field.typename), - 'ordinal': struct_field.ordinal.value \ - if struct_field.ordinal else None, - 'default': struct_field.default_value} + data = {'name': struct_field.name, + 'kind': _MapKind(struct_field.typename)} + _AddOptional(data, 'ordinal', + struct_field.ordinal.value + if struct_field.ordinal else None) + _AddOptional(data, 'default', struct_field.default_value) + _AddOptional(data, 'attributes', + _AttributeListToDict(struct_field.attribute_list)) + return data assert isinstance(struct, ast.Struct) - return {'name': struct.name, - 'attributes': _AttributeListToDict(struct.attribute_list), + data = {'name': struct.name, 'fields': _MapTreeForType(StructFieldToDict, struct.body, ast.StructField), 'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum), 'constants': _MapTreeForType(_ConstToDict, struct.body, ast.Const)} + _AddOptional(data, 'attributes', + _AttributeListToDict(struct.attribute_list)) + return data def UnionToDict(union): def UnionFieldToDict(union_field): assert isinstance(union_field, ast.UnionField) - return {'name': union_field.name, - 'kind': _MapKind(union_field.typename), - 'ordinal': union_field.ordinal.value \ - if union_field.ordinal else None} + data = {'name': union_field.name, + 'kind': _MapKind(union_field.typename)} + _AddOptional(data, 'ordinal', + union_field.ordinal.value + if union_field.ordinal else None) + _AddOptional(data, 'attributes', + _AttributeListToDict(union_field.attribute_list)) + return data + assert isinstance(union, ast.Union) - return {'name': union.name, + data = {'name': union.name, 'fields': _MapTreeForType(UnionFieldToDict, union.body, ast.UnionField)} + _AddOptional(data, 'attributes', + _AttributeListToDict(union.attribute_list)) + return data def InterfaceToDict(interface): def MethodToDict(method): def ParameterToDict(param): assert isinstance(param, ast.Parameter) - return {'name': param.name, - 'kind': _MapKind(param.typename), - 'ordinal': param.ordinal.value if param.ordinal else None} + data = {'name': param.name, + 'kind': _MapKind(param.typename)} + _AddOptional(data, 'ordinal', + param.ordinal.value if param.ordinal else None) + _AddOptional(data, 'attributes', + _AttributeListToDict(param.attribute_list)) + return data assert isinstance(method, ast.Method) - rv = {'name': method.name, - 'parameters': map(ParameterToDict, method.parameter_list), - 'ordinal': method.ordinal.value if method.ordinal else None} + data = {'name': method.name, + 'parameters': map(ParameterToDict, method.parameter_list)} if method.response_parameter_list is not None: - rv['response_parameters'] = map(ParameterToDict, - method.response_parameter_list) - return rv + data['response_parameters'] = map(ParameterToDict, + method.response_parameter_list) + _AddOptional(data, 'ordinal', + method.ordinal.value if method.ordinal else None) + _AddOptional(data, 'attributes', + _AttributeListToDict(method.attribute_list)) + return data assert isinstance(interface, ast.Interface) - attributes = _AttributeListToDict(interface.attribute_list) - return {'name': interface.name, - 'attributes': attributes, - 'client': attributes.get('Client'), + data = {'name': interface.name, 'methods': _MapTreeForType(MethodToDict, interface.body, ast.Method), 'enums': _MapTreeForType(_EnumToDict, interface.body, ast.Enum), 'constants': _MapTreeForType(_ConstToDict, interface.body, ast.Const)} + _AddOptional(data, 'attributes', + _AttributeListToDict(interface.attribute_list)) + return data assert isinstance(tree, ast.Mojom) self.mojom['name'] = name self.mojom['namespace'] = tree.module.name[1] if tree.module else '' self.mojom['imports'] = \ [{'filename': imp.import_filename} for imp in tree.import_list] - self.mojom['attributes'] = \ - _AttributeListToDict(tree.module.attribute_list) if tree.module else {} self.mojom['structs'] = \ _MapTreeForType(StructToDict, tree.definition_list, ast.Struct) - self.mojom['union'] = \ + self.mojom['unions'] = \ _MapTreeForType(UnionToDict, tree.definition_list, ast.Union) self.mojom['interfaces'] = \ _MapTreeForType(InterfaceToDict, tree.definition_list, ast.Interface) @@ -160,6 +188,9 @@ _MapTreeForType(_EnumToDict, tree.definition_list, ast.Enum) self.mojom['constants'] = \ _MapTreeForType(_ConstToDict, tree.definition_list, ast.Const) + _AddOptional(self.mojom, 'attributes', + _AttributeListToDict(tree.module.attribute_list) + if tree.module else None) return self.mojom
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/fileutil_unittest.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/fileutil_unittest.py new file mode 100644 index 0000000..d56faadb --- /dev/null +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/fileutil_unittest.py
@@ -0,0 +1,55 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import imp +import os.path +import shutil +import sys +import tempfile +import unittest + +def _GetDirAbove(dirname): + """Returns the directory "above" this file containing |dirname| (which must + also be "above" this file).""" + path = os.path.abspath(__file__) + while True: + path, tail = os.path.split(path) + assert tail + if tail == dirname: + return path + +try: + imp.find_module("mojom") +except ImportError: + sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib")) +from mojom import fileutil + + +class FileUtilTest(unittest.TestCase): + + def testEnsureDirectoryExists(self): + """Test that EnsureDirectoryExists fuctions correctly.""" + + temp_dir = tempfile.mkdtemp() + try: + self.assertTrue(os.path.exists(temp_dir)) + + # Directory does not exist, yet. + full = os.path.join(temp_dir, "foo", "bar") + self.assertFalse(os.path.exists(full)) + + # Create the directory. + fileutil.EnsureDirectoryExists(full) + self.assertTrue(os.path.exists(full)) + + # Trying to create it again does not cause an error. + fileutil.EnsureDirectoryExists(full) + self.assertTrue(os.path.exists(full)) + + # Bypass check for directory existence to tickle error handling that + # occurs in response to a race. + fileutil.EnsureDirectoryExists(full, always_try_to_create=True) + self.assertTrue(os.path.exists(full)) + finally: + shutil.rmtree(temp_dir)
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/data_unittest.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/data_unittest.py index 9ad63c1..90c90e37 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/data_unittest.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/data_unittest.py
@@ -32,7 +32,6 @@ module = mojom.Module('test_module', 'test_namespace') struct_data = { 'name': 'SomeStruct', - 'attributes': [], 'enums': [], 'constants': [], 'fields': [ @@ -41,9 +40,6 @@ {'name': 'field3', 'kind': 'i32', 'default': 15}]} struct = data.StructFromData(module, struct_data) - del struct_data['attributes'] - del struct_data['enums'] - del struct_data['constants'] struct.fields = map(lambda field: data.FieldFromData(module, field, struct), struct.fields_data) self.assertEquals(struct_data, data.StructToData(struct))
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/pack_unittest.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/pack_unittest.py new file mode 100644 index 0000000..329e242 --- /dev/null +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/generate/pack_unittest.py
@@ -0,0 +1,54 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import imp +import os.path +import sys +import unittest + + +def _GetDirAbove(dirname): + """Returns the directory "above" this file containing |dirname| (which must + also be "above" this file).""" + path = os.path.abspath(__file__) + while True: + path, tail = os.path.split(path) + assert tail + if tail == dirname: + return path + + +try: + imp.find_module("mojom") +except ImportError: + sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib")) +from mojom.generate import pack +from mojom.generate import module as mojom + + +# TODO(yzshen): Move tests in pack_tests.py here. +class PackTest(unittest.TestCase): + + def testMinVersion(self): + """Tests that |min_version| is properly set for packed fields.""" + struct = mojom.Struct('test') + struct.AddField('field_2', mojom.BOOL, 2) + struct.AddField('field_0', mojom.INT32, 0) + struct.AddField('field_1', mojom.INT64, 1) + ps = pack.PackedStruct(struct) + + self.assertEquals("field_0", ps.packed_fields[0].field.name) + self.assertEquals("field_2", ps.packed_fields[1].field.name) + self.assertEquals("field_1", ps.packed_fields[2].field.name) + + self.assertEquals(1, ps.packed_fields[0].min_version) + self.assertEquals(3, ps.packed_fields[1].min_version) + self.assertEquals(2, ps.packed_fields[2].min_version) + + struct.fields[0].attributes = {'MinVersion': 1} + ps = pack.PackedStruct(struct) + + self.assertEquals(0, ps.packed_fields[0].min_version) + self.assertEquals(1, ps.packed_fields[1].min_version) + self.assertEquals(0, ps.packed_fields[2].min_version)
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/parse/translate_unittest.py b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/parse/translate_unittest.py index 20704dc..29dd906 100644 --- a/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/parse/translate_unittest.py +++ b/third_party/mojo/src/mojo/public/tools/bindings/pylib/mojom_tests/parse/translate_unittest.py
@@ -54,11 +54,10 @@ ast.UnionField("b", None, None, "string")]))]) expected = [{ "name": "SomeUnion", - "fields": [ - {"kind": "i32", "name": "a", "ordinal": None}, - {"kind": "s", "name": "b", "ordinal": None}]}] + "fields": [{"kind": "i32", "name": "a"}, + {"kind": "s", "name": "b"}]}] actual = translate.Translate(tree, "mojom_tree") - self.assertEquals(actual["union"], expected) + self.assertEquals(actual["unions"], expected) if __name__ == "__main__":
diff --git a/third_party/mojo_services/src/geometry/public/cpp/DEPS b/third_party/mojo_services/src/geometry/public/cpp/DEPS deleted file mode 100644 index b4134703..0000000 --- a/third_party/mojo_services/src/geometry/public/cpp/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+geometry/public/interfaces", -]
diff --git a/third_party/mojo_services/src/gpu/public/interfaces/command_buffer.mojom b/third_party/mojo_services/src/gpu/public/interfaces/command_buffer.mojom index a31b3dd..aa2c5567 100644 --- a/third_party/mojo_services/src/gpu/public/interfaces/command_buffer.mojom +++ b/third_party/mojo_services/src/gpu/public/interfaces/command_buffer.mojom
@@ -25,10 +25,19 @@ DidInsertSyncPoint(uint32 sync_point); }; -[Client=CommandBufferClient] +interface CommandBufferLostContextObserver { + DidLoseContext(int32 context_lost_reason); +}; + interface CommandBuffer { + // Initialize attempts to initialize the command buffer. Success or failure + // will be communicated via the CommandBufferSyncClient DidInitialize() call. + // If the context is lost after creation the LostContext method on the + // CommandBufferLostContextObserver's will be called then this pipe will be + // closed. Initialize(CommandBufferSyncClient sync_client, CommandBufferSyncPointClient sync_point_client, + CommandBufferLostContextObserver lost_observer, handle<shared_buffer> shared_state); SetGetBuffer(int32 buffer); Flush(int32 put_offset); @@ -43,11 +52,4 @@ InsertSyncPoint(bool retire); RetireSyncPoint(uint32 sync_point); Echo() => (); - - // TODO(piman): sync points -}; - -interface CommandBufferClient { - DidDestroy(); - LostContext(int32 lost_reason); // TODO(piman): enum };
diff --git a/third_party/mojo_services/src/native_viewport/public/cpp/DEPS b/third_party/mojo_services/src/native_viewport/public/cpp/DEPS deleted file mode 100644 index 8fc8a7f..0000000 --- a/third_party/mojo_services/src/native_viewport/public/cpp/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+native_viewport/public", -]
diff --git a/third_party/mojo_services/src/public/js/application.js b/third_party/mojo_services/src/public/js/application.js index d4aa1e6..aea60fd 100644 --- a/third_party/mojo_services/src/public/js/application.js +++ b/third_party/mojo_services/src/public/js/application.js
@@ -8,20 +8,19 @@ "mojo/public/js/connection", "mojo/public/js/threading", "mojo/public/interfaces/application/application.mojom", - "mojo/services/public/js/service_provider", + "mojo/services/public/js/service_exchange", "mojo/services/public/js/shell", -], function(bindings, core, connection, threading, applicationMojom, serviceProvider, shell) { +], function(bindings, core, connection, threading, applicationMojom, serviceExchange, shell) { const ApplicationInterface = applicationMojom.Application; const ProxyBindings = bindings.ProxyBindings; - const ServiceProvider = serviceProvider.ServiceProvider; + const ServiceExchange = serviceExchange.ServiceExchange; const Shell = shell.Shell; class Application { constructor(appRequestHandle, url) { this.url = url; - this.serviceProviders = []; - this.exposedServiceProviders = []; + this.serviceExchanges = []; this.appRequestHandle_ = appRequestHandle; this.appStub_ = connection.bindHandleToStub(appRequestHandle, ApplicationInterface); @@ -37,30 +36,27 @@ this.initialize(args); } - initialize(args) {} - - // The mojom signature of this function is: - // AcceptConnection(string requestor_url, - // ServiceProvider&? services, - // ServiceProvider? exposed_services); - // - // We want to bind |services| to our js implementation of ServiceProvider - // and store |exposed_services| so we can request services of the connecting - // application. - doAcceptConnection(requestorUrl, servicesRequest, exposedServicesProxy) { - // Construct a new js ServiceProvider that can make outgoing calls on - // exposedServicesProxy. - var serviceProvider = - new ServiceProvider(servicesRequest, exposedServicesProxy); - this.serviceProviders.push(serviceProvider); - this.acceptConnection(requestorUrl, serviceProvider); + initialize(args) { } - acceptConnection(requestorUrl, serviceProvider) {} + // Implements AcceptConnection() from Application.mojom. Calls + // this.acceptConnection() with a JS ServiceExchange instead of a pair + // of Mojo ServiceProviders. + doAcceptConnection(requestorUrl, servicesRequest, exposedServicesProxy) { + var serviceExchange = + new ServiceExchange(servicesRequest, exposedServicesProxy); + this.serviceExchanges.push(serviceExchange); + this.acceptConnection(requestorUrl, serviceExchange); + } + + // Subclasses override this method to request or provide services for + // ConnectToApplication() calls from requestorURL. + acceptConnection(requestorUrl, serviceExchange) { + } quit() { - this.serviceProviders.forEach(function(sp) { - sp.close(); + this.serviceExchanges.forEach(function(exch) { + exch.close(); }); this.shell.close(); core.close(this.appRequestHandle_);
diff --git a/third_party/mojo_services/src/public/js/service_provider.js b/third_party/mojo_services/src/public/js/service_exchange.js similarity index 90% rename from third_party/mojo_services/src/public/js/service_provider.js rename to third_party/mojo_services/src/public/js/service_exchange.js index a6a81ca..a424c12 100644 --- a/third_party/mojo_services/src/public/js/service_provider.js +++ b/third_party/mojo_services/src/public/js/service_exchange.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -define("mojo/services/public/js/service_provider", [ +define("mojo/services/public/js/service_exchange", [ "mojo/public/js/bindings", "mojo/public/interfaces/application/service_provider.mojom", "mojo/public/js/connection", @@ -12,12 +12,12 @@ const StubBindings = bindings.StubBindings; const ServiceProviderInterface = spMojom.ServiceProvider; - function checkServiceProvider(sp) { - if (!sp.providers_) + function checkServiceExchange(exch) { + if (!exch.providers_) throw new Error("Service was closed"); } - class ServiceProvider { + class ServiceExchange { constructor(servicesRequest, exposedServicesProxy) { this.proxy = exposedServicesProxy; this.providers_ = new Map(); // serviceName => see provideService() below @@ -43,7 +43,7 @@ } provideService(service, factory) { - checkServiceProvider(this); + checkServiceExchange(this); var provider = { service: service, // A JS bindings interface object. @@ -61,7 +61,7 @@ // Outgoing requests requestService(interfaceObject, clientImpl) { - checkServiceProvider(this); + checkServiceExchange(this); if (!interfaceObject.name) throw new Error("Invalid service parameter"); if (!clientImpl && interfaceObject.client) @@ -81,6 +81,6 @@ } var exports = {}; - exports.ServiceProvider = ServiceProvider; + exports.ServiceExchange = ServiceExchange; return exports; });
diff --git a/third_party/mojo_services/src/public/js/shell.js b/third_party/mojo_services/src/public/js/shell.js index e6c2dee..90b3533 100644 --- a/third_party/mojo_services/src/public/js/shell.js +++ b/third_party/mojo_services/src/public/js/shell.js
@@ -8,12 +8,12 @@ "mojo/public/js/connection", "mojo/public/interfaces/application/shell.mojom", "mojo/public/interfaces/application/service_provider.mojom", - "mojo/services/public/js/service_provider","console", -], function(bindings, core, connection, shellMojom, spMojom, sp, console) { + "mojo/services/public/js/service_exchange", +], function(bindings, core, connection, shellMojom, spMojom, serviceExchange) { const ProxyBindings = bindings.ProxyBindings; const StubBindings = bindings.StubBindings; - const ServiceProvider = sp.ServiceProvider; + const ServiceExchange = serviceExchange.ServiceExchange; const ServiceProviderInterface = spMojom.ServiceProvider; const ShellInterface = shellMojom.Shell; @@ -28,7 +28,7 @@ if (application) return application; - var application = new ServiceProvider(); + var application = new ServiceExchange(); this.shellProxy.connectToApplication(url, function(services) { application.proxy = services;
diff --git a/third_party/mojo_services/src/public/sky/BUILD.gn b/third_party/mojo_services/src/public/sky/BUILD.gn index 4776aa39..2c5c63cc 100644 --- a/third_party/mojo_services/src/public/sky/BUILD.gn +++ b/third_party/mojo_services/src/public/sky/BUILD.gn
@@ -6,7 +6,7 @@ script = "../../../public/sky/convert_amd_modules_to_sky.py" sources = [ "../js/application.js", - "../js/service_provider.js", + "../js/service_exchange.js", "../js/shell.js", ] outputs = [
diff --git a/third_party/mojo_services/src/surfaces/public/cpp/DEPS b/third_party/mojo_services/src/surfaces/public/cpp/DEPS deleted file mode 100644 index bc9750c1..0000000 --- a/third_party/mojo_services/src/surfaces/public/cpp/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+geometry/public/interfaces", - "+surfaces/public", -]
diff --git a/third_party/mojo_services/src/surfaces/public/interfaces/BUILD.gn b/third_party/mojo_services/src/surfaces/public/interfaces/BUILD.gn index 76f51724..aaab024 100644 --- a/third_party/mojo_services/src/surfaces/public/interfaces/BUILD.gn +++ b/third_party/mojo_services/src/surfaces/public/interfaces/BUILD.gn
@@ -9,7 +9,6 @@ sources = [ "quads.mojom", "surfaces.mojom", - "surfaces_service.mojom", ] import_dirs = [ get_path_info("../../../", "abspath") ]
diff --git a/third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom b/third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom index 7badcd34..71aed7e 100644 --- a/third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom +++ b/third_party/mojo_services/src/surfaces/public/interfaces/surfaces.mojom
@@ -52,21 +52,28 @@ array<Pass> passes; }; -interface SurfaceClient { - // This sets the id namespace for this connection. This method will be invoked - // exactly once when a new connection is established. - SetIdNamespace(uint32 id_namespace); +interface ResourceReturner { ReturnResources(array<ReturnedResource> resources); }; -[Client=SurfaceClient] interface Surface { + // Request the id namespace for this connection. Fully qualified surface ids + // are the combination of the id_namespace for the connection that created the + // surface and the id_local component allocated by the caller. + GetIdNamespace() => (uint32 id_namespace); + + // Sets a ResourceReturner that will receive unused resources. + SetResourceReturner(ResourceReturner returner); + + // Creates a new surface with the given local identifier. Once a surface is + // created the caller may submit frames to it or destroy it using the local + // identifier. The caller can also produce a fully qualified surface id that + // can be embedded in frames produces by different connections. CreateSurface(uint32 id_local); - // The client can only submit frames to surfaces created with this - // connection. After the submitted frame is drawn for the first time, the - // surface will respond to the SubmitFrame message. Clients should use this - // acknowledgement to ratelimit frame submissions. + // After the submitted frame is drawn for the first time, the surface will + // respond to the SubmitFrame message. Clients should use this acknowledgement + // to ratelimit frame submissions. SubmitFrame(uint32 id_local, Frame frame) => (); DestroySurface(uint32 id_local);
diff --git a/third_party/mojo_services/src/surfaces/public/interfaces/surfaces_service.mojom b/third_party/mojo_services/src/surfaces/public/interfaces/surfaces_service.mojom deleted file mode 100644 index e1ca6902..0000000 --- a/third_party/mojo_services/src/surfaces/public/interfaces/surfaces_service.mojom +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module mojo; - -import "surfaces/public/interfaces/surfaces.mojom"; - -// Use this interface to request connections to the surfaces service. Each -// connection is associated with an id namespace -interface SurfacesService { - // DEPRECATED: Just connect to mojo.Surface directly and receive the id - // namespace via SetIdNamespace. - CreateSurfaceConnection() => (Surface surface, uint32 id_namespace); -};
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/DEPS b/third_party/mojo_services/src/view_manager/public/cpp/DEPS deleted file mode 100644 index c08c2c8..0000000 --- a/third_party/mojo_services/src/view_manager/public/cpp/DEPS +++ /dev/null
@@ -1,14 +0,0 @@ -include_rules = [ - "+geometry/public", - "+input_events/public", - "+surfaces/public", - "+view_manager/public", - "+window_manager/public", - - # TODO(blundell): Eliminate these dependencies. crbug.com/451403 - "!base/basictypes.h", - "!base/bind.h", - "!base/compiler_specific.h", - "!base/memory/scoped_ptr.h", - "!base/observer_list.h", -]
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/lib/DEPS b/third_party/mojo_services/src/view_manager/public/cpp/lib/DEPS deleted file mode 100644 index f36ebc7..0000000 --- a/third_party/mojo_services/src/view_manager/public/cpp/lib/DEPS +++ /dev/null
@@ -1,10 +0,0 @@ -include_rules = [ - "+mojo/services/window_manager/public", - - # TODO(blundell): Eliminate these dependencies. crbug.com/451403 - "!base/callback.h", - "!base/memory/scoped_vector.h", - "!base/memory/weak_ptr.h", - "!base/message_loop/message_loop.h", - "!base/stl_util.h", -]
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/lib/view.cc b/third_party/mojo_services/src/view_manager/public/cpp/lib/view.cc index d347292..ba3b61c 100644 --- a/third_party/mojo_services/src/view_manager/public/cpp/lib/view.cc +++ b/third_party/mojo_services/src/view_manager/public/cpp/lib/view.cc
@@ -389,7 +389,8 @@ metrics->size = Size::New(); return metrics.Pass(); } -} + +} // namespace View::View() : manager_(NULL),
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.cc b/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.cc index 595e0396..eea760b 100644 --- a/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.cc +++ b/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.cc
@@ -105,6 +105,7 @@ capture_view_(nullptr), focused_view_(nullptr), activated_view_(nullptr), + wm_observer_binding_(this), binding_(this, handle.Pass()), service_(binding_.client()), delete_on_error_(delete_on_error) { @@ -272,10 +273,12 @@ root_->AddObserver(new RootObserver(root_)); window_manager_.Bind(window_manager_pipe.Pass()); - window_manager_.set_client(this); // base::Unretained() is safe here as |window_manager_| is bound to our // lifetime. + WindowManagerObserverPtr observer; + wm_observer_binding_.Bind(GetProxy(&observer)); window_manager_->GetFocusedAndActiveViews( + observer.Pass(), base::Bind(&ViewManagerClientImpl::OnGotFocusedAndActiveViews, base::Unretained(this))); @@ -397,12 +400,11 @@ } //////////////////////////////////////////////////////////////////////////////// -// ViewManagerClientImpl, WindowManagerClient implementation: +// ViewManagerClientImpl, WindowManagerObserver implementation: -void ViewManagerClientImpl::OnCaptureChanged(Id old_capture_view_id, - Id new_capture_view_id) { - View* gained_capture = GetViewById(new_capture_view_id); - View* lost_capture = GetViewById(old_capture_view_id); +void ViewManagerClientImpl::OnCaptureChanged(Id capture_view_id) { + View* gained_capture = GetViewById(capture_view_id); + View* lost_capture = capture_view_; if (lost_capture) { FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(lost_capture).observers(), @@ -416,10 +418,9 @@ } } -void ViewManagerClientImpl::OnFocusChanged(Id old_focused_view_id, - Id new_focused_view_id) { - View* focused = GetViewById(new_focused_view_id); - View* blurred = GetViewById(old_focused_view_id); +void ViewManagerClientImpl::OnFocusChanged(Id focused_view_id) { + View* focused = GetViewById(focused_view_id); + View* blurred = focused_view_; if (blurred) { FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(blurred).observers(), @@ -433,10 +434,9 @@ } } -void ViewManagerClientImpl::OnActiveWindowChanged(Id old_active_view_id, - Id new_active_view_id) { - View* activated = GetViewById(new_active_view_id); - View* deactivated = GetViewById(old_active_view_id); +void ViewManagerClientImpl::OnActiveWindowChanged(Id active_view_id) { + View* activated = GetViewById(active_view_id); + View* deactivated = activated_view_; if (deactivated) { FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(deactivated).observers(), @@ -485,14 +485,16 @@ base::Unretained(this)); } -void ViewManagerClientImpl::OnGotFocusedAndActiveViews(uint32 focused_view_id, - uint32 active_view_id) { +void ViewManagerClientImpl::OnGotFocusedAndActiveViews( + uint32_t capture_view_id, + uint32_t focused_view_id, + uint32_t active_view_id) { + if (GetViewById(capture_view_id) != capture_view_) + OnCaptureChanged(capture_view_id); if (GetViewById(focused_view_id) != focused_view_) - OnFocusChanged(focused_view_ ? focused_view_->id() : 0, focused_view_id); - if (GetViewById(active_view_id) != activated_view_) { - OnActiveWindowChanged(activated_view_ ? activated_view_->id() : 0, - active_view_id); - } + OnFocusChanged(focused_view_id); + if (GetViewById(active_view_id) != activated_view_) + OnActiveWindowChanged(active_view_id); } } // namespace mojo
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.h b/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.h index 2405229..e0d7bba 100644 --- a/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.h +++ b/third_party/mojo_services/src/view_manager/public/cpp/lib/view_manager_client_impl.h
@@ -5,7 +5,6 @@ #ifndef MOJO_SERVICES_VIEW_MANAGER_PUBLIC_CPP_LIB_VIEW_MANAGER_CLIENT_IMPL_H_ #define MOJO_SERVICES_VIEW_MANAGER_PUBLIC_CPP_LIB_VIEW_MANAGER_CLIENT_IMPL_H_ -#include "base/basictypes.h" #include "base/callback.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" @@ -25,7 +24,7 @@ // Manages the connection with the View Manager service. class ViewManagerClientImpl : public ViewManager, public ViewManagerClient, - public WindowManagerClient, + public WindowManagerObserver, public ErrorHandler { public: ViewManagerClientImpl(ViewManagerDelegate* delegate, @@ -122,12 +121,10 @@ EventPtr event, const Callback<void()>& callback) override; - // Overridden from WindowManagerClient: - void OnCaptureChanged(Id old_capture_view_id, - Id new_capture_view_id) override; - void OnFocusChanged(Id old_focused_view_id, Id new_focused_view_id) override; - void OnActiveWindowChanged(Id old_focused_view_id, - Id new_focused_view_id) override; + // Overridden from WindowManagerObserver: + void OnCaptureChanged(Id capture_view_id) override; + void OnFocusChanged(Id focused_view_id) override; + void OnActiveWindowChanged(Id focused_view_id) override; // ErrorHandler implementation. void OnConnectionError() override; @@ -140,9 +137,10 @@ base::Callback<void(bool)> ActionCompletedCallback(); base::Callback<void(ErrorCode)> ActionCompletedCallbackWithErrorCode(); - // Callback from server for initial request of focused/active views. - void OnGotFocusedAndActiveViews(uint32 focused_view_id, - uint32 active_view_id); + // Callback from server for initial request of capture/focused/active views. + void OnGotFocusedAndActiveViews(uint32_t capture_view_id, + uint32_t focused_view_id, + uint32_t active_view_id); bool connected_; ConnectionSpecificId connection_id_; @@ -163,6 +161,7 @@ View* activated_view_; WindowManagerPtr window_manager_; + Binding<WindowManagerObserver> wm_observer_binding_; Binding<ViewManagerClient> binding_; ViewManagerService* service_;
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/tests/BUILD.gn b/third_party/mojo_services/src/view_manager/public/cpp/tests/BUILD.gn index e9120847..3414d33a 100644 --- a/third_party/mojo_services/src/view_manager/public/cpp/tests/BUILD.gn +++ b/third_party/mojo_services/src/view_manager/public/cpp/tests/BUILD.gn
@@ -7,10 +7,10 @@ test("mojo_view_manager_lib_unittests") { sources = [ + "run_all_unittests.cc", "view_manager_test_suite.cc", "view_manager_test_suite.h", "view_manager_unittest.cc", - "view_manager_unittests.cc", "view_unittest.cc", ]
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/tests/DEPS b/third_party/mojo_services/src/view_manager/public/cpp/tests/DEPS deleted file mode 100644 index 0f9ddb4..0000000 --- a/third_party/mojo_services/src/view_manager/public/cpp/tests/DEPS +++ /dev/null
@@ -1,16 +0,0 @@ -include_rules = [ - "+mojo/services/geometry/public", - - # TODO(blundell): Determine whether to eliminate these dependencies or move - # the tests outside of view_manager's public code. crbug.com/451403 - "!base/auto_reset.h", - "!base/bind.h", - "!base/i18n/icu_util.h", - "!base/logging.h", - "!base/strings/stringprintf.h", - "!base/test/launcher/unit_test_launcher.h", - "!base/test/test_suite.h", - "!shell/application_manager", - "!shell/shell_test_helper.h", - "!ui/gfx/x/x11_connection.h", -]
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/tests/view_manager_unittests.cc b/third_party/mojo_services/src/view_manager/public/cpp/tests/run_all_unittests.cc similarity index 100% rename from third_party/mojo_services/src/view_manager/public/cpp/tests/view_manager_unittests.cc rename to third_party/mojo_services/src/view_manager/public/cpp/tests/run_all_unittests.cc
diff --git a/third_party/mojo_services/src/view_manager/public/cpp/view_observer.h b/third_party/mojo_services/src/view_manager/public/cpp/view_observer.h index 7430566e..f059e113 100644 --- a/third_party/mojo_services/src/view_manager/public/cpp/view_observer.h +++ b/third_party/mojo_services/src/view_manager/public/cpp/view_observer.h
@@ -61,7 +61,7 @@ const ViewportMetrics& new_bounds) { } - virtual void OnCaptureChanged(View* gained_capture, View* lost_capture) {} + virtual void OnViewCaptureChanged(View* gained_capture, View* lost_capture) {} virtual void OnViewFocusChanged(View* gained_focus, View* lost_focus) {} virtual void OnViewActivationChanged(View* gained_active, View* lost_active) { }
diff --git a/third_party/mojo_services/src/window_manager/public/interfaces/window_manager.mojom b/third_party/mojo_services/src/window_manager/public/interfaces/window_manager.mojom index e365fb6..ee1b02e 100644 --- a/third_party/mojo_services/src/window_manager/public/interfaces/window_manager.mojom +++ b/third_party/mojo_services/src/window_manager/public/interfaces/window_manager.mojom
@@ -7,22 +7,30 @@ import "input_events/public/interfaces/input_events.mojom"; import "mojo/public/interfaces/application/service_provider.mojom"; -[Client=WindowManagerClient] interface WindowManager { // Requests the WindowManager to embed the app for |url| at an appropriate // View. See ViewMangerService::Embed() for details on |services| and // |exposed_services|. - Embed(string url, ServiceProvider&? services, ServiceProvider? exposed_services); + Embed(string url, + ServiceProvider&? services, + ServiceProvider? exposed_services); SetCapture(uint32 view_id) => (bool success); FocusWindow(uint32 view_id) => (bool success); ActivateWindow(uint32 view_id) => (bool success); - GetFocusedAndActiveViews() => (uint32 focused_view_id, uint32 active_view_id); + // Requests the current focus and activation state and an interface to observe + // future changes. + // If |observer| is not null capture, focus and activation updates will be + // sent to it. + GetFocusedAndActiveViews(WindowManagerObserver? observer) + => (uint32 capture_view_id, + uint32 focused_view_id, + uint32 active_view_id); }; -interface WindowManagerClient { - OnCaptureChanged(uint32 old_capture_view_id, uint32 new_capture_view_id); - OnFocusChanged(uint32 old_focused_view_id, uint32 new_focused_view_id); - OnActiveWindowChanged(uint32 old_focused_view_id, uint32 new_focused_view_id); +interface WindowManagerObserver { + OnCaptureChanged(uint32 capture_view_id); + OnFocusChanged(uint32 focused_view_id); + OnActiveWindowChanged(uint32 focused_view_id); };
diff --git a/third_party/polymer/README.chromium b/third_party/polymer/README.chromium index d9e89a9..70422b1a 100644 --- a/third_party/polymer/README.chromium +++ b/third_party/polymer/README.chromium
@@ -1,7 +1,7 @@ Name: Polymer Short Name: polymer URL: http://www.polymer-project.org -Version: 0.5.2 +Version: 0.5.2-4 Revision: (See components/<component>/.bower.json) License: BSD License File: LICENSE.polymer
diff --git a/third_party/polymer/bower.json b/third_party/polymer/bower.json index 65a1f33..16d9743a 100644 --- a/third_party/polymer/bower.json +++ b/third_party/polymer/bower.json
@@ -63,6 +63,6 @@ "paper-spinner": "Polymer/paper-spinner#0.5.2", "paper-tabs": "Polymer/paper-tabs#0.5.2", "paper-toast": "Polymer/paper-toast#0.5.2", - "paper-toggle-button": "Polymer/paper-toggle-button#0.5.2" + "paper-toggle-button": "Polymer/paper-toggle-button#0.5.4" } }
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/.bower.json b/third_party/polymer/components-chromium/paper-toggle-button/.bower.json index d56df55..5561f5e0a 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/.bower.json +++ b/third_party/polymer/components-chromium/paper-toggle-button/.bower.json
@@ -2,18 +2,18 @@ "name": "paper-toggle-button", "private": true, "dependencies": { - "font-roboto": "Polymer/font-roboto#^0.5.0", - "paper-radio-button": "Polymer/paper-radio-button#^0.5.0" + "font-roboto": "Polymer/font-roboto#^0.5", + "paper-radio-button": "Polymer/paper-radio-button#^0.5" }, - "version": "0.5.2", + "version": "0.5.4", "homepage": "https://github.com/Polymer/paper-toggle-button", - "_release": "0.5.2", + "_release": "0.5.4", "_resolution": { "type": "version", - "tag": "0.5.2", - "commit": "3fd4732c10180252a54d0199a4c15fafd220523a" + "tag": "0.5.4", + "commit": "b4cc158803ac87b1571f8c07c0d862ec89b10786" }, "_source": "git://github.com/Polymer/paper-toggle-button.git", - "_target": "0.5.2", + "_target": "0.5.4", "_originalSource": "Polymer/paper-toggle-button" } \ No newline at end of file
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/bower.json b/third_party/polymer/components-chromium/paper-toggle-button/bower.json index 11c9322..8c30db1 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/bower.json +++ b/third_party/polymer/components-chromium/paper-toggle-button/bower.json
@@ -2,8 +2,8 @@ "name": "paper-toggle-button", "private": true, "dependencies": { - "font-roboto": "Polymer/font-roboto#^0.5.0", - "paper-radio-button": "Polymer/paper-radio-button#^0.5.0" + "font-roboto": "Polymer/font-roboto#^0.5", + "paper-radio-button": "Polymer/paper-radio-button#^0.5" }, - "version": "0.5.2" + "version": "0.5.4" } \ No newline at end of file
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/demo.html b/third_party/polymer/components-chromium/paper-toggle-button/demo.html index 960ac569..370280bd 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/demo.html +++ b/third_party/polymer/components-chromium/paper-toggle-button/demo.html
@@ -27,10 +27,6 @@ font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial; margin: 0; padding: 24px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-touch-callout: none; } @@ -38,17 +34,25 @@ section { width: 200px; } - - paper-toggle-button.blue::shadow paper-radio-button::shadow #ink[checked] { + + paper-toggle-button.bluetooth::shadow [checked] .toggle-ink { color: #4285f4; } - - paper-toggle-button.blue::shadow paper-radio-button::shadow #onRadio { + + paper-toggle-button.bluetooth::shadow [checked] .toggle { background-color: #4285f4; } - paper-toggle-button.blue::shadow #toggleBar[checked] { - background-color: #4285f4; + paper-toggle-button.fun::shadow .toggle-ink { + color: #009688; + } + + paper-toggle-button.fun::shadow .toggle-bar { + background-color: #5677fc; + } + + paper-toggle-button.fun::shadow .toggle-button { + background-color: #9c27b0; } </style> @@ -68,7 +72,23 @@ <div center horizontal layout> <div flex>Bluetooth</div> - <paper-toggle-button class="blue"></paper-toggle-button> + <paper-toggle-button class="bluetooth"></paper-toggle-button> + </div> + + <br> + <br> + + <div center horizontal layout> + <div flex>Custom Colors</div> + <paper-toggle-button class="fun"></paper-toggle-button> + </div> + + <br> + <br> + + <div center horizontal layout> + <div flex>Disabled</div> + <paper-toggle-button disabled></paper-toggle-button> </div> </section>
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js index 7b006be..72d672e 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js +++ b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js
@@ -22,7 +22,7 @@ * @default false */ checked: false, - + /** * If true, the toggle button is disabled. A disabled toggle button cannot * be tapped or dragged to change the checked state. @@ -33,23 +33,55 @@ */ disabled: false, + eventDelegates: { + down: 'downAction', + up: 'upAction', + tap: 'tap', + trackstart: 'trackStart', + trackx: 'trackx', + trackend: 'trackEnd' + }, + + downAction: function(e) { + var rect = this.$.ink.getBoundingClientRect(); + this.$.ink.downAction({ + x: rect.left + rect.width / 2, + y: rect.top + rect.height / 2 + }); + }, + + upAction: function(e) { + this.$.ink.upAction(); + }, + + tap: function() { + if (this.disabled) { + return; + } + this.checked = !this.checked; + this.fire('change'); + }, + trackStart: function(e) { - this._w = this.$.toggleBar.offsetLeft + this.$.toggleBar.offsetWidth; + if (this.disabled) { + return; + } + this._w = this.$.toggleBar.offsetWidth / 2; e.preventTap(); }, trackx: function(e) { this._x = Math.min(this._w, Math.max(0, this.checked ? this._w + e.dx : e.dx)); - this.$.toggleRadio.classList.add('dragging'); - var s = this.$.toggleRadio.style; + this.$.toggleButton.classList.add('dragging'); + var s = this.$.toggleButton.style; s.webkitTransform = s.transform = 'translate3d(' + this._x + 'px,0,0)'; }, trackEnd: function() { - var s = this.$.toggleRadio.style; + var s = this.$.toggleButton.style; s.transform = s.webkitTransform = ''; - this.$.toggleRadio.classList.remove('dragging'); + this.$.toggleButton.classList.remove('dragging'); var old = this.checked; this.checked = Math.abs(this._x) > this._w / 2; if (this.checked !== old) { @@ -60,15 +92,6 @@ checkedChanged: function() { this.setAttribute('aria-pressed', Boolean(this.checked)); this.fire('core-change'); - }, - - changeAction: function(e) { - e.stopPropagation(); - this.fire('change'); - }, - - stopPropagation: function(e) { - e.stopPropagation(); } });
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.css b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.css index 67e8930..5ffe045 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.css +++ b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.css
@@ -15,53 +15,81 @@ outline: none; } +/* Class selectors can be overridden by users. */ + +.toggle-bar { + background-color: #000000; +} + +.toggle-button { + background-color: #f1f1f1; +} + +[checked] .toggle { + background-color: #0f9d58; +} + +.toggle-ink { + color: #bbb; +} + +[checked] .toggle-ink { + color: #0f9d58; +} + +/* ID selectors should not be overriden by users. */ + #toggleContainer { position: relative; - width: 64px; - height: 16px; + width: 36px; + height: 14px; +} + +#toggleContainer[disabled] { + opacity: 0.3; + pointer-events: none; } #toggleBar { position: absolute; - top: 8px; - left: 16px; - height: 1px; - width: 32px; - background-color: #5a5a5a; - pointer-events: none; -} - -#toggleBar[checked] { - background-color: #0f9d58; -} - -#toggleContainer[checked] #checkedBar { + height: 100%; width: 100%; + border-radius: 8px; + pointer-events: none; + opacity: 0.26; + transition: background-color linear .08s; } -#toggleRadio { +[checked] #toggleBar { + opacity: 0.5; +} + +#toggleButton { position: absolute; - left: 0; - padding: 8px 48px 8px 0; - margin: -8px -48px -8px 0; - transition: -webkit-transform linear .08s; - transition: transform linear .08s; + top: -3px; + height: 20px; + width: 20px; + border-radius: 50%; + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.4); + transition: -webkit-transform linear .08s, background-color linear .08s; + transition: transform linear .08s, background-color linear .08s; } -#toggleRadio[checked] { - -webkit-transform: translate(48px, 0); - transform: translate(48px, 0); - padding: 8px 0 8px 48px; - margin: -8px 0 -8px -48px; -} - -#toggleRadio.dragging { +#toggleButton.dragging { -webkit-transition: none; transition: none; } -/* disabled state */ -#toggleContainer[disabled] { - opacity: 0.3; +[checked] #toggleButton { + -webkit-transform: translate(16px, 0); + transform: translate(16px, 0); +} + +#ink { + position: absolute; + top: -14px; + left: -14px; + width: 48px; + height: 48px; pointer-events: none; }
diff --git a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.html b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.html index a6323ee1..81407249 100644 --- a/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.html +++ b/third_party/polymer/components-chromium/paper-toggle-button/paper-toggle-button.html
@@ -15,61 +15,64 @@ Styling toggle button: -To change the ink color for checked state: +To change the toggle color: - paper-toggle-button::shadow paper-radio-button::shadow #ink[checked] { + paper-toggle-button::shadow .toggle { + background-color: #9c27b0; + } + +To change the ink color: + + paper-toggle-button::shadow .toggle-ink { + color: #009688; + } + +To change the checked toggle color: + + paper-toggle-button::shadow [checked] .toggle { + background-color: #4285f4; + } + +To change the checked ink color: + + paper-toggle-button::shadow [checked] .toggle-ink { color: #4285f4; } - -To change the radio checked color: - - paper-toggle-button::shadow paper-radio-button::shadow #onRadio { - background-color: #4285f4; - } - -To change the bar color for checked state: - paper-toggle-button::shadow #toggleBar[checked] { - background-color: #4285f4; - } - -To change the ink color for unchecked state: +To change the toggle bar and toggle button colors separately: - paper-toggle-button::shadow paper-radio-button::shadow #ink { - color: #b5b5b5; - } - -To change the radio unchecked color: - - paper-toggle-button::shadow paper-radio-button::shadow #offRadio { - border-color: #b5b5b5; + paper-toggle-button::shadow .toggle-bar { + background-color: #5677fc; } -To change the bar color for unchecked state: - - paper-toggle-button::shadow #toggleBar { - background-color: red; + paper-toggle-button::shadow .toggle-button { + background-color: #9c27b0; } @group Paper Elements @element paper-toggle-button @homepage github.io --><html><head><link rel="import" href="../paper-radio-button/paper-radio-button.html"> +<link rel="import" href="../core-a11y-keys/core-a11y-keys.html"> </head><body><polymer-element name="paper-toggle-button" attributes="checked disabled" role="button" aria-pressed="false" tabindex="0" assetpath=""> <template> <link rel="stylesheet" href="paper-toggle-button.css"> - <div id="toggleContainer" disabled?="{{disabled}}"> + <core-a11y-keys target="{{}}" keys="space" on-keys-pressed="{{tap}}"></core-a11y-keys> + + <div id="toggleContainer" checked?="{{checked}}" disabled?="{{disabled}}"> - <div id="toggleBar" checked?="{{checked}}"></div> - - <paper-radio-button id="toggleRadio" toggles="" checked="{{checked}}" on-change="{{changeAction}}" on-core-change="{{stopPropagation}}" on-trackstart="{{trackStart}}" on-trackx="{{trackx}}" on-trackend="{{trackEnd}}"></paper-radio-button> - + <div id="toggleBar" class="toggle toggle-bar"></div> + + <div id="toggleButton" class="toggle toggle-button"> + <paper-ripple id="ink" class="toggle-ink circle"></paper-ripple> + </div> + </div> </template> </polymer-element> -<script src="paper-toggle-button-extracted.js"></script></body></html> \ No newline at end of file +<script charset="utf-8" src="paper-toggle-button-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/components/paper-toggle-button/.bower.json b/third_party/polymer/components/paper-toggle-button/.bower.json index d56df55..5561f5e0a 100644 --- a/third_party/polymer/components/paper-toggle-button/.bower.json +++ b/third_party/polymer/components/paper-toggle-button/.bower.json
@@ -2,18 +2,18 @@ "name": "paper-toggle-button", "private": true, "dependencies": { - "font-roboto": "Polymer/font-roboto#^0.5.0", - "paper-radio-button": "Polymer/paper-radio-button#^0.5.0" + "font-roboto": "Polymer/font-roboto#^0.5", + "paper-radio-button": "Polymer/paper-radio-button#^0.5" }, - "version": "0.5.2", + "version": "0.5.4", "homepage": "https://github.com/Polymer/paper-toggle-button", - "_release": "0.5.2", + "_release": "0.5.4", "_resolution": { "type": "version", - "tag": "0.5.2", - "commit": "3fd4732c10180252a54d0199a4c15fafd220523a" + "tag": "0.5.4", + "commit": "b4cc158803ac87b1571f8c07c0d862ec89b10786" }, "_source": "git://github.com/Polymer/paper-toggle-button.git", - "_target": "0.5.2", + "_target": "0.5.4", "_originalSource": "Polymer/paper-toggle-button" } \ No newline at end of file
diff --git a/third_party/polymer/components/paper-toggle-button/bower.json b/third_party/polymer/components/paper-toggle-button/bower.json index 11c9322..8c30db1 100644 --- a/third_party/polymer/components/paper-toggle-button/bower.json +++ b/third_party/polymer/components/paper-toggle-button/bower.json
@@ -2,8 +2,8 @@ "name": "paper-toggle-button", "private": true, "dependencies": { - "font-roboto": "Polymer/font-roboto#^0.5.0", - "paper-radio-button": "Polymer/paper-radio-button#^0.5.0" + "font-roboto": "Polymer/font-roboto#^0.5", + "paper-radio-button": "Polymer/paper-radio-button#^0.5" }, - "version": "0.5.2" + "version": "0.5.4" } \ No newline at end of file
diff --git a/third_party/polymer/components/paper-toggle-button/demo.html b/third_party/polymer/components/paper-toggle-button/demo.html index 960ac569..370280bd 100644 --- a/third_party/polymer/components/paper-toggle-button/demo.html +++ b/third_party/polymer/components/paper-toggle-button/demo.html
@@ -27,10 +27,6 @@ font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial; margin: 0; padding: 24px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-touch-callout: none; } @@ -38,17 +34,25 @@ section { width: 200px; } - - paper-toggle-button.blue::shadow paper-radio-button::shadow #ink[checked] { + + paper-toggle-button.bluetooth::shadow [checked] .toggle-ink { color: #4285f4; } - - paper-toggle-button.blue::shadow paper-radio-button::shadow #onRadio { + + paper-toggle-button.bluetooth::shadow [checked] .toggle { background-color: #4285f4; } - paper-toggle-button.blue::shadow #toggleBar[checked] { - background-color: #4285f4; + paper-toggle-button.fun::shadow .toggle-ink { + color: #009688; + } + + paper-toggle-button.fun::shadow .toggle-bar { + background-color: #5677fc; + } + + paper-toggle-button.fun::shadow .toggle-button { + background-color: #9c27b0; } </style> @@ -68,7 +72,23 @@ <div center horizontal layout> <div flex>Bluetooth</div> - <paper-toggle-button class="blue"></paper-toggle-button> + <paper-toggle-button class="bluetooth"></paper-toggle-button> + </div> + + <br> + <br> + + <div center horizontal layout> + <div flex>Custom Colors</div> + <paper-toggle-button class="fun"></paper-toggle-button> + </div> + + <br> + <br> + + <div center horizontal layout> + <div flex>Disabled</div> + <paper-toggle-button disabled></paper-toggle-button> </div> </section>
diff --git a/third_party/polymer/components/paper-toggle-button/paper-toggle-button.css b/third_party/polymer/components/paper-toggle-button/paper-toggle-button.css index 67e8930..5ffe045 100644 --- a/third_party/polymer/components/paper-toggle-button/paper-toggle-button.css +++ b/third_party/polymer/components/paper-toggle-button/paper-toggle-button.css
@@ -15,53 +15,81 @@ outline: none; } +/* Class selectors can be overridden by users. */ + +.toggle-bar { + background-color: #000000; +} + +.toggle-button { + background-color: #f1f1f1; +} + +[checked] .toggle { + background-color: #0f9d58; +} + +.toggle-ink { + color: #bbb; +} + +[checked] .toggle-ink { + color: #0f9d58; +} + +/* ID selectors should not be overriden by users. */ + #toggleContainer { position: relative; - width: 64px; - height: 16px; + width: 36px; + height: 14px; +} + +#toggleContainer[disabled] { + opacity: 0.3; + pointer-events: none; } #toggleBar { position: absolute; - top: 8px; - left: 16px; - height: 1px; - width: 32px; - background-color: #5a5a5a; - pointer-events: none; -} - -#toggleBar[checked] { - background-color: #0f9d58; -} - -#toggleContainer[checked] #checkedBar { + height: 100%; width: 100%; + border-radius: 8px; + pointer-events: none; + opacity: 0.26; + transition: background-color linear .08s; } -#toggleRadio { +[checked] #toggleBar { + opacity: 0.5; +} + +#toggleButton { position: absolute; - left: 0; - padding: 8px 48px 8px 0; - margin: -8px -48px -8px 0; - transition: -webkit-transform linear .08s; - transition: transform linear .08s; + top: -3px; + height: 20px; + width: 20px; + border-radius: 50%; + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.4); + transition: -webkit-transform linear .08s, background-color linear .08s; + transition: transform linear .08s, background-color linear .08s; } -#toggleRadio[checked] { - -webkit-transform: translate(48px, 0); - transform: translate(48px, 0); - padding: 8px 0 8px 48px; - margin: -8px 0 -8px -48px; -} - -#toggleRadio.dragging { +#toggleButton.dragging { -webkit-transition: none; transition: none; } -/* disabled state */ -#toggleContainer[disabled] { - opacity: 0.3; +[checked] #toggleButton { + -webkit-transform: translate(16px, 0); + transform: translate(16px, 0); +} + +#ink { + position: absolute; + top: -14px; + left: -14px; + width: 48px; + height: 48px; pointer-events: none; }
diff --git a/third_party/polymer/components/paper-toggle-button/paper-toggle-button.html b/third_party/polymer/components/paper-toggle-button/paper-toggle-button.html index d224bd02..a72e2a0 100644 --- a/third_party/polymer/components/paper-toggle-button/paper-toggle-button.html +++ b/third_party/polymer/components/paper-toggle-button/paper-toggle-button.html
@@ -17,40 +17,38 @@ Styling toggle button: -To change the ink color for checked state: +To change the toggle color: - paper-toggle-button::shadow paper-radio-button::shadow #ink[checked] { + paper-toggle-button::shadow .toggle { + background-color: #9c27b0; + } + +To change the ink color: + + paper-toggle-button::shadow .toggle-ink { + color: #009688; + } + +To change the checked toggle color: + + paper-toggle-button::shadow [checked] .toggle { + background-color: #4285f4; + } + +To change the checked ink color: + + paper-toggle-button::shadow [checked] .toggle-ink { color: #4285f4; } - -To change the radio checked color: - - paper-toggle-button::shadow paper-radio-button::shadow #onRadio { - background-color: #4285f4; - } - -To change the bar color for checked state: - paper-toggle-button::shadow #toggleBar[checked] { - background-color: #4285f4; - } - -To change the ink color for unchecked state: +To change the toggle bar and toggle button colors separately: - paper-toggle-button::shadow paper-radio-button::shadow #ink { - color: #b5b5b5; - } - -To change the radio unchecked color: - - paper-toggle-button::shadow paper-radio-button::shadow #offRadio { - border-color: #b5b5b5; + paper-toggle-button::shadow .toggle-bar { + background-color: #5677fc; } -To change the bar color for unchecked state: - - paper-toggle-button::shadow #toggleBar { - background-color: red; + paper-toggle-button::shadow .toggle-button { + background-color: #9c27b0; } @group Paper Elements @@ -59,19 +57,23 @@ --> <link rel="import" href="../paper-radio-button/paper-radio-button.html"> +<link rel="import" href="../core-a11y-keys/core-a11y-keys.html"> <polymer-element name="paper-toggle-button" attributes="checked disabled" role="button" aria-pressed="false" tabindex="0"> <template> <link rel="stylesheet" href="paper-toggle-button.css"> - <div id="toggleContainer" disabled?="{{disabled}}"> + <core-a11y-keys target="{{}}" keys="space" on-keys-pressed="{{tap}}"></core-a11y-keys> + + <div id="toggleContainer" checked?="{{checked}}" disabled?="{{disabled}}"> - <div id="toggleBar" checked?="{{checked}}"></div> - - <paper-radio-button id="toggleRadio" toggles checked="{{checked}}" on-change="{{changeAction}}" on-core-change="{{stopPropagation}}" - on-trackstart="{{trackStart}}" on-trackx="{{trackx}}" on-trackend="{{trackEnd}}"></paper-radio-button> - + <div id="toggleBar" class="toggle toggle-bar"></div> + + <div id="toggleButton" class="toggle toggle-button"> + <paper-ripple id="ink" class="toggle-ink circle"></paper-ripple> + </div> + </div> </template> @@ -99,7 +101,7 @@ * @default false */ checked: false, - + /** * If true, the toggle button is disabled. A disabled toggle button cannot * be tapped or dragged to change the checked state. @@ -110,23 +112,55 @@ */ disabled: false, + eventDelegates: { + down: 'downAction', + up: 'upAction', + tap: 'tap', + trackstart: 'trackStart', + trackx: 'trackx', + trackend: 'trackEnd' + }, + + downAction: function(e) { + var rect = this.$.ink.getBoundingClientRect(); + this.$.ink.downAction({ + x: rect.left + rect.width / 2, + y: rect.top + rect.height / 2 + }); + }, + + upAction: function(e) { + this.$.ink.upAction(); + }, + + tap: function() { + if (this.disabled) { + return; + } + this.checked = !this.checked; + this.fire('change'); + }, + trackStart: function(e) { - this._w = this.$.toggleBar.offsetLeft + this.$.toggleBar.offsetWidth; + if (this.disabled) { + return; + } + this._w = this.$.toggleBar.offsetWidth / 2; e.preventTap(); }, trackx: function(e) { this._x = Math.min(this._w, Math.max(0, this.checked ? this._w + e.dx : e.dx)); - this.$.toggleRadio.classList.add('dragging'); - var s = this.$.toggleRadio.style; + this.$.toggleButton.classList.add('dragging'); + var s = this.$.toggleButton.style; s.webkitTransform = s.transform = 'translate3d(' + this._x + 'px,0,0)'; }, trackEnd: function() { - var s = this.$.toggleRadio.style; + var s = this.$.toggleButton.style; s.transform = s.webkitTransform = ''; - this.$.toggleRadio.classList.remove('dragging'); + this.$.toggleButton.classList.remove('dragging'); var old = this.checked; this.checked = Math.abs(this._x) > this._w / 2; if (this.checked !== old) { @@ -137,15 +171,6 @@ checkedChanged: function() { this.setAttribute('aria-pressed', Boolean(this.checked)); this.fire('core-change'); - }, - - changeAction: function(e) { - e.stopPropagation(); - this.fire('change'); - }, - - stopPropagation: function(e) { - e.stopPropagation(); } });
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn index 973672b9..1367d8a 100644 --- a/third_party/protobuf/BUILD.gn +++ b/third_party/protobuf/BUILD.gn
@@ -30,10 +30,13 @@ } } -# This condif should be applied to targets using generated code from the proto +# This config should be applied to targets using generated code from the proto # compiler. It sets up the include directories properly. config("using_proto") { - include_dirs = [ "$root_gen_dir/protoc_out" ] + include_dirs = [ + "src", + "$root_gen_dir/protoc_out", + ] } protobuf_lite_sources = [
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index 8e518068..c6bb5c2 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium
@@ -38,3 +38,5 @@ GetEmptyString() and GoogleOnceInit() have been uninlined, for a large savings in binary size. + +A BUILD.gn file has been added for building with GN.
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium index 8fb3768..368d604a 100644 --- a/third_party/qcms/README.chromium +++ b/third_party/qcms/README.chromium
@@ -53,5 +53,7 @@ - https://code.google.com/p/chromium/issues/detail?id=401971 - Avoid divisions creating sample points in the float cube LUT builder - https://code.google.com/p/chromium/issues/detail?id=443863 + - Add bgra (z,y,x) sampled transform lookup table api + - https://code.google.com/p/chromium/issues/detail?id=443863 To regenerate google.patch: git diff b8456f38 src > google.patch
diff --git a/third_party/qcms/src/qcms.h b/third_party/qcms/src/qcms.h index c69a772..e9c0b09e 100644 --- a/third_party/qcms/src/qcms.h +++ b/third_party/qcms/src/qcms.h
@@ -158,11 +158,15 @@ qcms_profile* out, qcms_data_type out_type, qcms_intent intent); -void qcms_transform_release(qcms_transform *); +qcms_bool qcms_transform_create_LUT_zyx_bgra( + qcms_profile *in, qcms_profile* out, qcms_intent intent, + int samples, unsigned char* lut); void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length); void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type); +void qcms_transform_release(qcms_transform *); + void qcms_enable_iccv4(); #ifdef __cplusplus
diff --git a/third_party/qcms/src/transform.c b/third_party/qcms/src/transform.c index 9fd82389..f669a6b 100644 --- a/third_party/qcms/src/transform.c +++ b/third_party/qcms/src/transform.c
@@ -1167,6 +1167,71 @@ return transform; } +/* Create a transform LUT using the given number of sample points. The transform LUT data is stored + in the output (cube) in bgra format in zyx sample order. */ +qcms_bool qcms_transform_create_LUT_zyx_bgra(qcms_profile *in, qcms_profile *out, qcms_intent intent, + int samples, unsigned char* cube) +{ + uint16_t z,y,x; + uint32_t l,index; + uint32_t lutSize = 3 * samples * samples * samples; + + float* src = NULL; + float* dest = NULL; + float* lut = NULL; + float inverse; + + src = malloc(lutSize*sizeof(float)); + dest = malloc(lutSize*sizeof(float)); + + if (src && dest) { + /* Prepare a list of points we want to sample: z, y, x order */ + l = 0; + inverse = 1 / (float)(samples-1); + for (z = 0; z < samples; z++) { + for (y = 0; y < samples; y++) { + for (x = 0; x < samples; x++) { + src[l++] = x * inverse; // r + src[l++] = y * inverse; // g + src[l++] = z * inverse; // b + } + } + } + + lut = qcms_chain_transform(in, out, src, dest, lutSize); + + if (lut) { + index = l = 0; + for (z = 0; z < samples; z++) { + for (y = 0; y < samples; y++) { + for (x = 0; x < samples; x++) { + cube[index++] = (int)floorf(lut[l + 2] * 255.0f + 0.5f); // b + cube[index++] = (int)floorf(lut[l + 1] * 255.0f + 0.5f); // g + cube[index++] = (int)floorf(lut[l + 0] * 255.0f + 0.5f); // r + cube[index++] = 255; // a + l += 3; + } + } + } + } + } + + // XXX: qcms_modular_transform_data may return the lut data in either the src or + // dest buffer so free src, dest, and lut with care. + + if (src && lut != src) + free(src); + if (dest && lut != dest) + free(dest); + + if (lut) { + free(lut); + return true; + } + + return false; +} + #define NO_MEM_TRANSFORM NULL qcms_transform* qcms_transform_create(
diff --git a/tools/android/forwarder2/device_forwarder_main.cc b/tools/android/forwarder2/device_forwarder_main.cc index c215efa6..8b5df26c 100644 --- a/tools/android/forwarder2/device_forwarder_main.cc +++ b/tools/android/forwarder2/device_forwarder_main.cc
@@ -48,7 +48,7 @@ public: ServerDelegate() : initialized_(false) {} - virtual ~ServerDelegate() { + ~ServerDelegate() override { if (!controller_thread_.get()) return; // The DeviceController instance, if any, is constructed on the controller @@ -68,7 +68,7 @@ } // Daemon::ServerDelegate: - virtual void Init() override { + void Init() override { DCHECK(!g_notifier); g_notifier = new forwarder2::PipeNotifier(); signal(SIGTERM, KillHandler); @@ -77,7 +77,7 @@ controller_thread_->Start(); } - virtual void OnClientConnected(scoped_ptr<Socket> client_socket) override { + void OnClientConnected(scoped_ptr<Socket> client_socket) override { if (initialized_) { client_socket->WriteString("OK"); return; @@ -119,7 +119,7 @@ bool has_failed() const { return has_failed_; } // Daemon::ClientDelegate: - virtual void OnDaemonReady(Socket* daemon_socket) override { + void OnDaemonReady(Socket* daemon_socket) override { char buf[kBufSize]; const int bytes_read = daemon_socket->Read( buf, sizeof(buf) - 1 /* leave space for null terminator */);
diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc index a94a97b..f5d8e2f 100644 --- a/tools/android/forwarder2/host_forwarder_main.cc +++ b/tools/android/forwarder2/host_forwarder_main.cc
@@ -314,7 +314,7 @@ } // Daemon::ServerDelegate: - virtual void Init() override { + void Init() override { LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")"; DCHECK(!g_notifier); g_notifier = new PipeNotifier(); @@ -322,7 +322,7 @@ signal(SIGINT, KillHandler); } - virtual void OnClientConnected(scoped_ptr<Socket> client_socket) override { + void OnClientConnected(scoped_ptr<Socket> client_socket) override { char buf[kBufSize]; const int bytes_read = client_socket->Read(buf, sizeof(buf)); if (bytes_read <= 0) { @@ -366,7 +366,7 @@ bool has_failed() const { return has_failed_; } // Daemon::ClientDelegate: - virtual void OnDaemonReady(Socket* daemon_socket) override { + void OnDaemonReady(Socket* daemon_socket) override { // Send the forward command to the daemon. CHECK_EQ(static_cast<long>(command_pickle_.size()), daemon_socket->WriteNumBytes(command_pickle_.data(),
diff --git a/tools/android/heap_profiler/heap_profiler_unittest.cc b/tools/android/heap_profiler/heap_profiler_unittest.cc index d69af5f7..1771a88a 100644 --- a/tools/android/heap_profiler/heap_profiler_unittest.cc +++ b/tools/android/heap_profiler/heap_profiler_unittest.cc
@@ -14,9 +14,9 @@ class HeapProfilerTest : public testing::Test { public: - virtual void SetUp() override { heap_profiler_init(&stats_); } + void SetUp() override { heap_profiler_init(&stats_); } - virtual void TearDown() override { + void TearDown() override { CheckAllocVsStacktaceConsistency(); heap_profiler_cleanup(); }
diff --git a/tools/auto_bisect/bisect_perf_regression.py b/tools/auto_bisect/bisect_perf_regression.py index f30ceb0..db238be 100755 --- a/tools/auto_bisect/bisect_perf_regression.py +++ b/tools/auto_bisect/bisect_perf_regression.py
@@ -2480,7 +2480,13 @@ metric, test_run_multiplier=BORDER_REVISIONS_EXTRA_RUNS) # Is extend the right thing to do here? - state.value['values'].extend(run_results[0]['values']) + if run_results[1] != BUILD_RESULT_FAIL: + state.value['values'].extend(run_results[0]['values']) + else: + warning_text = 'Re-test of revision %s failed with error message: %s' + warning_text %= (state.revision, run_results[0]) + if warning_text not in self.warnings: + self.warnings.append(warning_text) def _IsPlatformSupported():
diff --git a/tools/bisect-builds.py b/tools/bisect-builds.py index 5e7db2db..99fcb45 100755 --- a/tools/bisect-builds.py +++ b/tools/bisect-builds.py
@@ -32,6 +32,9 @@ # URL template for viewing changelogs between revisions. CHANGELOG_URL = ('https://chromium.googlesource.com/chromium/src/+log/%s..%s') +# GS bucket name for tip of tree android builds. +ANDROID_TOT_BUCKET_NAME = ('chrome-android-tot/bisect') + # GS bucket name for android unsigned official builds. ANDROID_BUCKET_NAME = 'chrome-unsigned/android-C4MPAR1' @@ -142,8 +145,6 @@ # the build. self.githash_svn_dict = {} self.pdf_path = pdf_path - # android_apk defaults to Chrome.apk - self.android_apk = android_apk if android_apk else 'Chrome.apk' # The name of the ZIP file in a revision directory on the server. self.archive_name = None @@ -161,8 +162,14 @@ else: self.local_src_path = None + # Whether the build should be downloaded using gsutil. + self.download_with_gsutil = False + # If the script is being used for android builds. - self.android = self.platform.startswith('android') + self.is_android = self.platform.startswith('android') + # android_apk defaults to Chrome.apk + if self.is_android: + self.android_apk = android_apk if android_apk else 'Chrome.apk' # Set some internal members: # _listing_platform_dir = Directory that holds revisions. Ends with a '/'. @@ -177,7 +184,7 @@ self.archive_name = 'chrome-win32.zip' self._archive_extract_dir = 'chrome-win32' self._binary_name = 'chrome.exe' - elif self.android: + elif self.is_android: pass else: raise Exception('Invalid platform: %s' % self.platform) @@ -234,6 +241,11 @@ self._binary_name = 'Chromium.app/Contents/MacOS/Chromium' elif self.platform == 'win': self._listing_platform_dir = 'Win/' + elif self.platform == 'android-arm': + self.archive_name = 'bisect_android.zip' + # Need to download builds using gsutil instead of visiting url for + # authentication reasons. + self.download_with_gsutil = True def GetASANPlatformDir(self): """ASAN builds are in directories like "linux-release", or have filenames @@ -263,7 +275,7 @@ ASAN_BASE_URL, self.GetASANPlatformDir(), self.build_type, self.GetASANBaseName(), revision) if self.is_official: - if self.android: + if self.is_android: official_base_url = ANDROID_OFFICIAL_BASE_URL else: official_base_url = OFFICIAL_BASE_URL @@ -271,10 +283,15 @@ official_base_url, revision, self._listing_platform_dir, self.archive_name) else: - if str(revision) in self.githash_svn_dict: - revision = self.githash_svn_dict[str(revision)] - return '%s/%s%s/%s' % (self.base_url, self._listing_platform_dir, - revision, self.archive_name) + if self.is_android: + # These files need to be downloaded through gsutil. + return ('gs://%s/%s/%s' % (ANDROID_TOT_BUCKET_NAME, revision, + self.archive_name)) + else: + if str(revision) in self.githash_svn_dict: + revision = self.githash_svn_dict[str(revision)] + return '%s/%s%s/%s' % (self.base_url, self._listing_platform_dir, + revision, self.archive_name) def GetLastChangeURL(self): """Returns a URL to the LAST_CHANGE file.""" @@ -544,52 +561,51 @@ self.bad_revision) return revlist + def _GetHashToNumberDict(self): + """Gets the mapping of git hashes to git numbers from Google Storage.""" + gs_file = 'gs://%s/gitnumbers_dict.json' % ANDROID_TOT_BUCKET_NAME + local_file = 'gitnumbers_dict.json' + GsutilDownload(gs_file, local_file) + json_data = open(local_file).read() + os.remove(local_file) + return json.loads(json_data) + + def GetAndroidToTRevisions(self): + """Gets the ordered list of revisions between self.good_revision and + self.bad_revision from the Android tip of tree GS bucket. + """ + # Dictionary that maps git hashes to git numbers. The git numbers + # let us order the revisions. + hash_to_num = self._GetHashToNumberDict() + try: + good_rev_num = hash_to_num[self.good_revision] + bad_rev_num = hash_to_num[self.bad_revision] + except KeyError: + exit('Error. Make sure the good and bad revisions are valid git hashes.') + + # List of all builds by their git hashes in the storage bucket. + hash_list = GsutilList(ANDROID_TOT_BUCKET_NAME) + + # Get list of builds that we want to bisect over. + final_list = [] + minnum = min(good_rev_num, bad_rev_num) + maxnum = max(good_rev_num, bad_rev_num) + for githash in hash_list: + if len(githash) != 40: + continue + gitnumber = hash_to_num[githash] + if minnum < gitnumber < maxnum: + final_list.append(githash) + return sorted(final_list, key=lambda h: hash_to_num[h]) + def GetOfficialBuildsList(self): """Gets the list of official build numbers between self.good_revision and self.bad_revision.""" - def CheckDepotToolsInPath(): - delimiter = ';' if sys.platform.startswith('win') else ':' - path_list = os.environ['PATH'].split(delimiter) - for path in path_list: - if path.rstrip(os.path.sep).endswith('depot_tools'): - return path - return None - - def RunGsutilCommand(args): - gsutil_path = CheckDepotToolsInPath() - if gsutil_path is None: - print ('Follow the instructions in this document ' - 'http://dev.chromium.org/developers/how-tos/install-depot-tools' - ' to install depot_tools and then try again.') - sys.exit(1) - gsutil_path = os.path.join(gsutil_path, 'third_party', 'gsutil', 'gsutil') - gsutil = subprocess.Popen([sys.executable, gsutil_path] + args, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - env=None) - stdout, stderr = gsutil.communicate() - if gsutil.returncode: - if (re.findall(r'status[ |=]40[1|3]', stderr) or - stderr.startswith(CREDENTIAL_ERROR_MESSAGE)): - print ('Follow these steps to configure your credentials and try' - ' running the bisect-builds.py again.:\n' - ' 1. Run "python %s config" and follow its instructions.\n' - ' 2. If you have a @google.com account, use that account.\n' - ' 3. For the project-id, just enter 0.' % gsutil_path) - sys.exit(1) - else: - raise Exception('Error running the gsutil command: %s' % stderr) - return stdout - - def GsutilList(bucket): - query = 'gs://%s/' % bucket - stdout = RunGsutilCommand(['ls', query]) - return [url[len(query):].strip('/') for url in stdout.splitlines()] - # Download the revlist and filter for just the range between good and bad. minrev = min(self.good_revision, self.bad_revision) maxrev = max(self.good_revision, self.bad_revision) - if self.android: + if self.is_android: gs_bucket_name = ANDROID_BUCKET_NAME else: gs_bucket_name = GS_BUCKET_NAME @@ -614,6 +630,52 @@ connection.close() return final_list + +def CheckDepotToolsInPath(): + delimiter = ';' if sys.platform.startswith('win') else ':' + path_list = os.environ['PATH'].split(delimiter) + for path in path_list: + if path.rstrip(os.path.sep).endswith('depot_tools'): + return path + return None + + +def RunGsutilCommand(args): + gsutil_path = CheckDepotToolsInPath() + if gsutil_path is None: + print ('Follow the instructions in this document ' + 'http://dev.chromium.org/developers/how-tos/install-depot-tools' + ' to install depot_tools and then try again.') + sys.exit(1) + gsutil_path = os.path.join(gsutil_path, 'third_party', 'gsutil', 'gsutil') + gsutil = subprocess.Popen([sys.executable, gsutil_path] + args, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=None) + stdout, stderr = gsutil.communicate() + if gsutil.returncode: + if (re.findall(r'status[ |=]40[1|3]', stderr) or + stderr.startswith(CREDENTIAL_ERROR_MESSAGE)): + print ('Follow these steps to configure your credentials and try' + ' running the bisect-builds.py again.:\n' + ' 1. Run "python %s config" and follow its instructions.\n' + ' 2. If you have a @google.com account, use that account.\n' + ' 3. For the project-id, just enter 0.' % gsutil_path) + sys.exit(1) + else: + raise Exception('Error running the gsutil command: %s' % stderr) + return stdout + + +def GsutilList(bucket): + query = 'gs://%s/' % bucket + stdout = RunGsutilCommand(['ls', query]) + return [url[len(query):].strip('/') for url in stdout.splitlines()] + + +def GsutilDownload(gs_download_url, filename): + RunGsutilCommand(['cp', gs_download_url, filename]) + + def UnzipFilenameToDir(filename, directory): """Unzip |filename| to |directory|.""" cwd = os.getcwd() @@ -632,7 +694,7 @@ os.makedirs(name) else: # file directory = os.path.dirname(name) - if not os.path.isdir(directory): + if directory and not os.path.isdir(directory): os.makedirs(directory) out = open(name, 'wb') out.write(zf.read(name)) @@ -667,20 +729,32 @@ # Send a \r to let all progress messages use just one line of output. sys.stdout.write('\r' + progress) sys.stdout.flush() - download_url = context.GetDownloadURL(rev) try: - urllib.urlretrieve(download_url, filename, ReportHook) + if context.download_with_gsutil: + GsutilDownload(download_url, filename) + else: + urllib.urlretrieve(download_url, filename, ReportHook) if progress_event and progress_event.isSet(): print + except RuntimeError: pass +def RunADBCommand(args): + cmd = ['adb'] + args + adb = subprocess.Popen(['adb'] + args, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=None) + stdout, stderr = adb.communicate() + return stdout + + def IsADBInstalled(): """Checks if ADB is in the environment path.""" try: - adb_output = subprocess.check_output(['adb', 'version']) + adb_output = RunADBCommand(['version']) return ('Android Debug Bridge' in adb_output) except OSError: return False @@ -688,7 +762,7 @@ def GetAndroidDeviceList(): """Returns the list of Android devices attached to the host machine.""" - lines = subprocess.check_output(['adb', 'devices']).split('\n')[1:] + lines = RunADBCommand(['devices']).split('\n')[1:] devices = [] for line in lines: m = re.match('^(.*?)\s+device$', line) @@ -698,31 +772,38 @@ return devices -def RunAndroidRevision(context, revision, apk_file): +def RunAndroidRevision(context, revision, zip_file): """Given a Chrome apk, install it on a local device, and launch Chrome.""" devices = GetAndroidDeviceList() if len(devices) is not 1: sys.exit('Please have 1 Android device plugged in. %d devices found' % len(devices)) - devnull = open(os.devnull, 'w') - package_name = ANDROID_CHROME_PACKAGE_NAME[context.android_apk] + if context.is_official: + # Downloaded file is just the .apk in this case. + apk_file = zip_file + else: + cwd = os.getcwd() + tempdir = tempfile.mkdtemp(prefix='bisect_tmp') + UnzipFilenameToDir(zip_file, tempdir) + os.chdir(tempdir) + apk_file = context.android_apk - print 'Installing new Chrome version...' - subprocess.call(['adb', 'install', '-r', '-d', apk_file], - stdout=devnull, stderr=devnull) + package_name = ANDROID_CHROME_PACKAGE_NAME[context.android_apk] + print 'Installing...' + RunADBCommand(['install', '-r', '-d', apk_file]) print 'Launching Chrome...\n' - subprocess.call(['adb', 'shell', 'am', 'start', '-a', + RunADBCommand(['shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-n', package_name + - '/com.google.android.apps.chrome.Main'], stdout=devnull, stderr=devnull) + '/com.google.android.apps.chrome.Main']) def RunRevision(context, revision, zip_file, profile, num_runs, command, args): """Given a zipped revision, unzip it and run the test.""" print 'Trying revision %s...' % str(revision) - if context.android: + if context.is_android: RunAndroidRevision(context, revision, zip_file) # TODO(mikecase): Support running command to auto-bisect Android. return (None, None, None) @@ -779,7 +860,6 @@ stderr=subprocess.PIPE) (stdout, stderr) = subproc.communicate() results.append((subproc.returncode, stdout, stderr)) - os.chdir(cwd) try: shutil.rmtree(tempdir, True) @@ -917,6 +997,8 @@ '%s-%s' % (str(rev), context.archive_name)) if context.is_official: revlist = context.GetOfficialBuildsList() + elif context.is_android: # Android non-official + revlist = context.GetAndroidToTRevisions() else: revlist = context.GetRevList() @@ -1299,12 +1381,14 @@ opts.official_builds, opts.asan, opts.use_local_cache, opts.flash_path, opts.pdf_path, opts.apk) - # TODO(mikecase): Add support to bisect on nonofficial builds for Android. - if context.android and not opts.official_builds: - sys.exit('Can only bisect on official builds for Android.') + if context.is_android and not opts.official_builds: + if (context.platform != 'android-arm' or + context.android_apk != 'Chrome.apk'): + sys.exit('For non-official builds, can only bisect' + ' Chrome.apk arm builds.') # If bisecting Android, we make sure we have ADB setup. - if context.android: + if context.is_android: if opts.adb_path: os.environ['PATH'] = '%s:%s' % (os.path.dirname(opts.adb_path), os.environ['PATH']) @@ -1333,6 +1417,9 @@ if opts.official_builds: context.good_revision = LooseVersion(context.good_revision) context.bad_revision = LooseVersion(context.bad_revision) + elif context.is_android: + # Revisions are git hashes and should be left as strings. + pass else: context.good_revision = int(context.good_revision) context.bad_revision = int(context.bad_revision)
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py index f856f5ba..a8cac704 100644 --- a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py +++ b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py
@@ -15,7 +15,6 @@ CHROME_PROXY_VIA_HEADER = 'Chrome-Compression-Proxy' -CHROME_PROXY_VIA_HEADER_DEPRECATED = '1.1 Chrome Compression Proxy' class ChromeProxyResponse(network_metrics.HTTPResponse): @@ -44,11 +43,9 @@ if not via_header: return False vias = [v.strip(' ') for v in via_header.split(',')] - # The Via header is valid if it is the old format or the new format - # with 4-character version prefix, for example, - # "1.1 Chrome-Compression-Proxy". - return (CHROME_PROXY_VIA_HEADER_DEPRECATED in vias or - any(v[4:] == CHROME_PROXY_VIA_HEADER for v in vias)) + # The Via header is valid if it has a 4-character version prefix followed by + # the proxy name, for example, "1.1 Chrome-Compression-Proxy". + return any(v[4:] == CHROME_PROXY_VIA_HEADER for v in vias) def IsValidByViaHeader(self): return (not self.ShouldHaveChromeProxyViaHeader() or @@ -323,7 +320,7 @@ raise ChromeProxyMetricException, ( 'Response for %s should have come through the fallback proxy.\n' 'Response: remote_port=%s status=(%d, %s)\nHeaders:\n %s' % ( - r.url, str(fallback_resp.remote_port), r.status, r.status_text, + r.url, str(resp.remote_port), r.status, r.status_text, r.headers)) else: via_fallback_count += 1
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics_unittest.py b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics_unittest.py index 9396a09d..33aee4a 100644 --- a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics_unittest.py +++ b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics_unittest.py
@@ -46,19 +46,6 @@ body=network_unittest.HTML_BODY, remote_port=80)) -# An HTML via proxy with the deprecated Via header. -EVENT_HTML_PROXY_DEPRECATED_VIA = ( - network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent( - url='http://test.html2', - response_headers={ - 'Content-Type': 'text/html', - 'Content-Encoding': 'gzip', - 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)), - 'Via': (metrics.CHROME_PROXY_VIA_HEADER_DEPRECATED + - ',other-via'), - }, - body=network_unittest.HTML_BODY)) - # An image via proxy with Via header. EVENT_IMAGE_PROXY_VIA = ( network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent( @@ -123,7 +110,7 @@ }, status=307)) -# An HTML via proxy with the deprecated Via header. +# An HTML via proxy with the Via header. EVENT_IMAGE_BYPASS = ( network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent( url='http://test.image', @@ -191,7 +178,7 @@ metric = metrics.ChromeProxyMetric() events = [ EVENT_HTML_DIRECT, - EVENT_HTML_PROXY_DEPRECATED_VIA, + EVENT_HTML_PROXY_VIA, EVENT_IMAGE_PROXY_CACHED, EVENT_IMAGE_DIRECT] metric.SetEvents(events) @@ -208,7 +195,7 @@ metric = metrics.ChromeProxyMetric() metric.SetEvents([ EVENT_HTML_DIRECT, - EVENT_HTML_PROXY_DEPRECATED_VIA, + EVENT_HTML_PROXY_VIA, EVENT_IMAGE_PROXY_CACHED, EVENT_IMAGE_DIRECT]) @@ -224,7 +211,7 @@ # Two events with valid Via headers. metric.SetEvents([ - EVENT_HTML_PROXY_DEPRECATED_VIA, + EVENT_HTML_PROXY_VIA, EVENT_IMAGE_PROXY_CACHED]) metric.AddResultsForHeaderValidation(None, results) results.AssertHasPageSpecificScalarValue('checked_via_header', 'count', 2) @@ -233,7 +220,7 @@ metric = metrics.ChromeProxyMetric() metric.SetEvents([ EVENT_HTML_DIRECT, - EVENT_HTML_PROXY_DEPRECATED_VIA, + EVENT_HTML_PROXY_VIA, EVENT_IMAGE_PROXY_CACHED, EVENT_IMAGE_DIRECT]) results = test_page_test_results.TestPageTestResults(self) @@ -253,7 +240,7 @@ def testChromeProxyMetricForCorsBypass(self): metric = metrics.ChromeProxyMetric() - metric.SetEvents([EVENT_HTML_PROXY_DEPRECATED_VIA, + metric.SetEvents([EVENT_HTML_PROXY_VIA, EVENT_IMAGE_BYPASS, EVENT_IMAGE_DIRECT]) results = test_page_test_results.TestPageTestResults(self) @@ -279,19 +266,21 @@ # The second response was over direct, but was expected via proxy. self.assertTrue(exception_occurred) - def testChromeProxyMetricForSafebrowsing(self): + def testChromeProxyMetricForSafebrowsingOn(self): metric = metrics.ChromeProxyMetric() metric.SetEvents([EVENT_MALWARE_PROXY]) results = test_page_test_results.TestPageTestResults(self) - metric.AddResultsForSafebrowsing(None, results) - results.AssertHasPageSpecificScalarValue('safebrowsing', 'boolean', True) + metric.AddResultsForSafebrowsingOn(None, results) + results.AssertHasPageSpecificScalarValue( + 'safebrowsing', 'timeout responses', 1) # Clear results and metrics to test no response for safebrowsing results = test_page_test_results.TestPageTestResults(self) metric.SetEvents([]) - metric.AddResultsForSafebrowsing(None, results) - results.AssertHasPageSpecificScalarValue('safebrowsing', 'boolean', True) + metric.AddResultsForSafebrowsingOn(None, results) + results.AssertHasPageSpecificScalarValue( + 'safebrowsing', 'timeout responses', 1) def testChromeProxyMetricForHTTPFallback(self): metric = metrics.ChromeProxyMetric() @@ -318,7 +307,7 @@ EVENT_HTML_DIRECT, EVENT_IMAGE_DIRECT]) results = test_page_test_results.TestPageTestResults(self) - metric.AddResultsForHTTPToDirectFallback(None, results) + metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2') results.AssertHasPageSpecificScalarValue('via_fallback', 'count', 1) results.AssertHasPageSpecificScalarValue('bypass', 'count', 2) @@ -326,7 +315,7 @@ EVENT_HTML_DIRECT]) exception_occurred = False try: - metric.AddResultsForHTTPToDirectFallback(None, results) + metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2') except metrics.ChromeProxyMetricException: exception_occurred = True # The first response was expected through the HTTP fallback proxy. @@ -337,7 +326,7 @@ EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK]) exception_occurred = False try: - metric.AddResultsForHTTPToDirectFallback(None, results) + metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2') except metrics.ChromeProxyMetricException: exception_occurred = True # All but the first response were expected to be over direct. @@ -348,7 +337,7 @@ EVENT_IMAGE_DIRECT]) exception_occurred = False try: - metric.AddResultsForHTTPToDirectFallback(None, results) + metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2') except metrics.ChromeProxyMetricException: exception_occurred = True # The first response was expected through the HTTP fallback proxy.
diff --git a/tools/chrome_proxy/integration_tests/network_metrics.py b/tools/chrome_proxy/integration_tests/network_metrics.py index 747d60d..9c41dcc 100644 --- a/tools/chrome_proxy/integration_tests/network_metrics.py +++ b/tools/chrome_proxy/integration_tests/network_metrics.py
@@ -13,7 +13,6 @@ from telemetry.page import page_test # All network metrics are Chrome only for now. from telemetry.core.backends.chrome_inspector import inspector_network -from telemetry.timeline import recording_options from telemetry.value import scalar @@ -138,9 +137,7 @@ def Start(self, page, tab): self._events = None - opts = recording_options.TimelineRecordingOptions() - opts.record_network = True - tab.StartTimelineRecording(opts) + tab.StartTimelineRecording() def Stop(self, page, tab): assert self._events is None
diff --git a/tools/cygprofile/cyglog_to_orderfile.py b/tools/cygprofile/cyglog_to_orderfile.py index 0213fa49..db12328 100755 --- a/tools/cygprofile/cyglog_to_orderfile.py +++ b/tools/cygprofile/cyglog_to_orderfile.py
@@ -220,11 +220,18 @@ def main(): - if len(sys.argv) != 4: - logging.error('Usage: cyglog_to_orderfile.py <merged_cyglog> ' - '<library> <output_filename>') + parser = optparse.OptionParser(usage= + 'usage: %prog [options] <merged_cyglog> <library> <output_filename>') + parser.add_option('--target-arch', action='store', dest='arch', + default='arm', + choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'], + help='The target architecture for libchrome.so') + options, argv = parser.parse_args(sys.argv) + if len(argv) != 4: + parser.print_help() return 1 - (log_filename, lib_filename, output_filename) = sys.argv[1:] + (log_filename, lib_filename, output_filename) = argv[1:] + symbol_extractor.SetArchitecture(options.arch) obj_dir = os.path.abspath(os.path.join( os.path.dirname(lib_filename), '../obj'))
diff --git a/tools/cygprofile/cygprofile_unittest.cc b/tools/cygprofile/cygprofile_unittest.cc index 7a1a3e2..2022c03b 100644 --- a/tools/cygprofile/cygprofile_unittest.cc +++ b/tools/cygprofile/cygprofile_unittest.cc
@@ -46,12 +46,12 @@ ASSERT_EQ(2U, entries.size()); // The entries should appear in their insertion order. const LogEntry& first_entry = entries[0]; - ASSERT_EQ(reinterpret_cast<int>(first_entry.address), 2); + ASSERT_EQ(reinterpret_cast<uintptr_t>(first_entry.address), 2); ASSERT_EQ(getpid(), first_entry.pid); ASSERT_LT(0, first_entry.tid); const LogEntry& second_entry = entries[1]; - ASSERT_EQ(1, reinterpret_cast<int>(second_entry.address)); + ASSERT_EQ(1, reinterpret_cast<uintptr_t>(second_entry.address)); ASSERT_EQ(first_entry.pid, second_entry.pid); ASSERT_EQ(first_entry.tid, second_entry.tid); @@ -87,8 +87,8 @@ // The flush should have moved the data to the local vector of entries. EXPECT_EQ(2U, entries.size()); - ASSERT_EQ(2, reinterpret_cast<int>(entries[0].address)); - ASSERT_EQ(3, reinterpret_cast<int>(entries[1].address)); + ASSERT_EQ(2, reinterpret_cast<uintptr_t>(entries[0].address)); + ASSERT_EQ(3, reinterpret_cast<uintptr_t>(entries[1].address)); } } // namespace
diff --git a/tools/cygprofile/patch_orderfile.py b/tools/cygprofile/patch_orderfile.py index f4b590f49c..88abc62 100755 --- a/tools/cygprofile/patch_orderfile.py +++ b/tools/cygprofile/patch_orderfile.py
@@ -26,6 +26,7 @@ import collections import logging +import optparse import sys import symbol_extractor @@ -204,11 +205,19 @@ def main(argv): + parser = optparse.OptionParser(usage= + 'usage: %prog [options] <unpatched_orderfile> <library>') + parser.add_option('--target-arch', action='store', dest='arch', + default='arm', + choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'], + help='The target architecture for the library.') + options, argv = parser.parse_args(argv) if len(argv) != 3: - print 'Usage: %s <unpatched_orderfile> <libchrome.so>' % argv[0] + parser.print_help() return 1 orderfile_filename = argv[1] binary_filename = argv[2] + symbol_extractor.SetArchitecture(options.arch) (offset_to_symbol_infos, name_to_symbol_infos) = _GroupSymbolInfosFromBinary( binary_filename) profiled_symbols = GetSymbolsFromOrderfile(orderfile_filename)
diff --git a/tools/cygprofile/symbol_extractor.py b/tools/cygprofile/symbol_extractor.py index 5fd67a1..81c6e66 100755 --- a/tools/cygprofile/symbol_extractor.py +++ b/tools/cygprofile/symbol_extractor.py
@@ -18,14 +18,13 @@ import symbol -# TODO(lizeb): Change symbol.ARCH to the proper value when "arm" is no longer -# the only possible value. -_OBJDUMP_BINARY = symbol.ToolPath('objdump') - - SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size', 'section')) +def SetArchitecture(arch): + """Set the architecture for binaries to be symbolized.""" + symbol.ARCH = arch + def _FromObjdumpLine(line): """Create a SymbolInfo by parsing a properly formatted objdump output line. @@ -81,7 +80,7 @@ Returns: A list of SymbolInfo from the binary. """ - command = (_OBJDUMP_BINARY, '-t', '-w', binary_filename) + command = (symbol.ToolPath('objdump'), '-t', '-w', binary_filename) p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE) try: result = _SymbolInfosFromStream(p.stdout)
diff --git a/tools/git/move_source_file.py b/tools/git/move_source_file.py index 117b3eb..b5496fd 100755 --- a/tools/git/move_source_file.py +++ b/tools/git/move_source_file.py
@@ -119,6 +119,48 @@ r'\1%s\2' % PathMinusFirstComponent(to_path), ['*.gyp*']) + # Update references in BUILD.gn files. + # + # Unlike .gyp(i) files, BUILD.gn files can be placed in any directories, + # and paths in a BUILD.gn file are relative to the directory where the + # BUILD.gn file is placed. + # + # For instance, "chrome/browser/chromeos/device_uma.h" is listed as + # "browser/chromeos/device_uma.h" in "chrome/chrome_browser_chromeos.gypi", + # but it's listed as "device_uma.h" in "chrome/browser/chromeos/BUILD.gn". + # + # To handle this, the code here will visit directories from the top level + # src directory to the directory of |from_path| and try to update BUILD.gn + # in each directory. + # + # The code only handles files moved/renamed within the same BUILD.gn + # file. If files are moved beyond the same BUILD.gn file, the affected + # BUILD.gn files should be fixed manually. + def SplitByFirstComponent(path): + """'foo/bar/baz' -> ('foo', 'bar/baz') + 'bar' -> ('bar', '') + '' -> ('', '') + """ + parts = re.split(r"[/\\]", path, 1) + if len(parts) == 2: + return (parts[0], parts[1]) + else: + return (parts[0], '') + + visiting_directory = '' + from_rest = from_path + to_rest = to_path + while True: + mffr.MultiFileFindReplace( + r'([\'"])%s([\'"])' % from_rest, + r'\1%s\2' % to_rest, + [os.path.join(visiting_directory, 'BUILD.gn')]) + from_first, from_rest = SplitByFirstComponent(from_rest) + to_first, to_rest = SplitByFirstComponent(to_rest) + visiting_directory = os.path.join(visiting_directory, from_first) + if not from_rest or not to_rest: + break + def MakeIncludeGuardName(path_from_root): """Returns an include guard name given a path from root."""
diff --git a/tools/gn/action_target_generator.cc b/tools/gn/action_target_generator.cc index 09c89e4..a1ab3a3 100644 --- a/tools/gn/action_target_generator.cc +++ b/tools/gn/action_target_generator.cc
@@ -54,6 +54,9 @@ if (!FillDepfile()) return; + if (!FillCheckIncludes()) + return; + if (!CheckOutputs()) return;
diff --git a/tools/gn/binary_target_generator.cc b/tools/gn/binary_target_generator.cc index deee2161..923d0edd 100644 --- a/tools/gn/binary_target_generator.cc +++ b/tools/gn/binary_target_generator.cc
@@ -63,16 +63,6 @@ return; } -bool BinaryTargetGenerator::FillCheckIncludes() { - const Value* value = scope_->GetValue(variables::kCheckIncludes, true); - if (!value) - return true; - if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) - return false; - target_->set_check_includes(value->boolean_value()); - return true; -} - bool BinaryTargetGenerator::FillCompleteStaticLib() { if (target_->output_type() == Target::STATIC_LIBRARY) { const Value* value = scope_->GetValue(variables::kCompleteStaticLib, true);
diff --git a/tools/gn/binary_target_generator.h b/tools/gn/binary_target_generator.h index 0b8d521a..6d74238 100644 --- a/tools/gn/binary_target_generator.h +++ b/tools/gn/binary_target_generator.h
@@ -23,7 +23,6 @@ void DoRun() override; private: - bool FillCheckIncludes(); bool FillCompleteStaticLib(); bool FillOutputName(); bool FillOutputExtension();
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc index db7befca..797ffaa 100644 --- a/tools/gn/target_generator.cc +++ b/tools/gn/target_generator.cc
@@ -283,6 +283,16 @@ return true; } +bool TargetGenerator::FillCheckIncludes() { + const Value* value = scope_->GetValue(variables::kCheckIncludes, true); + if (!value) + return true; + if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) + return false; + target_->set_check_includes(value->boolean_value()); + return true; +} + bool TargetGenerator::EnsureSubstitutionIsInOutputDir( const SubstitutionPattern& pattern, const Value& original_value) {
diff --git a/tools/gn/target_generator.h b/tools/gn/target_generator.h index c93b12b..ef2ab83 100644 --- a/tools/gn/target_generator.h +++ b/tools/gn/target_generator.h
@@ -53,6 +53,7 @@ bool FillInputs(); bool FillConfigs(); bool FillOutputs(bool allow_substitutions); + bool FillCheckIncludes(); // Rrturns true if the given pattern will expand to a file in the output // directory. If not, returns false and sets the error, blaming the given
diff --git a/tools/ipc_fuzzer/mutate/generate.cc b/tools/ipc_fuzzer/mutate/generate.cc index 429f91d..6d8137d 100644 --- a/tools/ipc_fuzzer/mutate/generate.cc +++ b/tools/ipc_fuzzer/mutate/generate.cc
@@ -450,6 +450,24 @@ } }; +template <class A, class B, class C, class D> +struct GenerateTraits<std::map<A, B, C, D>> { + static bool Generate(std::map<A, B, C, D>* p, Generator* generator) { + static int g_depth = 0; + size_t count = ++g_depth > 3 ? 0 : RandElementCount(); + std::pair<A, B> place_holder; + for (size_t i = 0; i < count; ++i) { + if (!GenerateParam(&place_holder, generator)) { + --g_depth; + return false; + } + p->insert(place_holder); + } + --g_depth; + return true; + } +}; + template <class A, class B> struct GenerateTraits<std::pair<A, B> > { static bool Generate(std::pair<A, B>* p, Generator* generator) { @@ -504,9 +522,9 @@ return false; if (!GenerateParam(&last_modified, generator)) return false; - if (GenerateParam(&last_accessed, generator)) + if (!GenerateParam(&last_accessed, generator)) return false; - if (GenerateParam(&creation_time, generator)) + if (!GenerateParam(&creation_time, generator)) return false; p->last_modified = base::Time::FromDoubleT(last_modified); p->last_accessed = base::Time::FromDoubleT(last_accessed); @@ -941,8 +959,26 @@ }; template <> +struct GenerateTraits<content::NPIdentifier_Param> { + static bool Generate(content::NPIdentifier_Param* p, Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = content::NPIdentifier_Param(); + return true; + } +}; + +template <> +struct GenerateTraits<content::NPVariant_Param> { + static bool Generate(content::NPVariant_Param* p, Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = content::NPVariant_Param(); + return true; + } +}; + +template <> struct GenerateTraits<content::PageState> { - static bool Generate(content::PageState *p, Generator* generator) { + static bool Generate(content::PageState* p, Generator* generator) { std::string junk; if (!GenerateParam(&junk, generator)) return false; @@ -952,6 +988,96 @@ }; template <> +struct GenerateTraits<content::SyntheticGesturePacket> { + static bool Generate(content::SyntheticGesturePacket* p, + Generator* generator) { + scoped_ptr<content::SyntheticGestureParams> gesture_params; + switch (RandInRange(3)) { + case content::SyntheticGestureParams::GestureType:: + SMOOTH_SCROLL_GESTURE: { + content::SyntheticSmoothScrollGestureParams* params = + new content::SyntheticSmoothScrollGestureParams(); + if (!GenerateParam(¶ms->anchor, generator)) + return false; + if (!GenerateParam(¶ms->distances, generator)) + return false; + if (!GenerateParam(¶ms->prevent_fling, generator)) + return false; + if (!GenerateParam(¶ms->speed_in_pixels_s, generator)) + return false; + gesture_params.reset(params); + break; + } + case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: { + content::SyntheticPinchGestureParams* params = + new content::SyntheticPinchGestureParams(); + if (!GenerateParam(¶ms->scale_factor, generator)) + return false; + if (!GenerateParam(¶ms->anchor, generator)) + return false; + if (!GenerateParam(¶ms->relative_pointer_speed_in_pixels_s, + generator)) + return false; + gesture_params.reset(params); + break; + } + case content::SyntheticGestureParams::GestureType::TAP_GESTURE: { + content::SyntheticTapGestureParams* params = + new content::SyntheticTapGestureParams(); + if (!GenerateParam(¶ms->position, generator)) + return false; + if (!GenerateParam(¶ms->duration_ms, generator)) + return false; + gesture_params.reset(params); + break; + } + } + p->set_gesture_params(gesture_params.Pass()); + return true; + } +}; + +template <> +struct GenerateTraits<content::WebCursor> { + static bool Generate(content::WebCursor* p, Generator* generator) { + blink::WebCursorInfo::Type type; + if (!GenerateParam(&type, generator)) + return false; + content::WebCursor::CursorInfo info(type); + + // Omitting |externalHandle| since it is not serialized. + if (!GenerateParam(&info.hotspot, generator)) + return false; + if (!GenerateParam(&info.image_scale_factor, generator)) + return false; + if (!GenerateParam(&info.custom_image, generator)) + return false; + *p = content::WebCursor(info); + return true; + } +}; + +template <> +struct GenerateTraits<ContentSettingsPattern> { + static bool Generate(ContentSettingsPattern* p, Generator* generator) { + // TODO(mbarbella): This can crash if a pattern is generated from a random + // string. We could carefully generate a pattern or fix pattern generation. + *p = ContentSettingsPattern(); + return true; + } +}; + +template <> +struct GenerateTraits<ExtensionMsg_PermissionSetStruct> { + static bool Generate(ExtensionMsg_PermissionSetStruct* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ExtensionMsg_PermissionSetStruct(); + return true; + } +}; + +template <> struct GenerateTraits<extensions::URLPatternSet> { static bool Generate(extensions::URLPatternSet* p, Generator* generator) { std::set<URLPattern> patterns; @@ -963,187 +1089,6 @@ }; template <> -struct GenerateTraits<gpu::Mailbox> { - static bool Generate(gpu::Mailbox *p, Generator* generator) { - generator->GenerateBytes(p->name, sizeof(p->name)); - return true; - } -}; - -template <> -struct GenerateTraits<gpu::MailboxHolder> { - static bool Generate(gpu::MailboxHolder *p, Generator* generator) { - gpu::Mailbox mailbox; - uint32_t texture_target; - uint32_t sync_point; - if (!GenerateParam(&mailbox, generator)) - return false; - if (!GenerateParam(&texture_target, generator)) - return false; - if (!GenerateParam(&sync_point, generator)) - return false; - *p = gpu::MailboxHolder(mailbox, texture_target, sync_point); - return true; - } -}; - -template <> -struct GenerateTraits<gpu::ValueState> { - static bool Generate(gpu::ValueState* p, Generator* generator) { - gpu::ValueState state; - if (!GenerateParamArray(&state.float_value[0], 4, generator)) - return false; - if (!GenerateParamArray(&state.int_value[0], 4, generator)) - return false; - *p = state; - return true; - } -}; - -template <> -struct GenerateTraits<GURL> { - static bool Generate(GURL *p, Generator* generator) { - const char url_chars[] = "Ahtp0:/.?+\\%&#"; - size_t count = RandInRange(100); - std::string random_url; - for (size_t i = 0; i < count; ++i) - random_url += url_chars[RandInRange(sizeof(url_chars) - 1)]; - int selector = RandInRange(10); - if (selector == 0) - random_url = std::string("http://") + random_url; - else if (selector == 1) - random_url = std::string("file://") + random_url; - else if (selector == 2) - random_url = std::string("javascript:") + random_url; - else if (selector == 2) - random_url = std::string("data:") + random_url; - *p = GURL(random_url); - return true; - } -}; - -template <> -struct GenerateTraits<media::AudioParameters> { - static bool Generate(media::AudioParameters *p, Generator* generator) { - int format; - int channel_layout; - int sample_rate; - int bits_per_sample; - int frames_per_buffer; - int channels; - int effects; - if (!GenerateParam(&format, generator)) - return false; - if (!GenerateParam(&channel_layout, generator)) - return false; - if (!GenerateParam(&sample_rate, generator)) - return false; - if (!GenerateParam(&bits_per_sample, generator)) - return false; - if (!GenerateParam(&frames_per_buffer, generator)) - return false; - if (!GenerateParam(&channels, generator)) - return false; - if (!GenerateParam(&effects, generator)) - return false; - media::AudioParameters params( - static_cast<media::AudioParameters::Format>(format), - static_cast<media::ChannelLayout>(channel_layout), - channels, - sample_rate, - bits_per_sample, - frames_per_buffer, - effects); - *p = params; - return true; - } -}; - -template <> -struct GenerateTraits<media::VideoCaptureFormat> { - static bool Generate(media::VideoCaptureFormat *p, Generator* generator) { - int frame_size_width; - int frame_size_height; - int pixel_format; - if (!GenerateParam(&frame_size_height, generator)) - return false; - if (!GenerateParam(&frame_size_width, generator)) - return false; - if (!GenerateParam(&pixel_format, generator)) - return false; - if (!GenerateParam(&p->frame_rate, generator)) - return false; - p->frame_size.SetSize(frame_size_width, frame_size_height); - p->pixel_format = static_cast<media::VideoPixelFormat>(pixel_format); - return true; - } -}; - - -template <> -struct GenerateTraits<net::LoadTimingInfo> { - static bool Generate(net::LoadTimingInfo *p, Generator* generator) { - return - GenerateParam(&p->socket_log_id, generator) && - GenerateParam(&p->socket_reused, generator) && - GenerateParam(&p->request_start_time, generator) && - GenerateParam(&p->request_start, generator) && - GenerateParam(&p->proxy_resolve_start, generator) && - GenerateParam(&p->proxy_resolve_end, generator) && - GenerateParam(&p->connect_timing.dns_start, generator) && - GenerateParam(&p->connect_timing.dns_end, generator) && - GenerateParam(&p->connect_timing.connect_start, generator) && - GenerateParam(&p->connect_timing.connect_end, generator) && - GenerateParam(&p->connect_timing.ssl_start, generator) && - GenerateParam(&p->connect_timing.ssl_end, generator) && - GenerateParam(&p->send_start, generator) && - GenerateParam(&p->send_end, generator) && - GenerateParam(&p->receive_headers_end, generator); - } -}; - -template <> -struct GenerateTraits<net::HostPortPair> { - static bool Generate(net::HostPortPair *p, Generator* generator) { - std::string host; - uint16 port; - if (!GenerateParam(&host, generator)) - return false; - if (!GenerateParam(&port, generator)) - return false; - p->set_host(host); - p->set_port(port); - return true; - } -}; - -template <> -struct GenerateTraits<net::IPEndPoint> { - static bool Generate(net::IPEndPoint *p, Generator* generator) { - net::IPAddressNumber address; - int port; - if (!GenerateParam(&address, generator)) - return false; - if (!GenerateParam(&port, generator)) - return false; - net::IPEndPoint ip_endpoint(address, port); - *p = ip_endpoint; - return true; - } -}; - -template <> -struct GenerateTraits<network_hints::LookupRequest> { - static bool Generate(network_hints::LookupRequest* p, Generator* generator) { - network_hints::LookupRequest request; - if (!GenerateParam(&request.hostname_list, generator)) - return false; - *p = request; - return true; - } -}; - -template <> struct GenerateTraits<gfx::Point> { static bool Generate(gfx::Point *p, Generator* generator) { int x; @@ -1286,6 +1231,66 @@ }; template <> +struct GenerateTraits<gpu::Mailbox> { + static bool Generate(gpu::Mailbox* p, Generator* generator) { + generator->GenerateBytes(p->name, sizeof(p->name)); + return true; + } +}; + +template <> +struct GenerateTraits<gpu::MailboxHolder> { + static bool Generate(gpu::MailboxHolder* p, Generator* generator) { + gpu::Mailbox mailbox; + uint32_t texture_target; + uint32_t sync_point; + if (!GenerateParam(&mailbox, generator)) + return false; + if (!GenerateParam(&texture_target, generator)) + return false; + if (!GenerateParam(&sync_point, generator)) + return false; + *p = gpu::MailboxHolder(mailbox, texture_target, sync_point); + return true; + } +}; + +template <> +struct GenerateTraits<gpu::ValueState> { + static bool Generate(gpu::ValueState* p, Generator* generator) { + gpu::ValueState state; + if (!GenerateParamArray(&state.float_value[0], 4, generator)) + return false; + if (!GenerateParamArray(&state.int_value[0], 4, generator)) + return false; + *p = state; + return true; + } +}; + +template <> +struct GenerateTraits<GURL> { + static bool Generate(GURL* p, Generator* generator) { + const char url_chars[] = "Ahtp0:/.?+\\%&#"; + size_t count = RandInRange(100); + std::string random_url; + for (size_t i = 0; i < count; ++i) + random_url += url_chars[RandInRange(sizeof(url_chars) - 1)]; + int selector = RandInRange(10); + if (selector == 0) + random_url = std::string("http://") + random_url; + else if (selector == 1) + random_url = std::string("file://") + random_url; + else if (selector == 2) + random_url = std::string("javascript:") + random_url; + else if (selector == 2) + random_url = std::string("data:") + random_url; + *p = GURL(random_url); + return true; + } +}; + +template <> struct GenerateTraits<IPC::Message> { static bool Generate(IPC::Message *p, Generator* generator) { if (g_function_vector.empty()) @@ -1325,6 +1330,121 @@ } }; +template <> +struct GenerateTraits<media::AudioParameters> { + static bool Generate(media::AudioParameters* p, Generator* generator) { + int format; + int channel_layout; + int sample_rate; + int bits_per_sample; + int frames_per_buffer; + int channels; + int effects; + if (!GenerateParam(&format, generator)) + return false; + if (!GenerateParam(&channel_layout, generator)) + return false; + if (!GenerateParam(&sample_rate, generator)) + return false; + if (!GenerateParam(&bits_per_sample, generator)) + return false; + if (!GenerateParam(&frames_per_buffer, generator)) + return false; + if (!GenerateParam(&channels, generator)) + return false; + if (!GenerateParam(&effects, generator)) + return false; + media::AudioParameters params( + static_cast<media::AudioParameters::Format>(format), + static_cast<media::ChannelLayout>(channel_layout), channels, + sample_rate, bits_per_sample, frames_per_buffer, effects); + *p = params; + return true; + } +}; + +template <> +struct GenerateTraits<media::VideoCaptureFormat> { + static bool Generate(media::VideoCaptureFormat* p, Generator* generator) { + int frame_size_width; + int frame_size_height; + int pixel_format; + if (!GenerateParam(&frame_size_height, generator)) + return false; + if (!GenerateParam(&frame_size_width, generator)) + return false; + if (!GenerateParam(&pixel_format, generator)) + return false; + if (!GenerateParam(&p->frame_rate, generator)) + return false; + p->frame_size.SetSize(frame_size_width, frame_size_height); + p->pixel_format = static_cast<media::VideoPixelFormat>(pixel_format); + return true; + } +}; + +template <> +struct GenerateTraits<net::LoadTimingInfo> { + static bool Generate(net::LoadTimingInfo* p, Generator* generator) { + return GenerateParam(&p->socket_log_id, generator) && + GenerateParam(&p->socket_reused, generator) && + GenerateParam(&p->request_start_time, generator) && + GenerateParam(&p->request_start, generator) && + GenerateParam(&p->proxy_resolve_start, generator) && + GenerateParam(&p->proxy_resolve_end, generator) && + GenerateParam(&p->connect_timing.dns_start, generator) && + GenerateParam(&p->connect_timing.dns_end, generator) && + GenerateParam(&p->connect_timing.connect_start, generator) && + GenerateParam(&p->connect_timing.connect_end, generator) && + GenerateParam(&p->connect_timing.ssl_start, generator) && + GenerateParam(&p->connect_timing.ssl_end, generator) && + GenerateParam(&p->send_start, generator) && + GenerateParam(&p->send_end, generator) && + GenerateParam(&p->receive_headers_end, generator); + } +}; + +template <> +struct GenerateTraits<net::HostPortPair> { + static bool Generate(net::HostPortPair* p, Generator* generator) { + std::string host; + uint16 port; + if (!GenerateParam(&host, generator)) + return false; + if (!GenerateParam(&port, generator)) + return false; + p->set_host(host); + p->set_port(port); + return true; + } +}; + +template <> +struct GenerateTraits<net::IPEndPoint> { + static bool Generate(net::IPEndPoint* p, Generator* generator) { + net::IPAddressNumber address; + int port; + if (!GenerateParam(&address, generator)) + return false; + if (!GenerateParam(&port, generator)) + return false; + net::IPEndPoint ip_endpoint(address, port); + *p = ip_endpoint; + return true; + } +}; + +template <> +struct GenerateTraits<network_hints::LookupRequest> { + static bool Generate(network_hints::LookupRequest* p, Generator* generator) { + network_hints::LookupRequest request; + if (!GenerateParam(&request.hostname_list, generator)) + return false; + *p = request; + return true; + } +}; + // PP_ traits. template <> struct GenerateTraits<PP_Bool> { @@ -1338,6 +1458,15 @@ }; template <> +struct GenerateTraits<PP_KeyInformation> { + static bool Generate(PP_KeyInformation* p, Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = PP_KeyInformation(); + return true; + } +}; + +template <> struct GenerateTraits<PP_NetAddress_Private> { static bool Generate(PP_NetAddress_Private *p, Generator* generator) { p->size = RandInRange(sizeof(p->data) + 1); @@ -1347,6 +1476,25 @@ }; template <> +struct GenerateTraits<ppapi::PPB_X509Certificate_Fields> { + static bool Generate(ppapi::PPB_X509Certificate_Fields* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + return true; + } +}; + +template <> +struct GenerateTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params> { + static bool Generate(ppapi::proxy::PPBFlash_DrawGlyphs_Params* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ppapi::proxy::PPBFlash_DrawGlyphs_Params(); + return true; + } +}; + +template <> struct GenerateTraits<ppapi::proxy::ResourceMessageCallParams> { static bool Generate( ppapi::proxy::ResourceMessageCallParams *p, Generator* generator) { @@ -1386,6 +1534,45 @@ }; template <> +struct GenerateTraits<ppapi::proxy::SerializedHandle> { + static bool Generate(ppapi::proxy::SerializedHandle* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ppapi::proxy::SerializedHandle(); + return true; + } +}; + +template <> +struct GenerateTraits<ppapi::proxy::SerializedFontDescription> { + static bool Generate(ppapi::proxy::SerializedFontDescription* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ppapi::proxy::SerializedFontDescription(); + return true; + } +}; + +template <> +struct GenerateTraits<ppapi::proxy::SerializedTrueTypeFontDesc> { + static bool Generate(ppapi::proxy::SerializedTrueTypeFontDesc* p, + Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ppapi::proxy::SerializedTrueTypeFontDesc(); + return true; + } +}; + +template <> +struct GenerateTraits<ppapi::proxy::SerializedVar> { + static bool Generate(ppapi::proxy::SerializedVar* p, Generator* generator) { + // TODO(mbarbella): This should actually generate something. + *p = ppapi::proxy::SerializedVar(); + return true; + } +}; + +template <> struct GenerateTraits<ppapi::HostResource> { static bool Generate(ppapi::HostResource *p, Generator* generator) { PP_Instance instance; @@ -1466,16 +1653,85 @@ } }; -// FIXME: Actually generate something. template <> struct GenerateTraits<SkBitmap> { static bool Generate(SkBitmap* p, Generator* generator) { + // TODO(mbarbella): This should actually generate something. *p = SkBitmap(); return true; } }; template <> +struct GenerateTraits<storage::DataElement> { + static bool Generate(storage::DataElement* p, Generator* generator) { + switch (RandInRange(4)) { + case storage::DataElement::Type::TYPE_BYTES: { + if (RandEvent(2)) { + p->SetToEmptyBytes(); + } else { + // TODO(mbarbella): Occasionally send more data here. + char data[256]; + int data_len = RandInRange(sizeof(data)); + generator->GenerateBytes(&data[0], data_len); + p->SetToBytes(&data[0], data_len); + } + return true; + } + case storage::DataElement::Type::TYPE_FILE: { + base::FilePath path; + uint64 offset; + uint64 length; + base::Time modification_time; + if (!GenerateParam(&path, generator)) + return false; + if (!GenerateParam(&offset, generator)) + return false; + if (!GenerateParam(&length, generator)) + return false; + if (!GenerateParam(&modification_time, generator)) + return false; + p->SetToFilePathRange(path, offset, length, modification_time); + return true; + } + case storage::DataElement::Type::TYPE_BLOB: { + std::string uuid; + uint64 offset; + uint64 length; + if (!GenerateParam(&uuid, generator)) + return false; + if (!GenerateParam(&offset, generator)) + return false; + if (!GenerateParam(&length, generator)) + return false; + p->SetToBlobRange(uuid, offset, length); + return true; + } + case storage::DataElement::Type::TYPE_FILE_FILESYSTEM: { + GURL url; + uint64 offset; + uint64 length; + base::Time modification_time; + if (!GenerateParam(&url, generator)) + return false; + if (!GenerateParam(&offset, generator)) + return false; + if (!GenerateParam(&length, generator)) + return false; + if (!GenerateParam(&modification_time, generator)) + return false; + p->SetToFileSystemUrlRange(url, offset, length, modification_time); + return true; + } + default: { + NOTREACHED(); + return false; + } + } + } +}; + +template <> struct GenerateTraits<ui::LatencyInfo> { static bool Generate(ui::LatencyInfo* p, Generator* generator) { // TODO(inferno): Add param traits for |latency_components|. @@ -1519,6 +1775,29 @@ }; template <> +struct GenerateTraits<URLPattern> { + static bool Generate(URLPattern* p, Generator* generator) { + int valid_schemes; + std::string host; + std::string port; + std::string path; + if (!GenerateParam(&valid_schemes, generator)) + return false; + if (!GenerateParam(&host, generator)) + return false; + if (!GenerateParam(&port, generator)) + return false; + if (!GenerateParam(&path, generator)) + return false; + *p = URLPattern(valid_schemes); + p->SetHost(host); + p->SetPort(port); + p->SetPath(path); + return true; + } +}; + +template <> struct GenerateTraits<webrtc::DesktopSize> { static bool Generate(webrtc::DesktopSize* p, Generator* generator) { int32_t width; @@ -1566,6 +1845,20 @@ } }; +template <> +struct GenerateTraits<webrtc::MouseCursor> { + static bool Generate(webrtc::MouseCursor* p, Generator* generator) { + webrtc::DesktopVector hotspot; + if (!GenerateParam(&hotspot, generator)) + return false; + // Using a small size here to avoid OOM or overflow on image allocation. + webrtc::DesktopSize size(RandInRange(100), RandInRange(100)); + p->set_image(new webrtc::BasicDesktopFrame(size)); + p->set_hotspot(hotspot); + return true; + } +}; + // Redefine macros to generate generating from traits declarations. // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur. #undef IPC_STRUCT_BEGIN
diff --git a/tools/licenses.py b/tools/licenses.py index 374577f..597dcea 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -237,6 +237,12 @@ "License": "Khronos", "License File": "NOT_SHIPPED", }, + os.path.join('tools', 'telemetry', 'third_party', 'gsutil'): { + "Name": "gsutil", + "URL": "https://cloud.google.com/storage/docs/gsutil", + "License": "Apache 2.0", + "License File": "NOT_SHIPPED", + }, } # Special value for 'License File' field used to indicate that the license file
diff --git a/tools/memory/asan/blacklist_win.txt b/tools/memory/asan/blacklist_win.txt index 75ca1aa..9921509 100644 --- a/tools/memory/asan/blacklist_win.txt +++ b/tools/memory/asan/blacklist_win.txt
@@ -22,7 +22,6 @@ fun:*AutoProtectMemory*sandbox* fun:*EatResolverThunk*sandbox* fun:*InterceptionAgent*sandbox* -fun:*PolicyBase*sandbox* fun:*ResolverThunk*sandbox* fun:*Target*SandboxFactory*sandbox* src:*pe_image.h
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 1abe41b15..7bf2ca5 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -2557,7 +2557,7 @@ <action name="DomDistiller_DistilledPageOpened"> <owner>smaslo@chromium.org</owner> <owner>yfriedman@chromium.org</owner> - <description>User opens a distilled page.</description> + <description>User opens reader mode on a page.</description> </action> <action name="DomDistiller_DistilledPagePrefsOpened"> @@ -7113,6 +7113,24 @@ <description>Please enter the description of this user action.</description> </action> +<action name="ManagedUsers_Whitelist_Added"> + <owner>bauerb@chromium.org</owner> + <owner>treib@chromium.org</owner> + <owner>pam@chromium.org</owner> + <description> + A new whitelist has been installed for a supervised user. + </description> +</action> + +<action name="ManagedUsers_Whitelist_Removed"> + <owner>bauerb@chromium.org</owner> + <owner>treib@chromium.org</owner> + <owner>pam@chromium.org</owner> + <description> + A whitelist has been uninstalled for a supervised user. + </description> +</action> + <action name="MaxButton_Clk_ExitFS"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 3cd2f7f6..1c352d7 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -1803,6 +1803,22 @@ </summary> </histogram> +<histogram name="Autofill.FormEvents.Address" enum="AutofillFormEvent"> + <owner>waltercacau@chromium.org</owner> + <summary> + Autofill form events for address forms. These are recorded when the user + interacts with a form requesting an address. + </summary> +</histogram> + +<histogram name="Autofill.FormEvents.CreditCard" enum="AutofillFormEvent"> + <owner>waltercacau@chromium.org</owner> + <summary> + Autofill form events for credit card forms. These are recorded when the user + interacts with a form requesting a credit card. + </summary> +</histogram> + <histogram name="Autofill.IsEnabled.PageLoad" enum="BooleanEnabled"> <owner>isherman@chromium.org</owner> <summary> @@ -2701,6 +2717,16 @@ </summary> </histogram> +<histogram name="ChromeOS.MemoryPressureLevel" + enum="ChromeOSMemoryPressureLevel"> + <owner>xdai@chromium.org</owner> + <summary> + The memory pressure level in ChromeOS, which is recorded periodically (once + per second). This is used to show the relative frequency of the system being + in a critical vs relaxed memory pressure state. + </summary> +</histogram> + <histogram name="ChromeOS.PlatformVerification.Available" enum="BooleanAvailable"> <owner>dkrahn@chromium.org</owner> @@ -5435,11 +5461,19 @@ </summary> </histogram> -<histogram name="DomDistiller.PageDistillable" enum="BooleanDistillable"> - <owner>yfriedman@chromium.org</owner> +<histogram name="DomDistiller.PageDistillable" enum="DistillableType"> + <owner>cjhopman@chromium.org</owner> <summary> - Records the number of times a page was loaded for which using DomDistiller - is possible. + Records the "Distillable Type" (not distillable, mobile-friendly + distillable, non-mobile-friendly distillable, etc) for each analyzed page. + </summary> +</histogram> + +<histogram name="DomDistiller.PageDistilledType" enum="DistillableType"> + <owner>cjhopman@chromium.org</owner> + <summary> + Records the "Distillable Type" (not distillable, mobile-friendly + distillable, non-mobile-friendly distillable, etc) for each distilled page. </summary> </histogram> @@ -7919,11 +7953,31 @@ </summary> </histogram> +<histogram name="Extensions.BackgroundContentsServiceStartupTime" + units="milliseconds"> + <owner>yoz@chromium.org</owner> + <summary> + Time taken to load BackgroundContents for apps at startup when the extension + system notifies that it is ready. + </summary> +</histogram> + <histogram name="Extensions.BackgroundPageLoadTime" units="milliseconds"> + <obsolete> + Replaced by Extensions.BackgroundPageLoadTime2. + </obsolete> <owner>kalman@chromium.org</owner> <summary>The time for an extension's background page to load.</summary> </histogram> +<histogram name="Extensions.BackgroundPageLoadTime2" units="milliseconds"> + <owner>kalman@chromium.org</owner> + <summary> + The time taken for an extension's persistent background page to load its + initial URL. + </summary> +</histogram> + <histogram name="Extensions.BackgroundPageType" units="ExtensionBackgroundPageType"> <owner>kalman@chromium.org</owner> @@ -8027,6 +8081,9 @@ </histogram> <histogram name="Extensions.DialogLoadTime" units="milliseconds"> + <obsolete> + There is no such thing as an extension dialog. + </obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <summary>The time for a dialog-hosted extension to load.</summary> </histogram> @@ -8154,20 +8211,41 @@ </histogram> <histogram name="Extensions.EventPageActiveTime" units="milliseconds"> + <obsolete> + Replaced by Extensions.EventPageActiveTime2. + </obsolete> <owner>kalman@chromium.org</owner> <summary>The time an extension's event page has spent loaded.</summary> </histogram> +<histogram name="Extensions.EventPageActiveTime2" units="milliseconds"> + <owner>kalman@chromium.org</owner> + <summary> + The time between an extension's event page loading its first URL and the + event page later shutting down. + </summary> +</histogram> + <histogram name="Extensions.EventPageIdleTime" units="milliseconds"> <owner>kalman@chromium.org</owner> <summary>The time an extension's event page has spent unloaded.</summary> </histogram> <histogram name="Extensions.EventPageLoadTime" units="milliseconds"> + <obsolete> + Replaced by Extensions.EventPageLoadTime2. + </obsolete> <owner>kalman@chromium.org</owner> <summary>The time for an extension's event page to load.</summary> </histogram> +<histogram name="Extensions.EventPageLoadTime2" units="milliseconds"> + <owner>kalman@chromium.org</owner> + <summary> + The time taken for an extension's event page to load its initial URL. + </summary> +</histogram> + <histogram name="Extensions.ExtensionCacheCount"> <owner>dpolukhin@chromium.org</owner> <summary> @@ -8965,6 +9043,32 @@ </summary> </histogram> +<histogram name="Extensions.PopupLoadTime" units="milliseconds"> + <obsolete> + Replaced by Extensions.PopupLoadTime2. + </obsolete> + <owner>kalman@chromium.org</owner> + <summary>The time for an Extension's popup to load.</summary> +</histogram> + +<histogram name="Extensions.PopupLoadTime2" units="milliseconds"> + <owner>kalman@chromium.org</owner> + <summary> + The time taken for an extension popup to load its initial URL. This may not + include the time taken for an extension process to start, if the extension + already has a background page running. + </summary> +</histogram> + +<histogram name="Extensions.ProcessManagerStartupHostsTime" + units="milliseconds"> + <owner>yoz@chromium.org</owner> + <summary> + The time taken to start up persistent background pages for extensions in + ExtensionProcessManager when the extension system notifies that it is ready. + </summary> +</histogram> + <histogram name="Extensions.ResourceDirectoryTimestampQueryLatency" units="milliseconds"> <owner>asargent@chromium.org</owner> @@ -9475,6 +9579,9 @@ <histogram name="FileBrowser.HardUnpluggedAroundSuspend.TimeSinceResume" units="milliseconds"> + <obsolete> + The bug which the UMA was investigating got fixed. + </obsolete> <owner>hirono@chromium.org</owner> <summary> Chrome OS File Browser: time from the SuspendDone event to the DiskRemoved @@ -9484,6 +9591,9 @@ <histogram name="FileBrowser.HardUnpluggedAroundSuspend.TimeUntilSuspend" units="milliseconds"> + <obsolete> + The bug which the UMA was investigating got fixed. + </obsolete> <owner>hirono@chromium.org</owner> <summary> Chrome OS File Browser: time from the DiskRemoved event to the Suspend @@ -10856,7 +10966,9 @@ <histogram name="InputMethod.Commit.Type" enum="IMECommitType"> <owner>shuchen@chromium.org</owner> - <summary>The suggestion accuracy type which user chooses to commit.</summary> + <summary> + The suggestion accuracy type which the user chooses to commit. + </summary> </histogram> <histogram name="InputMethod.CommitLength"> @@ -10877,6 +10989,22 @@ <summary>The trigger type of input method switches by user.</summary> </histogram> +<histogram name="InputMethod.PkCommit.Index"> + <owner>shuchen@chromium.org</owner> + <summary> + The suggestion index (1-based) of the suggestion list item which user + chooses to commit for physical keyboard autocorrect. + </summary> +</histogram> + +<histogram name="InputMethod.PkCommit.Type" enum="IMECommitType"> + <owner>shuchen@chromium.org</owner> + <summary> + The suggestion accuracy type which the user chooses to commit for physical + keyboard autocorrect. + </summary> +</histogram> + <histogram name="InputMethod.VirtualKeyboard.BackspaceCount"> <owner>shuchen@chromium.org</owner> <summary> @@ -12186,6 +12314,16 @@ </summary> </histogram> +<histogram name="ManagedUsers.Whitelist.Count" units="whitelists"> + <owner>bauerb@chromium.org</owner> + <owner>treib@chromium.org</owner> + <owner>pam@chromium.org</owner> + <summary> + The number of whitelists installed for a supervised user. Recorded at every + profile startup. + </summary> +</histogram> + <histogram name="ManagedUsers.Whitelist.JsonParseDuration" units="milliseconds"> <owner>bauerb@chromium.org</owner> <owner>treib@chromium.org</owner> @@ -18451,6 +18589,15 @@ </summary> </histogram> +<histogram name="Net.QuicSession.OutOfOrderLargePacketsReceived"> + <owner>rch@chromium.org</owner> + <summary> + The number of times the current received packet had a lower sequence number + than the previously received packet sequence number, and the size of the + current packet is larger than the size of the previous packet. + </summary> +</histogram> + <histogram name="Net.QuicSession.OutOfOrderPacketsReceived"> <owner>rch@chromium.org</owner> <summary> @@ -24990,6 +25137,15 @@ </summary> </histogram> +<histogram name="Platform.TPM.DictionaryAttackResetStatus" + enum="CrosTPMDictionaryAttackResetStatusEnum"> + <owner>dkrahn@chromium.org</owner> + <summary> + Each sample is the status of a periodic attempt to reset the TPM dictionary + attack counter. + </summary> +</histogram> + <histogram name="Platform.TPMForcedReboot" units="reboots"> <owner>dkrahn@chromium.org</owner> <summary> @@ -39929,6 +40085,11 @@ <summary>TBD</summary> </histogram> +<histogram name="V8.CodeCacheSizeRatio" units="percent"> + <owner>yangguo@chromium.org</owner> + <summary>Cache size to source size ratio when caching compiled code.</summary> +</histogram> + <histogram name="V8.CodeCreation"> <obsolete> This histogram is no longer present in V8. @@ -43224,6 +43385,10 @@ <int value="17" label="fp05cc03e1"/> </enum> +<enum name="AutofillFormEvent" type="int"> + <int value="1" label="Interacted once"/> +</enum> + <enum name="AutofillMacAddressBook" type="int"> <int value="0" label="Showed popup entry"/> <int value="1" label="Selected popup entry"/> @@ -43506,11 +43671,6 @@ <int value="1" label="Did fall back"/> </enum> -<enum name="BooleanDistillable" type="int"> - <int value="0" label="Not distillable"/> - <int value="1" label="Distillable"/> -</enum> - <enum name="BooleanDuplicate" type="int"> <int value="0" label="Not Duplicate"/> <int value="1" label="Duplicate"/> @@ -43920,6 +44080,12 @@ <int value="3" label="Reading"/> </enum> +<enum name="ChromeOSMemoryPressureLevel" type="int"> + <int value="0" label="No memory pressure"/> + <int value="1" label="Medium memory pressure"/> + <int value="2" label="High memory pressure"/> +</enum> + <enum name="ChromeOSPlatformVerificationResult" type="int"> <summary> Possible results of a platform verification attempt. See @@ -44578,6 +44744,15 @@ <int value="8" label="PlayMusic"/> </enum> +<enum name="CrosTPMDictionaryAttackResetStatusEnum" type="int"> + <int value="0" label="Reset not necessary"/> + <int value="1" label="Reset attempt succeeded"/> + <int value="2" label="Reset attempt failed"/> + <int value="3" label="TPM owner delegate not allowed to reset"/> + <int value="4" label="TPM owner delegate does not exist"/> + <int value="5" label="Failed to query dictionary attack counter"/> +</enum> + <enum name="CryptohomeError" type="int"> <int value="1" label="TPM returned TPM_E_FAIL"/> <int value="2" label="TCS key load failed"/> @@ -44834,6 +45009,12 @@ <int value="3" label="Primary accounts present but different"/> </enum> +<enum name="DistillableType" type="int"> + <int value="0" label="Not distillable"/> + <int value="1" label="Non-mobile-friendly Distillable"/> + <int value="2" label="Mobile-friendly distillable"/> +</enum> + <enum name="DllHash" type="int"> <!-- Generated by chrome_elf/dll_hash/dll_hash_main.cc --> @@ -47296,6 +47477,7 @@ <int value="954" label="EXTENSIONVIEWINTERNAL_NAVIGATE"/> <int value="955" label="NETWORKING_CONFIG_SETNETWORKFILTER"/> <int value="956" label="NETWORKING_CONFIG_FINISHAUTHENTICATION"/> + <int value="957" label="PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES"/> </enum> <enum name="ExtensionInstallCause" type="int"> @@ -47484,6 +47666,7 @@ <int value="67" label="kU2fDevices"/> <int value="68" label="kDocumentScan"/> <int value="69" label="kNetworkingConfig"/> + <int value="70" label="kPlatformKeys"/> </enum> <enum name="ExtensionServiceVerifyAllSuccess" type="int"> @@ -50807,6 +50990,7 @@ <int value="-1319688939" label="ignore-gpu-blacklist"/> <int value="-1285021473" label="save-page-as-mhtml"/> <int value="-1268836676" label="disable-out-of-process-pdf"/> + <int value="-1267958145" label="disable-pdf-material-ui"/> <int value="-1241747717" label="enable-android-password-link"/> <int value="-1218608640" label="disable-offline-load-stale-cache"/> <int value="-1212273428" label="enable-experimental-app-list"/> @@ -50855,6 +51039,7 @@ <int value="-660160292" label="enable-apps-show-on-first-paint"/> <int value="-649956990" label="enable-harfbuzz-rendertext"/> <int value="-641719457" label="disable-compositor-touch-hit-testing"/> + <int value="-622685174" label="enable-pdf-material-ui"/> <int value="-604814313" label="enable-pinch"/> <int value="-601384286" label="disable-contextual-search"/> <int value="-579192400" label="disable-input-view"/> @@ -50931,8 +51116,10 @@ <int value="360599302" label="enable-gpu-rasterization"/> <int value="365467768" label="prefetch-search-results"/> <int value="370486304" label="enable-origin-chip-on-srp"/> + <int value="400322063" label="ash-disable-screen-orientation-lock"/> <int value="401983950" label="enable-spdy4"/> <int value="402143634" label="enable-search-button-in-omnibox-always"/> + <int value="413081240" label="enable-new-md-input-view"/> <int value="415154056" label="enable-physical-keyboard-autocorrect"/> <int value="423615350" label="enable-tab-audio-muting"/> <int value="446316019" label="enable-threaded-compositing"/> @@ -54213,6 +54400,7 @@ <int value="1681523535" label="PPB_TCPSocket;1.2"/> <int value="1703245231" label="PPB_NetworkList;1.0"/> <int value="1721408268" label="PPB_URLLoader;1.0"/> + <int value="1735606779" label="PPB_VideoEncoder;0.1"/> <int value="1753813390" label="PPB_Flash_Clipboard;4.0"/> <int value="1773992510" label="PPB_PDF;1"/> <int value="1775059283" label="PPB_Flash_FontFile;0.1"/> @@ -59472,6 +59660,16 @@ <affected-histogram name="Renderer4.StartToFinish"/> </histogram_suffixes> +<histogram_suffixes name="AutofillDataAvailability"> + <suffix name="WithNoData" label="no autofill data"/> + <suffix name="WithOnlyServerData" label="only server autofill data"/> + <suffix name="WithOnlyLocalData" label="only local autofill data"/> + <suffix name="WithBothServerAndLocalData" + label="both server and local autofill data"/> + <affected-histogram name="Autofill.FormEvents.Address"/> + <affected-histogram name="Autofill.FormEvents.CreditCard"/> +</histogram_suffixes> + <histogram_suffixes name="AutofillServerExperiments"> <suffix name="ar06" label="Acceptance ratio: 0.6"/> <suffix name="ar1" label="Acceptance ratio: 1.0"/>
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 0543986..9268f30 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -168,6 +168,7 @@ return CreatePageSetFromPath(path, SKIPPED_FILE) +@benchmark.Disabled('win') # crbug.com/455796 class BlinkPerfCanvas(benchmark.Benchmark): tag = 'canvas' test = _BlinkPerfMeasurement
diff --git a/tools/perf/benchmarks/tab_switching.py b/tools/perf/benchmarks/tab_switching.py index e51236c..138555a 100644 --- a/tools/perf/benchmarks/tab_switching.py +++ b/tools/perf/benchmarks/tab_switching.py
@@ -44,6 +44,7 @@ return 'tab_switching.typical_25' +@benchmark.Disabled('mac') # http://crbug.com/455349 @benchmark.Enabled('has tabs') class TabSwitchingFiveBlankTabs(benchmark.Benchmark): """This test records the MPArch.RWH_TabSwitchPaintDuration histogram.
diff --git a/tools/perf/measurements/rasterize_and_record_micro.py b/tools/perf/measurements/rasterize_and_record_micro.py index 3523a7b..f278ff6 100644 --- a/tools/perf/measurements/rasterize_and_record_micro.py +++ b/tools/perf/measurements/rasterize_and_record_micro.py
@@ -83,14 +83,24 @@ picture_memory_usage)) results.AddValue(scalar.ScalarValue( results.current_page, 'record_time', 'ms', record_time)) + record_time_sk_null_canvas = data['record_time_sk_null_canvas_ms'] record_time_painting_disabled = data['record_time_painting_disabled_ms'] + # TODO(schenney): Remove this workaround when reference builds get past + # the change that adds this comment. + if ('record_time_caching_disabled_ms' in data): + record_time_caching_disabled = data['record_time_caching_disabled_ms'] + else: + record_time_caching_disabled = 0 results.AddValue(scalar.ScalarValue( results.current_page, 'record_time_sk_null_canvas', 'ms', record_time_sk_null_canvas)) results.AddValue(scalar.ScalarValue( results.current_page, 'record_time_painting_disabled', 'ms', record_time_painting_disabled)) + results.AddValue(scalar.ScalarValue( + results.current_page, 'record_time_caching_disabled', 'ms', + record_time_caching_disabled)) if self._report_detailed_results: pixels_rasterized_with_non_solid_color = \
diff --git a/tools/perf/metrics/keychain_metric.py b/tools/perf/metrics/keychain_metric.py index 5657dfe..a2c89fa9 100644 --- a/tools/perf/metrics/keychain_metric.py +++ b/tools/perf/metrics/keychain_metric.py
@@ -2,9 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import logging import sys from metrics import Metric +from telemetry.util.mac import keychain_helper from telemetry.value import histogram_util from telemetry.value import scalar @@ -18,6 +20,36 @@ DISPLAY_NAME = 'OSX_Keychain_Access' HISTOGRAM_NAME = 'OSX.Keychain.Access' + @staticmethod + def _CheckKeychainConfiguration(): + """ + On OSX, it is possible for a misconfigured keychain to cause the + Telemetry tests to stall. This method confirms that the keychain is in a + sane state that will not cause this behavior. Three conditions are checked: + - The keychain is unlocked. + - The keychain will not auto-lock after a period of time. + - The ACLs are correctly configured on the relevant keychain items. + """ + warning_suffix = ('which will cause some Telemetry tests to stall when run' + ' on a headless machine (e.g. perf bot).') + if keychain_helper.IsKeychainLocked(): + logging.warning('The default keychain is locked, %s', warning_suffix) + + if keychain_helper.DoesKeychainHaveTimeout(): + logging.warning('The default keychain is configured to automatically' + ' lock itself have a period of time, %s', warning_suffix) + + chrome_acl_configured = (keychain_helper. + IsKeychainConfiguredForBotsWithChrome()) + chromium_acl_configured = (keychain_helper. + IsKeychainConfiguredForBotsWithChromium()) + acl_warning = ('A commonly used %s key stored in the default keychain does' + ' not give decryption access to all applications, %s') + if not chrome_acl_configured: + logging.warning(acl_warning, 'Chrome', warning_suffix) + if not chromium_acl_configured: + logging.warning(acl_warning, 'Chromium', warning_suffix) + @classmethod def CustomizeBrowserOptions(cls, options): """Adds a browser argument that allows for the collection of keychain @@ -25,6 +57,8 @@ if sys.platform != 'darwin': return + KeychainMetric._CheckKeychainConfiguration() + options.AppendExtraBrowserArgs(['--enable-stats-collection-bindings']) def AddResults(self, tab, results):
diff --git a/tools/perf/page_sets/key_mobile_sites_smooth.py b/tools/perf/page_sets/key_mobile_sites_smooth.py index 36178c5..18d12259 100644 --- a/tools/perf/page_sets/key_mobile_sites_smooth.py +++ b/tools/perf/page_sets/key_mobile_sites_smooth.py
@@ -24,14 +24,19 @@ class KeyMobileSitesSmoothPage(page_module.Page): - def __init__(self, url, page_set, name='', labels=None): + def __init__(self, url, page_set, name='', labels=None, + action_on_load_complete=False): super(KeyMobileSitesSmoothPage, self).__init__( url=url, page_set=page_set, name=name, credentials_path='data/credentials.json', labels=labels) self.user_agent_type = 'mobile' self.archive_data_file = 'data/key_mobile_sites.json' + self.action_on_load_complete = action_on_load_complete def RunPageInteractions(self, action_runner): + if self.action_on_load_complete: + action_runner.WaitForJavaScriptCondition( + 'document.readyState == "complete"', 30) _IssueMarkerAndScroll(action_runner) @@ -166,12 +171,18 @@ page_set=self, name='Wordpress')) - # Why: #6 (Alexa) most visited worldwide, picked an interesting page + # Why: #6 (Alexa) most visited worldwide, picked an interesting page self.AddUserStory(KeyMobileSitesSmoothPage( url='http://en.wikipedia.org/wiki/Wikipedia', page_set=self, name='Wikipedia (1 tab)')) + # Why: Wikipedia page with a delayed scroll start + self.AddUserStory(KeyMobileSitesSmoothPage( + url='http://en.wikipedia.org/wiki/Wikipedia', + page_set=self, + name='Wikipedia (1 tab) - delayed scroll start', + action_on_load_complete=True)) # Why: #8 (Alexa global), picked an interesting page # Forbidden (Rate Limit Exceeded)
diff --git a/tools/perf_expectations/perf_expectations.json b/tools/perf_expectations/perf_expectations.json index c479ba8c..8da8935 100644 --- a/tools/perf_expectations/perf_expectations.json +++ b/tools/perf_expectations/perf_expectations.json
@@ -4,7 +4,7 @@ "linux-release-64/sizes/chrome-text/text": {"reva": 314576, "revb": 314597, "type": "absolute", "better": "lower", "improve": 99684402, "regress": 110179552, "sha1": "dd896f5d"}, "linux-release-64/sizes/chrome/chrome": {"reva": 314576, "revb": 314597, "type": "absolute", "better": "lower", "improve": 144357447, "regress": 159558118, "sha1": "dd048ccd"}, "linux-release-64/sizes/nacl_helper-bss/bss": {"reva": 282247, "revb": 282247, "type": "absolute", "better": "lower", "improve": 257670, "regress": 284794, "sha1": "4baf0f5e"}, - "linux-release-64/sizes/nacl_helper-data/data": {"reva": 299377, "revb": 299377, "type": "absolute", "better": "lower", "improve": 209098, "regress": 231110, "sha1": "9d7262fa"}, + "linux-release-64/sizes/nacl_helper-data/data": {"reva": 315014, "revb": 315022, "type": "absolute", "better": "lower", "improve": 220172, "regress": 243348, "sha1": "7b14efc5"}, "linux-release-64/sizes/nacl_helper-si/initializers": {"reva": 271321, "revb": 271321, "type": "absolute", "better": "lower", "improve": 5, "regress": 7, "sha1": "f29296a1"}, "linux-release-64/sizes/nacl_helper-text/text": {"reva": 308775, "revb": 308775, "type": "absolute", "better": "lower", "improve": 5944151, "regress": 6569853, "sha1": "1c60058b"}, "linux-release-64/sizes/nacl_helper/nacl_helper": {"reva": 308775, "revb": 308775, "type": "absolute", "better": "lower", "improve": 8146212, "regress": 9003708, "sha1": "c059ee1f"}, @@ -370,11 +370,11 @@ "linux-release/sizes/chrome/chrome": {"reva": 314576, "revb": 314590, "type": "absolute", "better": "lower", "improve": 138826666, "regress": 153444353, "sha1": "943c4b9d"}, "linux-release/sizes/libffmpegsumo.so-textrel/textrel": {"reva": 200467, "revb": 203456, "type": "absolute", "better": "lower", "improve": 1075, "regress": 1189, "sha1": "a10d4ea4"}, "linux-release/sizes/nacl_helper-bss/bss": {"reva": 282247, "revb": 282247, "type": "absolute", "better": "lower", "improve": 143640, "regress": 158760, "sha1": "95c4c516"}, - "linux-release/sizes/nacl_helper-data/data": {"reva": 299377, "revb": 299377, "type": "absolute", "better": "lower", "improve": 107384, "regress": 118688, "sha1": "2e0b5d0c"}, + "linux-release/sizes/nacl_helper-data/data": {"reva": 315014, "revb": 315022, "type": "absolute", "better": "lower", "improve": 113042, "regress": 124942, "sha1": "d4f92fae"}, "linux-release/sizes/nacl_helper-si/initializers": {"reva": 271321, "revb": 271321, "type": "absolute", "better": "lower", "improve": 6, "regress": 8, "sha1": "3394be7f"}, - "linux-release/sizes/nacl_helper-text/text": {"reva": 294959, "revb": 295013, "type": "absolute", "better": "lower", "improve": 5237667, "regress": 5796135, "sha1": "56cafa68"}, + "linux-release/sizes/nacl_helper-text/text": {"reva": 314720, "revb": 314730, "type": "absolute", "better": "lower", "improve": 5490160, "regress": 6068328, "sha1": "d97ac1ae"}, "linux-release/sizes/nacl_helper-textrel/textrel": {"reva": 264283, "revb": 264283, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "sha1": "0efaa99f"}, - "linux-release/sizes/nacl_helper/nacl_helper": {"reva": 294959, "revb": 295013, "type": "absolute", "better": "lower", "improve": 6996604, "regress": 7742223, "sha1": "085c3df8"}, + "linux-release/sizes/nacl_helper/nacl_helper": {"reva": 314720, "revb": 314730, "type": "absolute", "better": "lower", "improve": 7294860, "regress": 8062740, "sha1": "804bb0b4"}, "linux-release/sizes/nacl_helper_bootstrap-bss/bss": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 1019980807, "regress": 1127347209, "sha1": "a4ff54ab"}, "linux-release/sizes/nacl_helper_bootstrap-data/data": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 19, "regress": 21, "sha1": "6a3e92f4"}, "linux-release/sizes/nacl_helper_bootstrap-si/initializers": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "sha1": "dd908f29"}, @@ -739,6 +739,6 @@ "xp-release/sizes/chrome.exe/chrome.exe": {"reva": 309071, "revb": 309081, "type": "absolute", "better": "lower", "improve": 612377, "regress": 676839, "sha1": "63dbfdc5"}, "xp-release/sizes/chrome_child.dll/chrome_child.dll": {"reva": 314576, "revb": 314588, "type": "absolute", "better": "lower", "improve": 39555993, "regress": 43720858, "sha1": "46896665"}, "xp-release/sizes/mini_installer.exe/mini_installer.exe": {"reva": 296771, "revb": 296791, "type": "absolute", "better": "lower", "improve": 32967219, "regress": 36469709, "sha1": "f4744be2"}, - "xp-release/sizes/setup.exe/setup.exe": {"reva": 309071, "revb": 309081, "type": "absolute", "better": "lower", "improve": 933888, "regress": 1032192, "sha1": "a257fcad"}, + "xp-release/sizes/setup.exe/setup.exe": {"reva": 314972, "revb": 314998, "type": "absolute", "better": "lower", "improve": 882816, "regress": 975744, "sha1": "682290df"}, "load": true }
diff --git a/tools/profile_chrome/chrome_startup_controller.py b/tools/profile_chrome/chrome_startup_controller.py index d685502..87353e3 100644 --- a/tools/profile_chrome/chrome_startup_controller.py +++ b/tools/profile_chrome/chrome_startup_controller.py
@@ -7,6 +7,7 @@ import time from pylib import flag_changer +from pylib.device import intent from pylib.perf import cache_control from profile_chrome import controllers @@ -39,7 +40,7 @@ package=self._package_info.package, activity=self._package_info.activity, data=self._url, - extras={'create_new_tab' : True})) + extras={'create_new_tab' : True}), blocking=True) def _TearDownTracing(self): changer = flag_changer.FlagChanger(
diff --git a/tools/telemetry/bin/mac/x86_64/determine_if_keychain_entry_is_decryptable.sha1 b/tools/telemetry/bin/mac/x86_64/determine_if_keychain_entry_is_decryptable.sha1 new file mode 100644 index 0000000..171728c --- /dev/null +++ b/tools/telemetry/bin/mac/x86_64/determine_if_keychain_entry_is_decryptable.sha1
@@ -0,0 +1 @@ +5daabb8e5d485a99efc9139634a8242fa60a25e7 \ No newline at end of file
diff --git a/tools/telemetry/bin/mac/x86_64/determine_if_keychain_is_locked.sha1 b/tools/telemetry/bin/mac/x86_64/determine_if_keychain_is_locked.sha1 new file mode 100644 index 0000000..367fde5 --- /dev/null +++ b/tools/telemetry/bin/mac/x86_64/determine_if_keychain_is_locked.sha1
@@ -0,0 +1 @@ +13a57efae9a680ac0f160b3567e02e81f4ac493c \ No newline at end of file
diff --git a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_backend.py b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_backend.py index ede50781..ec566b79 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_backend.py +++ b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_backend.py
@@ -7,6 +7,7 @@ import logging import os import os.path +import re import shutil import subprocess as subprocess import sys @@ -262,7 +263,13 @@ return None output = subprocess.check_output([cdb, '-y', self._browser_directory, '-c', '.ecxr;k30;q', '-z', minidump]) - stack_start = output.find('ChildEBP') + # cdb output can start the stack with "ChildEBP", "Child-SP", and possibly + # other things we haven't seen yet. If we can't find the start of the + # stack, include output from the beginning. + stack_start = 0 + stack_start_match = re.search("^Child(?:EBP|-SP)", output, re.MULTILINE) + if stack_start_match: + stack_start = stack_start_match.start() stack_end = output.find('quit:') return output[stack_start:stack_end]
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/devtools_client_backend_unittest.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/devtools_client_backend_unittest.py index 1a4d10c..64ba2c89 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/devtools_client_backend_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/devtools_client_backend_unittest.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from telemetry import decorators from telemetry.core.backends.chrome_inspector import devtools_client_backend from telemetry.core.backends.chrome_inspector import devtools_http from telemetry.unittest_util import browser_test_case @@ -24,6 +25,7 @@ def testIsAlive(self): self.assertTrue(self._devtools_client.IsAlive()) + @decorators.Enabled('has tabs') def testGetUpdatedInspectableContexts(self): self._browser.tabs.New() c1 = self._devtools_client.GetUpdatedInspectableContexts()
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py index 338f13a8..8a4003d2 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py
@@ -14,13 +14,11 @@ from telemetry.core.backends.chrome_inspector import inspector_network from telemetry.core.backends.chrome_inspector import inspector_page from telemetry.core.backends.chrome_inspector import inspector_runtime -from telemetry.core.backends.chrome_inspector import inspector_timeline from telemetry.core.backends.chrome_inspector import inspector_websocket from telemetry.core.backends.chrome_inspector import websocket from telemetry.core.heap import model as heap_model_module from telemetry.image_processing import image_util from telemetry.timeline import model as timeline_model_module -from telemetry.timeline import recording_options from telemetry.timeline import trace_data as trace_data_module @@ -53,7 +51,6 @@ self._page = inspector_page.InspectorPage( self._websocket, timeout=timeout) self._runtime = inspector_runtime.InspectorRuntime(self._websocket) - self._timeline = inspector_timeline.InspectorTimeline(self._websocket) self._network = inspector_network.InspectorNetwork(self._websocket) self._timeline_model = None @@ -179,34 +176,17 @@ def timeline_model(self): return self._timeline_model - def StartTimelineRecording(self, options=None): - if not options: - options = recording_options.TimelineRecordingOptions() - if options.record_timeline: - self._timeline.Start() - if options.record_network: - self._network.timeline_recorder.Start() + def StartTimelineRecording(self): + self._network.timeline_recorder.Start() def StopTimelineRecording(self): builder = trace_data_module.TraceDataBuilder() - data = self._timeline.Stop() - if data: - builder.AddEventsTo(trace_data_module.INSPECTOR_TRACE_PART, data) - data = self._network.timeline_recorder.Stop() if data: builder.AddEventsTo(trace_data_module.INSPECTOR_TRACE_PART, data) - - if builder.HasEventsFor(trace_data_module.INSPECTOR_TRACE_PART): - self._timeline_model = timeline_model_module.TimelineModel( - builder.AsData(), shift_world_to_zero=False) - else: - self._timeline_model = None - - @property - def is_timeline_recording_running(self): - return self._timeline.is_timeline_recording_running + self._timeline_model = timeline_model_module.TimelineModel( + builder.AsData(), shift_world_to_zero=False) # Network public methods.
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network.py index 0335d305..5b7b3e8 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network.py
@@ -4,7 +4,6 @@ import logging from telemetry.core import util -from telemetry.core.backends.chrome_inspector import timeline_recorder class InspectorNetworkException(Exception): @@ -210,9 +209,8 @@ return self._timeline_recorder -class TimelineRecorder(timeline_recorder.TimelineRecorder): +class TimelineRecorder(object): def __init__(self, inspector_network): - super(TimelineRecorder, self).__init__() self._inspector_network = inspector_network self._is_recording = False
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py index 7b7bd9d..af94122 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py
@@ -4,16 +4,13 @@ from telemetry import decorators from telemetry.core.backends.chrome_inspector import inspector_network -from telemetry.timeline import recording_options from telemetry.unittest_util import tab_test_case class InspectorNetworkTabTest(tab_test_case.TabTestCase): class TestCase(object): - def __init__(self, monitoring=False, responses_count=0, + def __init__(self, responses_count=0, subresources=None): - # Whether to monitor network for this case. - self.monitoring = monitoring # Number of responses expected for this case. self.responses_count = responses_count # List of subresource links for this case. @@ -22,10 +19,8 @@ def __init__(self, *args): super(InspectorNetworkTabTest, self).__init__(*args) - def _NavigateAndGetHTTPResponseEvents(self, page, record_network=True): - opts = recording_options.TimelineRecordingOptions() - opts.record_network = record_network - self._tab.StartTimelineRecording(opts) + def _NavigateAndGetHTTPResponseEvents(self, page): + self._tab.StartTimelineRecording() self.Navigate(page) self._tab.StopTimelineRecording() @@ -36,17 +31,14 @@ @decorators.Disabled('mac', 'android', 'win') def testHTTPResponseTimelineRecorder(self): tests = { - 'blank.html': InspectorNetworkTabTest.TestCase(), - 'green_rect.html': InspectorNetworkTabTest.TestCase( - monitoring=True, responses_count=1), + 'blank.html': InspectorNetworkTabTest.TestCase(responses_count=1), + 'green_rect.html': InspectorNetworkTabTest.TestCase(responses_count=1), 'image_decoding.html': InspectorNetworkTabTest.TestCase( - monitoring=True, responses_count=2, subresources=['image.png']), + responses_count=2, subresources=['image.png']), } for page, test in tests.iteritems(): - events = self._NavigateAndGetHTTPResponseEvents(page, test.monitoring) + events = self._NavigateAndGetHTTPResponseEvents(page) self.assertEqual(test.responses_count, len(events)) - if not test.monitoring: - continue # Verify required event fields for event in events:
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline.py deleted file mode 100644 index 9289f26..0000000 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline.py +++ /dev/null
@@ -1,109 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from telemetry.core.backends.chrome_inspector import timeline_recorder - - -class TabBackendException(Exception): - """An exception which indicates an error response from devtools inspector.""" - pass - - -class InspectorTimeline(timeline_recorder.TimelineRecorder): - """Implementation of dev tools timeline.""" - - class Recorder(object): - """Utility class to Start and Stop recording timeline. - - Example usage: - - with inspector_timeline.InspectorTimeline.Recorder(tab): - # Something to run while the timeline is recording. - - This is an alternative to directly calling the Start and Stop methods below. - """ - def __init__(self, tab): - self._tab = tab - - def __enter__(self): - self._tab.StartTimelineRecording() - - def __exit__(self, *args): - self._tab.StopTimelineRecording() - - def __init__(self, inspector_websocket): - super(InspectorTimeline, self).__init__() - self._inspector_websocket = inspector_websocket - self._is_recording = False - self._raw_events = None - - @property - def is_timeline_recording_running(self): - return self._is_recording - - def Start(self): - """Starts recording.""" - assert not self._is_recording, 'Start should only be called once.' - self._raw_events = None - self._is_recording = True - self._inspector_websocket.RegisterDomain( - 'Timeline', self._OnNotification, self._OnClose) - # The 'bufferEvents' parameter below means that events should not be sent - # individually as messages, but instead all at once when a Timeline.stop - # request is sent. - request = { - 'method': 'Timeline.start', - 'params': {'bufferEvents': True}, - } - self._SendSyncRequest(request) - - def Stop(self): - """Stops recording and returns timeline event data.""" - if not self._is_recording: - return None - request = {'method': 'Timeline.stop'} - result = self._SendSyncRequest(request) - self._inspector_websocket.UnregisterDomain('Timeline') - self._is_recording = False - - # TODO: Backward compatibility. Needs to be removed when - # M38 becomes stable. - if 'events' in result: - raw_events = result['events'] - else: # In M38 events will arrive via Timeline.stopped event. - raw_events = self._raw_events - self._raw_events = None - return raw_events - - def _SendSyncRequest(self, request, timeout=60): - """Sends a devtools remote debugging protocol request. - - The types of request that are valid is determined by protocol.json: - https://src.chromium.org/viewvc/blink/trunk/Source/devtools/protocol.json - - Args: - request: Request dict, may contain the keys 'method' and 'params'. - timeout: Number of seconds to wait for a response. - - Returns: - The result given in the response message. - - Raises: - TabBackendException: The response indicates an error occurred. - """ - response = self._inspector_websocket.SyncRequest(request, timeout) - if 'error' in response: - raise TabBackendException(response['error']['message']) - return response['result'] - - def _OnNotification(self, msg): - """Handler called when a message is received.""" - # Since 'Timeline.start' was invoked with the 'bufferEvents' parameter, - # the events will arrive in Timeline.stopped event. - if msg['method'] == 'Timeline.stopped' and 'events' in msg['params']: - self._raw_events = msg['params']['events'] - - def _OnClose(self): - """Handler called when a domain is unregistered.""" - pass
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline_unittest.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline_unittest.py deleted file mode 100644 index f653b9c1..0000000 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_timeline_unittest.py +++ /dev/null
@@ -1,41 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from telemetry.core import util -from telemetry.core.backends.chrome_inspector import inspector_timeline -from telemetry.unittest_util import tab_test_case - - -class InspectorTimelineTabTest(tab_test_case.TabTestCase): - """Test case that opens a browser and creates and then checks an event.""" - - def _WaitForAnimationFrame(self): - """Wait until the variable window.done is set on the tab.""" - def _IsDone(): - return bool(self._tab.EvaluateJavaScript('window.done')) - util.WaitFor(_IsDone, 5) - - def testGotTimeline(self): - # While the timeline is recording, call window.webkitRequestAnimationFrame. - # This will create a FireAnimationEvent, which can be checked below. See: - # https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame - with inspector_timeline.InspectorTimeline.Recorder(self._tab): - self._tab.ExecuteJavaScript( - """ - var done = false; - function sleep(ms) { - var endTime = (new Date().getTime()) + ms; - while ((new Date().getTime()) < endTime); - } - window.webkitRequestAnimationFrame(function() { - sleep(10); - window.done = true; - }); - """) - self._WaitForAnimationFrame() - - # There should be at least a FireAnimationFrame record with some duration. - events = self._tab.timeline_model.GetAllEventsOfName('FireAnimationFrame') - self.assertTrue(len(events) > 0) - self.assertTrue(events[0].duration > 0)
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/timeline_recorder.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/timeline_recorder.py deleted file mode 100644 index 7700ab1..0000000 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/timeline_recorder.py +++ /dev/null
@@ -1,13 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -class TimelineRecorder(object): - """Interface for classes that can record timeline raw events.""" - def Start(self): - """Starts recording.""" - raise NotImplementedError - - def Stop(self): - """Stops recording and returns timeline event data.""" - raise NotImplementedError
diff --git a/tools/telemetry/telemetry/core/platform/__init__.py b/tools/telemetry/telemetry/core/platform/__init__.py index a4cb604..1421d60 100644 --- a/tools/telemetry/telemetry/core/platform/__init__.py +++ b/tools/telemetry/telemetry/core/platform/__init__.py
@@ -128,6 +128,12 @@ Examples: VISTA, WIN7, LION, MOUNTAINLION""" return self._platform_backend.GetOSVersionName() + def GetOSVersionNumber(self): + """Returns an integer description of the Platform OS major version. + + Examples: On Mac, 13 for Mavericks, 14 for Yosemite.""" + return self._platform_backend.GetOSVersionNumber() + def CanFlushIndividualFilesFromSystemCache(self): """Returns true if the disk cache can be flushed for specific files.""" return self._platform_backend.CanFlushIndividualFilesFromSystemCache()
diff --git a/tools/telemetry/telemetry/core/tab_unittest.py b/tools/telemetry/telemetry/core/tab_unittest.py index b7bd190..7109156 100644 --- a/tools/telemetry/telemetry/core/tab_unittest.py +++ b/tools/telemetry/telemetry/core/tab_unittest.py
@@ -83,13 +83,6 @@ self._tab.Navigate(url) self.assertEquals(self._tab.url, url) - def testIsTimelineRecordingRunningTab(self): - self.assertFalse(self._tab.is_timeline_recording_running) - self._tab.StartTimelineRecording() - self.assertTrue(self._tab.is_timeline_recording_running) - self._tab.StopTimelineRecording() - self.assertFalse(self._tab.is_timeline_recording_running) - #pylint: disable=W0212 def testIsVideoCaptureRunning(self): original_platform_backend = self._tab.browser._platform_backend
diff --git a/tools/telemetry/telemetry/core/web_contents.py b/tools/telemetry/telemetry/core/web_contents.py index 05475c5..fe790ad1 100644 --- a/tools/telemetry/telemetry/core/web_contents.py +++ b/tools/telemetry/telemetry/core/web_contents.py
@@ -167,12 +167,8 @@ def timeline_model(self): return self._inspector_backend.timeline_model - def StartTimelineRecording(self, options=None): - self._inspector_backend.StartTimelineRecording(options) - - @property - def is_timeline_recording_running(self): - return self._inspector_backend.is_timeline_recording_running + def StartTimelineRecording(self): + self._inspector_backend.StartTimelineRecording() def StopTimelineRecording(self): self._inspector_backend.StopTimelineRecording()
diff --git a/tools/telemetry/telemetry/page/page_run_end_to_end_unittest.py b/tools/telemetry/telemetry/page/page_run_end_to_end_unittest.py index 4d14b0a..fcfb549 100644 --- a/tools/telemetry/telemetry/page/page_run_end_to_end_unittest.py +++ b/tools/telemetry/telemetry/page/page_run_end_to_end_unittest.py
@@ -3,10 +3,8 @@ # found in the LICENSE file. import os -import tempfile import unittest import shutil -import sys import tempfile from telemetry import benchmark @@ -24,8 +22,7 @@ from telemetry.unittest_util import system_stub from telemetry.user_story import user_story_runner from telemetry.util import exception_formatter as exception_formatter_module -from telemetry.value import scalar -from telemetry.value import string +from unittest_data.page_sets import example_domain # pylint: disable=bad-super-call @@ -116,7 +113,8 @@ class Test(page_test.PageTest): def __init__(self, *args): - super(Test, self).__init__(*args) + super(Test, self).__init__( + *args, needs_browser_restart_after_each_page=True) self.run_count = 0 def RestartBrowserBeforeEachPage(self): @@ -529,3 +527,26 @@ with self.assertRaises(page_test.MultiTabTestAppCrashError): self._RunPageTestThatRaisesAppCrashException(test, max_failures=1) + def testWebPageReplay(self): + ps = example_domain.ExampleDomainPageSet() + expectations = test_expectations.TestExpectations() + body = [] + class TestWpr(page_test.PageTest): + def ValidateAndMeasurePage(self, _, tab, __): + body.append(tab.EvaluateJavaScript('document.body.innerText')) + test = TestWpr() + options = options_for_unittests.GetCopy() + options.output_formats = ['none'] + options.suppress_gtest_report = True + SetUpUserStoryRunnerArguments(options) + results = results_options.CreateResults(EmptyMetadataForTest(), options) + + user_story_runner.Run(test, ps, expectations, options, results) + + self.longMessage = True + self.assertIn('Example Domain', body[0], msg='URL: %s' % ps.pages[0].url) + self.assertIn('Example Domain', body[1], msg='URL: %s' % ps.pages[1].url) + + self.assertEquals(2, len(GetSuccessfulPageRuns(results))) + self.assertEquals(0, len(results.failures)) +
diff --git a/tools/telemetry/telemetry/timeline/recording_options.py b/tools/telemetry/telemetry/timeline/recording_options.py deleted file mode 100644 index a8c7e145..0000000 --- a/tools/telemetry/telemetry/timeline/recording_options.py +++ /dev/null
@@ -1,9 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - - -class TimelineRecordingOptions(object): - def __init__(self): - self.record_timeline = True - self.record_network = False
diff --git a/tools/telemetry/telemetry/user_story/user_story_runner.py b/tools/telemetry/telemetry/user_story/user_story_runner.py index ad9dde0b..8d489ad 100644 --- a/tools/telemetry/telemetry/user_story/user_story_runner.py +++ b/tools/telemetry/telemetry/user_story/user_story_runner.py
@@ -211,7 +211,7 @@ # Reorder page set based on options. user_stories = _ShuffleAndFilterUserStorySet(user_story_set, finder_options) - if (not finder_options.use_live_sites and + if (not finder_options.use_live_sites and user_story_set.bucket and finder_options.browser_options.wpr_mode != wpr_modes.WPR_RECORD): _UpdateUserStoryArchivesIfChanged(user_story_set) if not _UpdateAndCheckArchives(
diff --git a/tools/telemetry/telemetry/user_story/user_story_runner_unittest.py b/tools/telemetry/telemetry/user_story/user_story_runner_unittest.py index eed754f..6c5b8a6 100644 --- a/tools/telemetry/telemetry/user_story/user_story_runner_unittest.py +++ b/tools/telemetry/telemetry/user_story/user_story_runner_unittest.py
@@ -23,6 +23,7 @@ from telemetry.value import scalar from telemetry.value import string from telemetry.web_perf import timeline_based_measurement +from telemetry.wpr import archive_info # This linter complains if we define classes nested inside functions. # pylint: disable=bad-super-call @@ -440,54 +441,60 @@ self.assertIn('*RESULT metric: metric= [1,2,3,4] unit', contents) def testUpdateAndCheckArchives(self): - uss = user_story_set.UserStorySet() - uss.AddUserStory(page_module.Page( - 'http://www.testurl.com', uss, uss.base_dir)) - # Page set missing archive_data_file. - self.assertRaises( - user_story_runner.ArchiveError, - user_story_runner._UpdateAndCheckArchives, - uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) + usr_stub = system_stub.Override(user_story_runner, ['cloud_storage']) + wpr_stub = system_stub.Override(archive_info, ['cloud_storage']) + try: + uss = user_story_set.UserStorySet() + uss.AddUserStory(page_module.Page( + 'http://www.testurl.com', uss, uss.base_dir)) + # Page set missing archive_data_file. + self.assertRaises( + user_story_runner.ArchiveError, + user_story_runner._UpdateAndCheckArchives, + uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) - uss = user_story_set.UserStorySet( - archive_data_file='missing_archive_data_file.json') - uss.AddUserStory(page_module.Page( - 'http://www.testurl.com', uss, uss.base_dir)) - # Page set missing json file specified in archive_data_file. - self.assertRaises( - user_story_runner.ArchiveError, - user_story_runner._UpdateAndCheckArchives, - uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) + uss = user_story_set.UserStorySet( + archive_data_file='missing_archive_data_file.json') + uss.AddUserStory(page_module.Page( + 'http://www.testurl.com', uss, uss.base_dir)) + # Page set missing json file specified in archive_data_file. + self.assertRaises( + user_story_runner.ArchiveError, + user_story_runner._UpdateAndCheckArchives, + uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) - uss = user_story_set.UserStorySet( - archive_data_file='../../unittest_data/archive_files/test.json', - cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET) - uss.AddUserStory(page_module.Page( - 'http://www.testurl.com', uss, uss.base_dir)) - # Page set with valid archive_data_file. - self.assertTrue(user_story_runner._UpdateAndCheckArchives( - uss.archive_data_file, uss.wpr_archive_info, uss.user_stories)) - uss.AddUserStory(page_module.Page( - 'http://www.google.com', uss, uss.base_dir)) - # Page set with an archive_data_file which exists but is missing a page. - self.assertRaises( - user_story_runner.ArchiveError, - user_story_runner._UpdateAndCheckArchives, - uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) + uss = user_story_set.UserStorySet( + archive_data_file='../../unittest_data/archive_files/test.json', + cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET) + uss.AddUserStory(page_module.Page( + 'http://www.testurl.com', uss, uss.base_dir)) + # Page set with valid archive_data_file. + self.assertTrue(user_story_runner._UpdateAndCheckArchives( + uss.archive_data_file, uss.wpr_archive_info, uss.user_stories)) + uss.AddUserStory(page_module.Page( + 'http://www.google.com', uss, uss.base_dir)) + # Page set with an archive_data_file which exists but is missing a page. + self.assertRaises( + user_story_runner.ArchiveError, + user_story_runner._UpdateAndCheckArchives, + uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) - uss = user_story_set.UserStorySet( - archive_data_file='../../unittest_data/test_missing_wpr_file.json', - cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET) - uss.AddUserStory(page_module.Page( - 'http://www.testurl.com', uss, uss.base_dir)) - uss.AddUserStory(page_module.Page( - 'http://www.google.com', uss, uss.base_dir)) - # Page set with an archive_data_file which exists and contains all pages - # but fails to find a wpr file. - self.assertRaises( - user_story_runner.ArchiveError, - user_story_runner._UpdateAndCheckArchives, - uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) + uss = user_story_set.UserStorySet( + archive_data_file='../../unittest_data/test_missing_wpr_file.json', + cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET) + uss.AddUserStory(page_module.Page( + 'http://www.testurl.com', uss, uss.base_dir)) + uss.AddUserStory(page_module.Page( + 'http://www.google.com', uss, uss.base_dir)) + # Page set with an archive_data_file which exists and contains all pages + # but fails to find a wpr file. + self.assertRaises( + user_story_runner.ArchiveError, + user_story_runner._UpdateAndCheckArchives, + uss.archive_data_file, uss.wpr_archive_info, uss.user_stories) + finally: + usr_stub.Restore() + wpr_stub.Restore() def _testMaxFailuresOptionIsRespectedAndOverridable(
diff --git a/tools/telemetry/telemetry/util/cloud_storage.py b/tools/telemetry/telemetry/util/cloud_storage.py index 236b1cdc..0e1ddc3 100644 --- a/tools/telemetry/telemetry/util/cloud_storage.py +++ b/tools/telemetry/telemetry/util/cloud_storage.py
@@ -216,7 +216,7 @@ bucket, remote_path) -def GetIfChanged(file_path, bucket=None): +def GetIfChanged(file_path, bucket): """Gets the file at file_path if it has a hash file that doesn't match. If the file is not in Cloud Storage, log a warning instead of raising an @@ -224,6 +224,10 @@ Returns: True if the binary was changed. + Raises: + CredentialsError if the user has no configured credentials. + PermissionError if the user does not have permission to access the bucket. + NotFoundError if the file is not in the given bucket in cloud_storage. """ hash_path = file_path + '.sha1' if not os.path.exists(hash_path): @@ -234,20 +238,8 @@ if os.path.exists(file_path) and CalculateHash(file_path) == expected_hash: return False - if bucket: - buckets = [bucket] - else: - buckets = [PUBLIC_BUCKET, PARTNER_BUCKET, INTERNAL_BUCKET] - - for bucket in buckets: - try: - Get(bucket, expected_hash, file_path) - return True - except NotFoundError: - continue - - logging.warning('Unable to find file in Cloud Storage: %s', file_path) - return False + Get(bucket, expected_hash, file_path) + return True def CalculateHash(file_path):
diff --git a/tools/telemetry/telemetry/util/mac/README b/tools/telemetry/telemetry/util/mac/README new file mode 100644 index 0000000..0c5538b --- /dev/null +++ b/tools/telemetry/telemetry/util/mac/README
@@ -0,0 +1,2 @@ +This directory contains files needed to run Chrome browser Telemetry tests on +OSX.
diff --git a/tools/telemetry/telemetry/util/mac/__init__.py b/tools/telemetry/telemetry/util/mac/__init__.py new file mode 100644 index 0000000..4d6aabb9 --- /dev/null +++ b/tools/telemetry/telemetry/util/mac/__init__.py
@@ -0,0 +1,3 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file.
diff --git a/tools/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c b/tools/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c new file mode 100644 index 0000000..5facb61a --- /dev/null +++ b/tools/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c
@@ -0,0 +1,94 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This program determines whether a specific entry in the default OSX Keychain +// is decryptable by all applications without a user prompt. +// +// This program uses APIs only available on OSX 10.7+. +// +// Input format: +// determine_if_keychain_entry_is_decryptable [service name] [account name] +// +// Return values: +// 0 - The entry doesn't exist, or the ACLs are correct. +// 1 - The ACLs are incorrect. +// >=2 - Unexpected error. +// +// To compile, run: "clang -framework Security -framework CoreFoundation +// -o determine_if_keychain_entry_is_decryptable +// determine_if_keychain_entry_is_decryptable.c" + +#include <CoreFoundation/CoreFoundation.h> +#include <Security/Security.h> +#include <string.h> + +int main(int argc, char* argv[]) { + // There must be exactly 2 arguments to the program. + if (argc != 3) + return 2; + + const char* service_name = argv[1]; + const char* account_name = argv[2]; + SecKeychainItemRef item; + OSStatus status = SecKeychainFindGenericPassword(NULL, strlen(service_name), + service_name, strlen(account_name), account_name, NULL, NULL, &item); + + // There is no keychain item. + if (status == errSecItemNotFound) + return 0; + + // Unexpected error. + if (status != errSecSuccess) + return 3; + + SecAccessRef access; + status = SecKeychainItemCopyAccess(item, &access); + + // Unexpected error. + if (status != errSecSuccess) { + CFRelease(access); + CFRelease(item); + return 4; + } + + CFArrayRef acl_list = + SecAccessCopyMatchingACLList(access, kSecACLAuthorizationDecrypt); + + for (CFIndex i = 0; i < CFArrayGetCount(acl_list); ++i) { + SecACLRef acl = (SecACLRef)CFArrayGetValueAtIndex(acl_list, i); + + CFArrayRef application_list; + CFStringRef description; + SecKeychainPromptSelector prompt_selector; + status = SecACLCopyContents(acl, &application_list, &description, + &prompt_selector); + + // Unexpected error. + if (status != errSecSuccess) { + CFRelease(acl_list); + CFRelease(access); + CFRelease(item); + return 5; + } + + // Check whether this acl gives decryption access to all applications. + bool found_correct_acl = (application_list == NULL); + CFRelease(description); + if (application_list) + CFRelease(application_list); + + if (found_correct_acl) { + CFRelease(acl_list); + CFRelease(access); + CFRelease(item); + return 0; + } + } + + // No acl was found that gave decryption access to all applications. + CFRelease(acl_list); + CFRelease(access); + CFRelease(item); + return 1; +}
diff --git a/tools/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c b/tools/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c new file mode 100644 index 0000000..ddf0aff4 --- /dev/null +++ b/tools/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c
@@ -0,0 +1,25 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This program determines whether the default OSX Keychain is unlocked without +// causing a user interaction prompt. +// Return values: +// 0 - The default keychain is unlocked. +// 1 - The default keychain is locked. +// 2 - Unexpected error. +// +// To compile, run: "clang -framework Security +// -o determine_if_keychain_is_locked +// determine_if_keychain_is_locked.c" + +#include <Security/Security.h> + +int main() { + SecKeychainStatus keychain_status; + OSStatus os_status = SecKeychainGetStatus(NULL, &keychain_status); + if (os_status != errSecSuccess) + return 2; + + return (keychain_status & kSecUnlockStateStatus) ? 0 : 1; +}
diff --git a/tools/telemetry/telemetry/util/mac/keychain_helper.py b/tools/telemetry/telemetry/util/mac/keychain_helper.py new file mode 100644 index 0000000..00f60335 --- /dev/null +++ b/tools/telemetry/telemetry/util/mac/keychain_helper.py
@@ -0,0 +1,64 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import subprocess + +from telemetry.core import platform +from telemetry.util import support_binaries + +def _PathForExecutable(executable_name): + """Fetches the executable from cloud storage, and returns its path.""" + arch_name = platform.GetHostPlatform().GetArchName() + return support_binaries.FindPath(executable_name, arch_name, 'mac') + +def IsKeychainLocked(): + """ + Returns True if the keychain is locked, or if there is an error determining + the keychain state. + """ + path = _PathForExecutable('determine_if_keychain_is_locked') + + child = subprocess.Popen(path, stdout=subprocess.PIPE) + child.communicate() + return child.returncode != 0 + +def DoesKeychainHaveTimeout(): + """ + Returns True if the keychain will lock itself have a period of time. + + This method will trigger a blocking, modal dialog if the keychain is + locked. + """ + command = ("/usr/bin/security", "show-keychain-info") + child = subprocess.Popen(command, stderr=subprocess.PIPE) + stderr = child.communicate()[1] + return "no-timeout" not in stderr + +def _IsKeychainConfiguredForBots(service_name, account_name): + """ + Returns True if the keychain entry associated with |service_name| and + |account_name| is correctly configured for running telemetry tests on bots. + + This method will trigger a blocking, modal dialog if the keychain is + locked. + """ + # The executable requires OSX 10.7+ APIs. + if (platform.GetHostPlatform().GetOSVersionName() < + platform.platform_backend.LION): + return False + + path = _PathForExecutable('determine_if_keychain_entry_is_decryptable') + + command = (path, service_name, account_name) + child = subprocess.Popen(command) + child.communicate() + return child.returncode == 0 + +def IsKeychainConfiguredForBotsWithChrome(): + return _IsKeychainConfiguredForBots("Chrome Safe Storage", + "Chrome") + +def IsKeychainConfiguredForBotsWithChromium(): + return _IsKeychainConfiguredForBots("Chromium Safe Storage", + "Chromium")
diff --git a/tools/telemetry/telemetry/wpr/archive_info.py b/tools/telemetry/telemetry/wpr/archive_info.py index 1e2691b2..e90ae5e8 100644 --- a/tools/telemetry/telemetry/wpr/archive_info.py +++ b/tools/telemetry/telemetry/wpr/archive_info.py
@@ -92,7 +92,10 @@ else: logging.error("You either aren't authenticated or don't have " "permission to use the archives for this page set." - "\nYou may need to run gsutil config.") + "\nYou may need to run gsutil config." + "\nYou can find instructions for gsutil config at: " + "http://www.chromium.org/developers/telemetry/" + "upload_to_cloud_storage") raise def WprFilePathForUserStory(self, story):
diff --git a/tools/telemetry/unittest_data/page_sets/__init__.py b/tools/telemetry/unittest_data/page_sets/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/telemetry/unittest_data/page_sets/__init__.py
diff --git a/tools/telemetry/unittest_data/page_sets/data/.gitignore b/tools/telemetry/unittest_data/page_sets/data/.gitignore new file mode 100644 index 0000000..2f9e5f9 --- /dev/null +++ b/tools/telemetry/unittest_data/page_sets/data/.gitignore
@@ -0,0 +1 @@ +*.wpr
diff --git a/tools/telemetry/unittest_data/page_sets/data/example_domain.json b/tools/telemetry/unittest_data/page_sets/data/example_domain.json new file mode 100644 index 0000000..20dec47 --- /dev/null +++ b/tools/telemetry/unittest_data/page_sets/data/example_domain.json
@@ -0,0 +1,9 @@ +{ + "description": "Describes the Web Page Replay archives for a user story set. Don't edit by hand! Use record_wpr for updating.", + "archives": { + "example_domain_001.wpr": [ + "http://www.example.com", + "https://www.example.com" + ] + } +} \ No newline at end of file
diff --git a/tools/telemetry/unittest_data/page_sets/data/example_domain_001.wpr.sha1 b/tools/telemetry/unittest_data/page_sets/data/example_domain_001.wpr.sha1 new file mode 100644 index 0000000..fdfac39 --- /dev/null +++ b/tools/telemetry/unittest_data/page_sets/data/example_domain_001.wpr.sha1
@@ -0,0 +1 @@ +5e49b8152e40b5df427a8e73062045ddde2edcb8 \ No newline at end of file
diff --git a/tools/telemetry/unittest_data/page_sets/example_domain.py b/tools/telemetry/unittest_data/page_sets/example_domain.py new file mode 100644 index 0000000..10cf1e9 --- /dev/null +++ b/tools/telemetry/unittest_data/page_sets/example_domain.py
@@ -0,0 +1,17 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from telemetry.page import page +from telemetry.page import page_set + + +class ExampleDomainPageSet(page_set.PageSet): + def __init__(self): + super(ExampleDomainPageSet, self).__init__( + archive_data_file='data/example_domain.json', + user_agent_type='desktop', + bucket=page_set.PUBLIC_BUCKET) + + self.AddUserStory(page.Page('http://www.example.com', self)) + self.AddUserStory(page.Page('https://www.example.com', self))
diff --git a/tools/valgrind/asan/asan_symbolize.py b/tools/valgrind/asan/asan_symbolize.py index cd61dae..9280d7a8 100755 --- a/tools/valgrind/asan/asan_symbolize.py +++ b/tools/valgrind/asan/asan_symbolize.py
@@ -10,6 +10,8 @@ import base64 import json import os +import re +import subprocess import sys class LineBuffered(object): @@ -48,6 +50,73 @@ os.environ['LLVM_SYMBOLIZER_PATH'] = os.path.abspath(symbolizer_path) +def is_hash_name(name): + match = re.match('[0-9a-f]+$', name) + return bool(match) + + +def split_path(path): + ret = [] + while True: + head, tail = os.path.split(path) + if head == path: + return [head] + ret + ret, path = [tail] + ret, head + + +def chrome_product_dir_path(exe_path): + if exe_path is None: + return None + path_parts = split_path(exe_path) + # Make sure the product dir path isn't empty if |exe_path| consists of + # a single component. + if len(path_parts) == 1: + path_parts = ['.'] + path_parts + for index, part in enumerate(path_parts): + if part.endswith('.app'): + return os.path.join(*path_parts[:index]) + # If the executable isn't an .app bundle, it's a commandline binary that + # resides right in the product dir. + return os.path.join(*path_parts[:-1]) + + +inode_path_cache = {} + + +def find_inode_at_path(inode, path): + if inode in inode_path_cache: + return inode_path_cache[inode] + cmd = ['find', path, '-inum', str(inode)] + find_line = subprocess.check_output(cmd).rstrip() + lines = find_line.split('\n') + ret = None + if lines: + # `find` may give us several paths (e.g. 'Chromium Framework' in the + # product dir and 'Chromium Framework' inside 'Chromium.app', + # chrome_dsym_hints() will produce correct .dSYM path for any of them. + ret = lines[0] + inode_path_cache[inode] = ret + return ret + + +# Create a binary name filter that works around https://crbug.com/444835. +# When running tests on OSX swarming servers, ASan sometimes prints paths to +# files in cache (ending with SHA1 filenames) instead of paths to hardlinks to +# those files in the product dir. +# For a given |binary_path| chrome_osx_binary_name_filter() returns one of the +# hardlinks to the same inode in |product_dir_path|. +def make_chrome_osx_binary_name_filter(product_dir_path=''): + def chrome_osx_binary_name_filter(binary_path): + basename = os.path.basename(binary_path) + if is_hash_name(basename) and product_dir_path: + inode = os.stat(binary_path).st_ino + new_binary_path = find_inode_at_path(inode, product_dir_path) + if new_binary_path: + return new_binary_path + return binary_path + return chrome_osx_binary_name_filter + + # Construct a path to the .dSYM bundle for the given binary. # There are three possible cases for binary location in Chromium: # 1. The binary is a standalone executable or dynamic library in the product @@ -63,7 +132,7 @@ # path. Only one of these bundles may be a framework and frameworks cannot # contain other bundles. def chrome_dsym_hints(binary): - path_parts = binary.split(os.path.sep) + path_parts = split_path(binary) app_positions = [] framework_positions = [] for index, part in enumerate(path_parts): @@ -89,7 +158,7 @@ # In case 2 this is the same as |outermost_bundle|. innermost_bundle = bundle_positions[-1] dsym_path = product_dir + [path_parts[innermost_bundle]] - result = '%s.dSYM' % os.path.sep.join(dsym_path) + result = '%s.dSYM' % os.path.join(*dsym_path) return [result] @@ -169,13 +238,22 @@ parser.add_argument('strip_path_prefix', nargs='*', help='When printing source file names, the longest prefix ending in one ' 'of these substrings will be stripped. E.g.: "Release/../../".') + parser.add_argument('--executable-path', + help='Path to program executable. Used on OSX swarming bots to locate ' + 'dSYM bundles for associated frameworks and bundles.') args = parser.parse_args() disable_buffering() set_symbolizer_path() asan_symbolize.demangle = True asan_symbolize.fix_filename_patterns = args.strip_path_prefix - loop = asan_symbolize.SymbolizationLoop(dsym_hint_producer=chrome_dsym_hints) + binary_name_filter = None + if os.uname()[0] == 'Darwin': + binary_name_filter = make_chrome_osx_binary_name_filter( + chrome_product_dir_path(args.executable_path)) + loop = asan_symbolize.SymbolizationLoop( + binary_name_filter=binary_name_filter, + dsym_hint_producer=chrome_dsym_hints) if args.test_summary_json_file: symbolize_snippets_in_json(args.test_summary_json_file, loop)
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py index 51ebeda..554beb3e 100755 --- a/tools/valgrind/chrome_tests.py +++ b/tools/valgrind/chrome_tests.py
@@ -567,7 +567,8 @@ "--no-retry-failures", # retrying takes too much time # http://crbug.com/176908: Don't launch a browser when done. "--no-show-results", - "--nocheck-sys-deps"] + "--nocheck-sys-deps", + "--additional-drt-flag=--no-sandbox"] # Pass build mode to run-webkit-tests. We aren't passed it directly, # so parse it out of build_dir. run-webkit-tests can only handle # the two values "Release" and "Debug".
diff --git a/tools/valgrind/drmemory/suppressions.txt b/tools/valgrind/drmemory/suppressions.txt index fb1861f..c876701f7 100644 --- a/tools/valgrind/drmemory/suppressions.txt +++ b/tools/valgrind/drmemory/suppressions.txt
@@ -722,10 +722,44 @@ ... *!content::RenderWidgetHostViewAura::Destroy +INVALID HEAP ARGUMENT +name=http://crbug.com/455994 +drmemorylib.dll!replace_operator_delete +*!IPC::Listener::`vector deleting destructor' +*!content::RenderFrameImpl::~RenderFrameImpl +*!content::RenderFrameImpl::`vector deleting destructor' +*!content::RenderViewImpl::~RenderViewImpl +*!content::RenderViewImpl::`vector deleting destructor' +*!scoped_refptr<>::Release +*!base::internal::BindState<>::`scalar deleting destructor' +*!scoped_refptr<>::Release +*!base::internal::CallbackBase::~CallbackBase +*!base::MessagePumpDefault::Run +*!base::MessageLoop::RunHandler +*!base::MessageLoop::Run +*!content::RendererMain +*!content::RunNamedProcessTypeMain +*!content::ContentMainRunnerImpl::Run +*!content::ContentMain +*!content::LaunchTests + UNADDRESSABLE ACCESS -name=http://crbug.com/455066 -system call NtReadFile parameter #4 -KERNELBASE.dll!ReadFile -KERNEL32.dll!ReadFile -*!net::FileStream::Context::ReadAsync -*!base::internal::RunnableAdapter<>::Run +name=http://crbug.com/456131 +... +*!content::NavigateToURL +*!content::BrowserSideNavigationBrowserTest_BrowserInitiatedNavigations_Test::RunTestOnMainThread +*!content::ContentBrowserTest::RunTestOnMainThreadLoop +*!content::BrowserTestBase::ProxyRunTestOnMainThreadLoop +*!content::ShellBrowserMainParts::PreMainMessageLoopRun +*!content::BrowserMainLoop::PreMainMessageLoopRun +*!base::internal::Invoker<>::Run +*!content::StartupTaskRunner::RunAllTasksNow +*!content::BrowserMainLoop::CreateStartupTasks +*!content::BrowserMainRunnerImpl::Initialize +*!ShellBrowserMain +*!content::ShellMainDelegate::RunProcess +*!content::RunNamedProcessTypeMain +*!content::ContentMainRunnerImpl::Run +*!content::ContentMain +*!content::BrowserTestBase::SetUp +*!content::ContentBrowserTest::SetUp
diff --git a/tools/valgrind/drmemory/suppressions_full.txt b/tools/valgrind/drmemory/suppressions_full.txt index beb52f8..d823d49b 100644 --- a/tools/valgrind/drmemory/suppressions_full.txt +++ b/tools/valgrind/drmemory/suppressions_full.txt
@@ -1892,3 +1892,9 @@ UNINITIALIZED READ name=bug_399842 skia.dll!S32A_Opaque_BlitRow32_SSE4 + +UNINITIALIZED READ +name=bug_455417 +*!std::char_traits<>::compare +... +*!*::*URLRequest*::TestBody
diff --git a/tools/valgrind/gtest_exclude/chrome_app_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/chrome_app_unittests.gtest-drmemory_win32.txt new file mode 100644 index 0000000..f1382daf --- /dev/null +++ b/tools/valgrind/gtest_exclude/chrome_app_unittests.gtest-drmemory_win32.txt
@@ -0,0 +1,2 @@ +# crbug.com/455536 +ChromeWatcherCommandLineTest.BasicTest
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index fea7c3b1..10849ae0 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt
@@ -3596,3 +3596,23 @@ fun:_ZN4base12SimpleThread10ThreadMainEv fun:_ZN4base12_GLOBAL__N_110ThreadFuncEPv } +{ + bug_455732 + Memcheck:Leak + fun:_Znw* + fun:_ZN4mojo7BindingINS_15ServiceProviderEE4BindENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEPK15MojoAsyncWaiter + fun:_ZN4mojo7BindingINS_15ServiceProviderEE4BindENS_16InterfaceRequestIS1_EEPK15MojoAsyncWaiter + fun:_ZN7content19ServiceRegistryImpl4BindEN4mojo16InterfaceRequestINS1_15ServiceProviderEEE + fun:_ZN7content12_GLOBAL__N_120ApplicationSetupImpl24ExchangeServiceProvidersEN4mojo16InterfaceRequestINS2_15ServiceProviderEEENS2_12InterfacePtrIS4_EE + fun:_ZN7content20ApplicationSetupStub6AcceptEPN4mojo7MessageE + fun:_ZN4mojo8internal6Router21HandleIncomingMessageEPNS_7MessageE + fun:_ZN4mojo8internal6Router26HandleIncomingMessageThunk6AcceptEPNS_7MessageE + fun:_ZN7content32ApplicationSetupRequestValidator6AcceptEPN4mojo7MessageE + fun:_ZN4mojo8internal22MessageHeaderValidator6AcceptEPNS_7MessageE + fun:_ZN4mojo22ReadAndDispatchMessageENS_17MessagePipeHandleEPNS_15MessageReceiverEPb + fun:_ZN4mojo8internal9Connector17ReadSingleMessageEPi + fun:_ZN4mojo8internal9Connector24ReadAllAvailableMessagesEv + fun:_ZN4mojo8internal9Connector13OnHandleReadyEi + fun:_ZN4mojo8internal9Connector17CallOnHandleReadyEPvi + fun:_ZN4mojo8internal12_GLOBAL__N_113OnHandleReadyEPNS_6common13HandleWatcherEPFvPviES5_i +}
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java index 07f48dc..b32cd9b 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -32,7 +32,8 @@ } @Override - public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) { + public int showCancelableIntent( + PendingIntent intent, IntentCallback callback, Integer errorId) { Activity activity = mActivityRef.get(); if (activity == null) return START_INTENT_FAILURE; @@ -50,7 +51,7 @@ } @Override - public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) { + public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { Activity activity = mActivityRef.get(); if (activity == null) return START_INTENT_FAILURE; @@ -104,8 +105,9 @@ return requestCode; } - private void storeCallbackData(int requestCode, IntentCallback callback, int errorId) { + private void storeCallbackData(int requestCode, IntentCallback callback, Integer errorId) { mOutstandingIntents.put(requestCode, callback); - mIntentErrors.put(requestCode, mApplicationContext.getString(errorId)); + mIntentErrors.put( + requestCode, errorId == null ? null : mApplicationContext.getString(errorId)); } }
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index 8f1c58f6..0816862 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -4,6 +4,8 @@ package org.chromium.ui.base; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; import android.app.Activity; import android.app.PendingIntent; @@ -13,6 +15,7 @@ import android.os.Bundle; import android.util.Log; import android.util.SparseArray; +import android.view.View; import android.widget.Toast; import org.chromium.base.CalledByNative; @@ -21,6 +24,7 @@ import java.lang.ref.WeakReference; import java.util.HashMap; +import java.util.HashSet; /** * The window base class that has the minimum functionality. @@ -47,6 +51,10 @@ // the Android lint warning "UseSparseArrays". protected HashMap<Integer, String> mIntentErrors; + // We track all animations over content and provide a drawing placeholder for them. + private HashSet<Animator> mAnimationsOverContent = new HashSet<Animator>(); + private View mAnimationPlaceholderView; + private final VSyncMonitor.Listener mVSyncListener = new VSyncMonitor.Listener() { @Override public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) { @@ -83,10 +91,10 @@ * @param intent The PendingIntent that needs to be shown. * @param callback The object that will receive the results for the intent. * @param errorId The ID of error string to be show if activity is paused before intent - * results. + * results, or null if no message is required. * @return Whether the intent was shown. */ - public boolean showIntent(PendingIntent intent, IntentCallback callback, int errorId) { + public boolean showIntent(PendingIntent intent, IntentCallback callback, Integer errorId) { return showCancelableIntent(intent, callback, errorId) >= 0; } @@ -95,10 +103,10 @@ * @param intent The intent that needs to be shown. * @param callback The object that will receive the results for the intent. * @param errorId The ID of error string to be show if activity is paused before intent - * results. + * results, or null if no message is required. * @return Whether the intent was shown. */ - public boolean showIntent(Intent intent, IntentCallback callback, int errorId) { + public boolean showIntent(Intent intent, IntentCallback callback, Integer errorId) { return showCancelableIntent(intent, callback, errorId) >= 0; } @@ -107,11 +115,12 @@ * @param intent The PendingIntent that needs to be shown. * @param callback The object that will receive the results for the intent. * @param errorId The ID of error string to be show if activity is paused before intent - * results. + * results, or null if no message is required. * @return A non-negative request code that could be used for finishActivity, or * START_INTENT_FAILURE if failed. */ - public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) { + public int showCancelableIntent( + PendingIntent intent, IntentCallback callback, Integer errorId) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return START_INTENT_FAILURE; } @@ -121,11 +130,11 @@ * @param intent The intent that needs to be showed. * @param callback The object that will receive the results for the intent. * @param errorId The ID of error string to be show if activity is paused before intent - * results. + * results, or null if no message is required. * @return A non-negative request code that could be used for finishActivity, or * START_INTENT_FAILURE if failed. */ - public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) { + public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return START_INTENT_FAILURE; } @@ -289,6 +298,56 @@ return mNativeWindowAndroid; } + /** + * Set the animation placeholder view, which we set to 'draw' during animations, such that + * animations aren't clipped by the SurfaceView 'hole'. This can be the SurfaceView itself + * or a view directly on top of it. This could be extended to many views if we ever need it. + */ + public void setAnimationPlaceholderView(View view) { + mAnimationPlaceholderView = view; + } + + /** + * Start a post-layout animation on top of web content. + * + * By default, Android optimizes what it shows on top of SurfaceViews (saves power). + * Effectively, layouts determine what gets drawn and post-layout animations outside + * of this area may be 'clipped'. Using this method to start such animations will + * ensure that nothing is clipped during the animation, and restore the optimal + * state when the animation ends. + */ + public void startAnimationOverContent(Animator animation) { + // We may not need an animation placeholder (eg. Webview doesn't use SurfaceView) + if (mAnimationPlaceholderView == null) + return; + if (animation.isStarted()) throw new IllegalArgumentException("Already started."); + boolean added = mAnimationsOverContent.add(animation); + if (!added) throw new IllegalArgumentException("Already Added."); + + // We start the animation in this method to help guarantee that we never get stuck in this + // state or leak objects into the set. Starting the animation here should guarantee that we + // get an onAnimationEnd callback, and remove this animation. + animation.start(); + + // When the first animation starts, make the placeholder 'draw' itself. + if (mAnimationPlaceholderView.willNotDraw()) { + mAnimationPlaceholderView.setWillNotDraw(false); + } + + // When the last animation ends, remove the placeholder view, + // returning to the default optimized state. + animation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + animation.removeListener(this); + mAnimationsOverContent.remove(animation); + if (mAnimationsOverContent.isEmpty()) { + mAnimationPlaceholderView.setWillNotDraw(true); + } + } + }); + } + private native long nativeInit(); private native void nativeOnVSync(long nativeWindowAndroid, long vsyncTimeMicros,
diff --git a/ui/android/resources/resource_manager_impl_unittest.cc b/ui/android/resources/resource_manager_impl_unittest.cc index 1b1a2c1..0c78a1a 100644 --- a/ui/android/resources/resource_manager_impl_unittest.cc +++ b/ui/android/resources/resource_manager_impl_unittest.cc
@@ -19,7 +19,7 @@ explicit TestResourceManagerImpl(UIResourceProvider* provider) : ResourceManagerImpl(provider) {} - virtual ~TestResourceManagerImpl() {} + ~TestResourceManagerImpl() override {} void SetResourceAsLoaded(AndroidResourceType res_type, int res_id) { SkBitmap small_bitmap; @@ -57,7 +57,7 @@ virtual ~MockUIResourceProvider() {} - virtual cc::UIResourceId CreateUIResource( + cc::UIResourceId CreateUIResource( ui::UIResourceClientAndroid* client) override { if (!has_layer_tree_host_) return 0; @@ -67,12 +67,12 @@ return id; } - virtual void DeleteUIResource(cc::UIResourceId id) override { + void DeleteUIResource(cc::UIResourceId id) override { CHECK(has_layer_tree_host_); ui_resource_client_map_.erase(id); } - virtual bool SupportsETC1NonPowerOfTwo() const override { return true; } + bool SupportsETC1NonPowerOfTwo() const override { return true; } void LayerTreeHostCleared() { has_layer_tree_host_ = false;
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index a17864e..53a1401 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -50,9 +50,6 @@ const float kFolderShadowRadius = 23.5; const float kFolderShadowOffsetY = 1; -const int kCardShadowBlur = 4; -const int kCardShadowYOffset = 1; -const SkColor kCardShadowColor = SkColorSetARGB(0x4C, 0, 0, 0); const SkColor kCardBackgroundColor = SK_ColorWHITE; // Duration in milliseconds for page transition. @@ -126,4 +123,21 @@ #endif #endif +gfx::ShadowValue GetShadowForZHeight(int z_height) { + if (z_height <= 0) + return gfx::ShadowValue(); + + switch (z_height) { + case 1: + return gfx::ShadowValue(gfx::Point(0, 1), 2, + SkColorSetARGB(0x4C, 0, 0, 0)); + case 2: + return gfx::ShadowValue(gfx::Point(0, 2), 4, + SkColorSetARGB(0x33, 0, 0, 0)); + default: + return gfx::ShadowValue(gfx::Point(0, 8), 12, + SkColorSetARGB(0x3F, 0, 0, 0)); + } +} + } // namespace app_list
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index e0a5c12..96c40383 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -9,6 +9,7 @@ #include "ui/app_list/app_list_export.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/animation/tween.h" +#include "ui/gfx/shadow_value.h" namespace app_list { @@ -43,9 +44,6 @@ APP_LIST_EXPORT extern const float kFolderShadowRadius; APP_LIST_EXPORT extern const float kFolderShadowOffsetY; -APP_LIST_EXPORT extern const int kCardShadowBlur; -APP_LIST_EXPORT extern const int kCardShadowYOffset; -APP_LIST_EXPORT extern const SkColor kCardShadowColor; APP_LIST_EXPORT extern const SkColor kCardBackgroundColor; APP_LIST_EXPORT extern const int kPageTransitionDurationInMs; @@ -84,6 +82,9 @@ APP_LIST_EXPORT extern const char kAppListWMClass[]; #endif +// Returns the shadow values for a view at |z_height|. +gfx::ShadowValue APP_LIST_EXPORT GetShadowForZHeight(int z_height); + } // namespace app_list #endif // UI_APP_LIST_APP_LIST_CONSTANTS_H_
diff --git a/ui/app_list/search/mixer_unittest.cc b/ui/app_list/search/mixer_unittest.cc index 5562742..168123d 100644 --- a/ui/app_list/search/mixer_unittest.cc +++ b/ui/app_list/search/mixer_unittest.cc
@@ -120,7 +120,7 @@ providers_[i]->Stop(); } - mixer_->MixAndPublish(is_voice_query_, KnownResults()); + mixer_->MixAndPublish(is_voice_query_, known_results_); } std::string GetResults() const { @@ -146,9 +146,14 @@ is_voice_query_ = is_voice_query; } + void AddKnownResult(const std::string& id, KnownResultType type) { + known_results_[id] = type; + } + private: scoped_ptr<Mixer> mixer_; scoped_ptr<AppListModel::SearchResults> results_; + KnownResults known_results_; bool is_voice_query_; @@ -218,6 +223,25 @@ EXPECT_EQ("dup0,dup1,dup2", GetResults()); } +// Tests that "known results" have priority over others. +TEST_F(MixerTest, KnownResultsPriority) { + // This gives omnibox 0 -- 5. + omnibox_provider()->set_count(6); + + // omnibox 1 -- 4 are "known results". + AddKnownResult("omnibox1", PREFIX_SECONDARY); + AddKnownResult("omnibox2", PERFECT_SECONDARY); + AddKnownResult("omnibox3", PREFIX_PRIMARY); + AddKnownResult("omnibox4", PERFECT_PRIMARY); + + RunQuery(); + + // omnibox 1 -- 4 should be prioritised over the others. They should be + // ordered 4, 3, 2, 1 (in order of match quality). + EXPECT_EQ("omnibox4,omnibox3,omnibox2,omnibox1,omnibox0,omnibox5", + GetResults()); +} + TEST_F(MixerTest, VoiceQuery) { omnibox_provider()->set_count(3); RunQuery();
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index dbb948a..c825d64 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -25,7 +25,6 @@ #include "ui/app_list/views/apps_grid_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/search_box_view.h" -#include "ui/app_list/views/search_result_list_view.h" #include "ui/app_list/views/search_result_page_view.h" #include "ui/app_list/views/search_result_tile_item_view.h" #include "ui/app_list/views/start_page_view.h" @@ -478,6 +477,7 @@ EXPECT_EQ(view_size.ToString(), view_->GetPreferredSize().ToString()); // Check tiles hide and show on deletion and addition. + EXPECT_TRUE(SetAppListState(AppListModel::STATE_START)); model->results()->Add(new TestStartPageSearchResult()); start_page_view->UpdateForTesting(); EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views())); @@ -605,13 +605,8 @@ contents_view->GetDefaultContentsBounds(); EXPECT_EQ(AppListModel::STATE_SEARCH_RESULTS, delegate_->GetTestModel()->state()); - if (test_type_ == EXPERIMENTAL) { - EXPECT_EQ(default_contents_bounds, - contents_view->search_results_page_view()->bounds()); - } else { - EXPECT_EQ(default_contents_bounds, - contents_view->search_results_list_view()->bounds()); - } + EXPECT_EQ(default_contents_bounds, + contents_view->search_results_page_view()->bounds()); // Hide the search results. contents_view->ShowSearchResults(false);
diff --git a/ui/app_list/views/contents_animator.cc b/ui/app_list/views/contents_animator.cc index 97d3c502..e651980 100644 --- a/ui/app_list/views/contents_animator.cc +++ b/ui/app_list/views/contents_animator.cc
@@ -12,11 +12,21 @@ #include "ui/app_list/views/start_page_view.h" #include "ui/gfx/animation/tween.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/shadow_value.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" namespace app_list { +namespace { + +gfx::ShadowValue GetSearchBoxShadowForState(AppListModel::State state) { + return GetShadowForZHeight(state == AppListModel::STATE_SEARCH_RESULTS ? 1 + : 2); +} + +} // namespace + // ContentsAnimator ContentsAnimator::ContentsAnimator(ContentsView* contents_view) @@ -27,21 +37,23 @@ } gfx::Rect ContentsAnimator::GetOnscreenPageBounds(int page_index) const { - return contents_view_->IsStateActive(AppListModel::STATE_CUSTOM_LAUNCHER_PAGE) + return contents_view_->GetPageIndexForState( + AppListModel::STATE_CUSTOM_LAUNCHER_PAGE) == page_index ? contents_view_->GetContentsBounds() : contents_view_->GetDefaultContentsBounds(); } gfx::Rect ContentsAnimator::GetOffscreenPageBounds(int page_index) const { - gfx::Rect bounds(contents_view_->GetContentsBounds()); + gfx::Rect bounds(GetOnscreenPageBounds(page_index)); // The start page and search page origins are above; all other pages' origins // are below. - int page_height = bounds.height(); bool origin_above = contents_view_->GetPageIndexForState( AppListModel::STATE_START) == page_index || contents_view_->GetPageIndexForState( AppListModel::STATE_SEARCH_RESULTS) == page_index; - bounds.set_y(origin_above ? -page_height : page_height); + bounds.set_y(origin_above + ? -bounds.height() + : contents_view_->GetContentsBounds().height() + bounds.y()); return bounds; } @@ -95,9 +107,27 @@ gfx::Rect search_box_rect = gfx::Tween::RectValueBetween(progress, search_box_from, search_box_to); + AppListModel::State from_state = + contents_view()->GetStateForPageIndex(from_page); + AppListModel::State to_state = contents_view()->GetStateForPageIndex(to_page); + + gfx::ShadowValue original_shadow = GetSearchBoxShadowForState(from_state); + gfx::ShadowValue target_shadow = GetSearchBoxShadowForState(to_state); + SearchBoxView* search_box = contents_view()->GetSearchBoxView(); - search_box->GetWidget()->SetBounds(contents_view()->ConvertRectToWidget( - search_box->GetViewBoundsForSearchBoxContentsBounds(search_box_rect))); + gfx::Point offset(gfx::Tween::LinearIntValueBetween( + progress, original_shadow.x(), target_shadow.x()), + gfx::Tween::LinearIntValueBetween( + progress, original_shadow.y(), target_shadow.y())); + search_box->SetShadow(gfx::ShadowValue( + offset, gfx::Tween::LinearIntValueBetween( + progress, original_shadow.blur(), target_shadow.blur()), + gfx::Tween::ColorValueBetween(progress, original_shadow.color(), + target_shadow.color()))); + + search_box->GetWidget()->SetBounds( + search_box->GetViewBoundsForSearchBoxContentsBounds( + contents_view()->ConvertRectToWidget(search_box_rect))); } void ContentsAnimator::ClipSearchResultsPageToOnscreenBounds(
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index 3de1018..985f943 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -31,7 +31,6 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view) : apps_container_view_(nullptr), - search_results_list_view_(nullptr), search_results_page_view_(nullptr), start_page_view_(nullptr), custom_page_view_(nullptr), @@ -73,26 +72,22 @@ // Start page. start_page_view_ = new StartPageView(app_list_main_view_, view_delegate); AddLauncherPage(start_page_view_, AppListModel::STATE_START); + } - // Search results UI. - search_results_page_view_ = new SearchResultPageView(); + // Search results UI. + search_results_page_view_ = new SearchResultPageView(); - AppListModel::SearchResults* results = view_delegate->GetModel()->results(); - search_results_page_view_->AddSearchResultContainerView( - results, new SearchResultListView(app_list_main_view_, view_delegate)); + AppListModel::SearchResults* results = view_delegate->GetModel()->results(); + search_results_page_view_->AddSearchResultContainerView( + results, new SearchResultListView(app_list_main_view_, view_delegate)); + + if (app_list::switches::IsExperimentalAppListEnabled()) { search_results_page_view_->AddSearchResultContainerView( results, new SearchResultTileItemListView(GetSearchBoxView()->search_box())); - - AddLauncherPage(search_results_page_view_, - AppListModel::STATE_SEARCH_RESULTS); - } else { - search_results_list_view_ = - new SearchResultListView(app_list_main_view_, view_delegate); - AddLauncherPage(search_results_list_view_, - AppListModel::STATE_SEARCH_RESULTS); - search_results_list_view_->SetResults(model->results()); } + AddLauncherPage(search_results_page_view_, + AppListModel::STATE_SEARCH_RESULTS); apps_container_view_ = new AppsContainerView(app_list_main_view_, model); @@ -224,15 +219,6 @@ app_list_main_view_->model()->ClearCustomLauncherPageSubpages(); } - // TODO(xiyuan): Highlight default match instead of the first. - if (state == AppListModel::STATE_SEARCH_RESULTS && - search_results_list_view_ && search_results_list_view_->visible()) { - search_results_list_view_->OnContainerSelected(false); - } - - if (search_results_list_view_) - search_results_list_view_->UpdateAutoLaunchState(); - if (custom_page_view_) { custom_page_view_->SetFocusable(state == AppListModel::STATE_CUSTOM_LAUNCHER_PAGE); @@ -442,15 +428,7 @@ } gfx::Size ContentsView::GetDefaultContentsSize() const { - const gfx::Size container_size = - apps_container_view_->apps_grid_view()->GetPreferredSize(); - const gfx::Size results_size = - search_results_list_view_ ? search_results_list_view_->GetPreferredSize() - : gfx::Size(); - - int width = std::max(container_size.width(), results_size.width()); - int height = std::max(container_size.height(), results_size.height()); - return gfx::Size(width, height); + return apps_container_view_->apps_grid_view()->GetPreferredSize(); } gfx::Size ContentsView::GetPreferredSize() const {
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index 1b7b0cb..3d296d8d 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -34,7 +34,6 @@ class ContentsAnimator; class PaginationModel; class SearchBoxView; -class SearchResultListView; class SearchResultPageView; class StartPageView; @@ -100,9 +99,6 @@ } StartPageView* start_page_view() const { return start_page_view_; } views::View* custom_page_view() const { return custom_page_view_; } - SearchResultListView* search_results_list_view() const { - return search_results_list_view_; - } SearchResultPageView* search_results_page_view() { return search_results_page_view_; } @@ -216,11 +212,9 @@ // Special sub views of the ContentsView. All owned by the views hierarchy. AppsContainerView* apps_container_view_; - // Only used in the normal app list. - SearchResultListView* search_results_list_view_; + SearchResultPageView* search_results_page_view_; // Only used in the experimental app list. - SearchResultPageView* search_results_page_view_; StartPageView* start_page_view_; views::View* custom_page_view_;
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index b23e5dd..a590fb9 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -17,6 +17,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/events/event.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/shadow_value.h" #include "ui/resources/grit/ui_resources.h" #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" @@ -43,10 +44,6 @@ const int kBackgroundBorderCornerRadius = 2; -const int kShadowBlur = 4; -const int kShadowYOffset = 2; -const SkColor kShadowColor = SkColorSetARGB(0x33, 0, 0, 0); - // A background that paints a solid white rounded rect with a thin grey border. class ExperimentalSearchBoxBackground : public views::Background { public: @@ -85,8 +82,7 @@ AddChildView(content_container_); if (switches::IsExperimentalAppListEnabled()) { - SetBorder(make_scoped_ptr( - new views::ShadowBorder(kShadowBlur, kShadowColor, kShadowYOffset, 0))); + SetShadow(GetShadowForZHeight(1)); back_button_ = new views::ImageButton(this); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); back_button_->SetImage( @@ -175,10 +171,15 @@ menu_.reset(); } +void SearchBoxView::SetShadow(const gfx::ShadowValue& shadow) { + SetBorder(make_scoped_ptr(new views::ShadowBorder(shadow))); + Layout(); +} + gfx::Rect SearchBoxView::GetViewBoundsForSearchBoxContentsBounds( const gfx::Rect& rect) const { gfx::Rect view_bounds = rect; - view_bounds.Inset(GetInsets().Scale(-1)); + view_bounds.Inset(-GetInsets()); return view_bounds; }
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index b141da6..f32ec041 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -9,6 +9,7 @@ #include "ui/app_list/search_box_model_observer.h" #include "ui/app_list/speech_ui_model_observer.h" +#include "ui/gfx/shadow_value.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/controls/textfield/textfield_controller.h" @@ -48,6 +49,9 @@ void ClearSearch(); void InvalidateMenu(); + // Sets the shadow border of the search box. + void SetShadow(const gfx::ShadowValue& shadow); + // Returns the bounds to use for the view (including the shadow) given the // desired bounds of the search box contents. gfx::Rect GetViewBoundsForSearchBoxContentsBounds(
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index a923ba95..f77c722 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc
@@ -5,10 +5,13 @@ #include "ui/app_list/views/search_result_page_view.h" #include "ui/app_list/app_list_constants.h" +#include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/views/app_list_main_view.h" +#include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_result_list_view.h" #include "ui/app_list/views/search_result_tile_item_list_view.h" +#include "ui/gfx/shadow_value.h" #include "ui/views/background.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" @@ -26,8 +29,7 @@ class SearchCardView : public views::View { public: explicit SearchCardView(views::View* content_view) { - SetBorder(make_scoped_ptr(new views::ShadowBorder( - kCardShadowBlur, kCardShadowColor, kCardShadowYOffset, 0))); + SetBorder(make_scoped_ptr(new views::ShadowBorder(GetShadowForZHeight(1)))); SetLayoutManager(new views::FillLayout()); content_view->set_background( views::Background::CreateSolidBackground(kCardBackgroundColor)); @@ -45,9 +47,22 @@ } // namespace SearchResultPageView::SearchResultPageView() : selected_index_(0) { - SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, - kExperimentalWindowPadding, kTopPadding, - kGroupSpacing)); + if (switches::IsExperimentalAppListEnabled()) { + gfx::ShadowValue shadow = GetShadowForZHeight(1); + scoped_ptr<views::Border> border(new views::ShadowBorder(shadow)); + + gfx::Insets insets = gfx::Insets(kTopPadding, kExperimentalWindowPadding, 0, + kExperimentalWindowPadding); + insets += -border->GetInsets(); + + views::BoxLayout* layout = + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, kGroupSpacing); + layout->set_inside_border_insets(insets); + + SetLayoutManager(layout); + } else { + SetLayoutManager(new views::FillLayout); + } } SearchResultPageView::~SearchResultPageView() { @@ -56,7 +71,11 @@ void SearchResultPageView::AddSearchResultContainerView( AppListModel::SearchResults* results_model, SearchResultContainerView* result_container) { - AddChildView(new SearchCardView(result_container)); + views::View* view_to_add = result_container; + if (switches::IsExperimentalAppListEnabled()) + view_to_add = new SearchCardView(result_container); + + AddChildView(view_to_add); result_container_views_.push_back(result_container); result_container->SetResults(results_model); }
diff --git a/ui/app_list/views/speech_view.cc b/ui/app_list/views/speech_view.cc index 8337ffc..038faa7ebe 100644 --- a/ui/app_list/views/speech_view.cc +++ b/ui/app_list/views/speech_view.cc
@@ -14,6 +14,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/path.h" +#include "ui/gfx/shadow_value.h" #include "ui/resources/grit/ui_resources.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/animation/bounds_animator.h" @@ -109,9 +110,7 @@ : delegate_(delegate), logo_(NULL) { SetBorder(scoped_ptr<views::Border>( - new views::ShadowBorder(kCardShadowBlur, kCardShadowColor, - kCardShadowYOffset, // Vertical offset. - 0))); + new views::ShadowBorder(GetShadowForZHeight(1)))); // To keep the painting order of the border and the background, this class // actually has a single child of 'container' which has white background and
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index 01ea2d60..c4e0ce7 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -14,7 +14,7 @@ #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/search_box_view.h" -#include "ui/app_list/views/search_result_list_view.h" +#include "ui/app_list/views/search_result_container_view.h" #include "ui/app_list/views/search_result_tile_item_view.h" #include "ui/app_list/views/tile_item_view.h" #include "ui/gfx/canvas.h" @@ -63,6 +63,120 @@ } // namespace +// A container that holds the start page recommendation tiles and the all apps +// tile. +class StartPageView::StartPageTilesContainer + : public SearchResultContainerView { + public: + StartPageTilesContainer(ContentsView* contents_view, + AllAppsTileItemView* all_apps_button); + ~StartPageTilesContainer() override; + + TileItemView* GetTileItemView(size_t index); + + const std::vector<SearchResultTileItemView*>& tile_views() const { + return search_result_tile_views_; + } + + AllAppsTileItemView* all_apps_button() { return all_apps_button_; } + + // Overridden from SearchResultContainerView: + int Update() override; + void UpdateSelectedIndex(int old_selected, int new_selected) override; + void OnContainerSelected(bool from_bottom) override; + + private: + ContentsView* contents_view_; + + std::vector<SearchResultTileItemView*> search_result_tile_views_; + AllAppsTileItemView* all_apps_button_; + + DISALLOW_COPY_AND_ASSIGN(StartPageTilesContainer); +}; + +StartPageView::StartPageTilesContainer::StartPageTilesContainer( + ContentsView* contents_view, + AllAppsTileItemView* all_apps_button) + : contents_view_(contents_view), all_apps_button_(all_apps_button) { + views::BoxLayout* tiles_layout_manager = + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, kTileSpacing); + tiles_layout_manager->set_main_axis_alignment( + views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); + SetLayoutManager(tiles_layout_manager); + set_background( + views::Background::CreateSolidBackground(kLabelBackgroundColor)); + + // Add SearchResultTileItemViews to the container. + for (size_t i = 0; i < kNumStartPageTiles; ++i) { + SearchResultTileItemView* tile_item = new SearchResultTileItemView(); + AddChildView(tile_item); + tile_item->SetParentBackgroundColor(kLabelBackgroundColor); + search_result_tile_views_.push_back(tile_item); + } + + // Also add a special "all apps" button to the end of the container. + all_apps_button_->UpdateIcon(); + all_apps_button_->SetParentBackgroundColor(kLabelBackgroundColor); + AddChildView(all_apps_button_); +} + +StartPageView::StartPageTilesContainer::~StartPageTilesContainer() { +} + +TileItemView* StartPageView::StartPageTilesContainer::GetTileItemView( + size_t index) { + DCHECK_GT(kNumStartPageTiles + 1, index); + if (index == kNumStartPageTiles) + return all_apps_button_; + + return search_result_tile_views_[index]; +} + +int StartPageView::StartPageTilesContainer::Update() { + // Ignore updates and disable buttons when transitioning to a different + // state. + if (contents_view_->GetActiveState() != AppListModel::STATE_START) { + for (auto* view : search_result_tile_views_) + view->SetEnabled(false); + + return num_results(); + } + + std::vector<SearchResult*> display_results = + AppListModel::FilterSearchResultsByDisplayType( + results(), SearchResult::DISPLAY_RECOMMENDATION, kNumStartPageTiles); + + // Update the tile item results. + for (size_t i = 0; i < search_result_tile_views_.size(); ++i) { + SearchResult* item = NULL; + if (i < display_results.size()) + item = display_results[i]; + search_result_tile_views_[i]->SetSearchResult(item); + search_result_tile_views_[i]->SetEnabled(true); + } + + Layout(); + parent()->Layout(); + // Add 1 to the results size to account for the all apps button. + return display_results.size() + 1; +} + +void StartPageView::StartPageTilesContainer::UpdateSelectedIndex( + int old_selected, + int new_selected) { + if (old_selected >= 0) + GetTileItemView(old_selected)->SetSelected(false); + + if (new_selected >= 0) + GetTileItemView(new_selected)->SetSelected(true); +} + +void StartPageView::StartPageTilesContainer::OnContainerSelected( + bool from_bottom) { +} + +//////////////////////////////////////////////////////////////////////////////// +// StartPageView implementation: StartPageView::StartPageView(AppListMainView* app_list_main_view, AppListViewDelegate* view_delegate) : app_list_main_view_(app_list_main_view), @@ -70,16 +184,19 @@ search_box_spacer_view_(new SearchBoxSpacerView( app_list_main_view->search_box_view()->GetPreferredSize())), instant_container_(new views::View), - tiles_container_(new views::View) { + tiles_container_(new StartPageTilesContainer( + app_list_main_view->contents_view(), + new AllAppsTileItemView( + app_list_main_view_->contents_view(), + view_delegate_->GetModel()->top_level_item_list()))) { // The view containing the start page WebContents and SearchBoxSpacerView. InitInstantContainer(); AddChildView(instant_container_); // The view containing the start page tiles. - InitTilesContainer(); AddChildView(tiles_container_); - SetResults(view_delegate_->GetModel()->results()); + tiles_container_->SetResults(view_delegate_->GetModel()->results()); Reset(); } @@ -107,48 +224,27 @@ instant_container_->AddChildView(search_box_spacer_view_); } -void StartPageView::InitTilesContainer() { - views::BoxLayout* tiles_layout_manager = - new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, kTileSpacing); - tiles_layout_manager->set_main_axis_alignment( - views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); - tiles_container_->SetLayoutManager(tiles_layout_manager); - tiles_container_->set_background( - views::Background::CreateSolidBackground(kLabelBackgroundColor)); - - // Add SearchResultTileItemViews to the container. - for (size_t i = 0; i < kNumStartPageTiles; ++i) { - SearchResultTileItemView* tile_item = new SearchResultTileItemView(); - tiles_container_->AddChildView(tile_item); - tile_item->SetParentBackgroundColor(kLabelBackgroundColor); - search_result_tile_views_.push_back(tile_item); - } - - // Also add a special "all apps" button to the end of the container. - all_apps_button_ = new AllAppsTileItemView( - app_list_main_view_->contents_view(), - view_delegate_->GetModel()->top_level_item_list()); - all_apps_button_->UpdateIcon(); - all_apps_button_->SetParentBackgroundColor(kLabelBackgroundColor); - tiles_container_->AddChildView(all_apps_button_); -} - void StartPageView::Reset() { - Update(); + tiles_container_->Update(); } void StartPageView::UpdateForTesting() { - Update(); + tiles_container_->Update(); +} + +const std::vector<SearchResultTileItemView*>& StartPageView::tile_views() + const { + return tiles_container_->tile_views(); } TileItemView* StartPageView::all_apps_button() const { - return all_apps_button_; + return tiles_container_->all_apps_button(); } void StartPageView::OnShow() { DCHECK(app_list_main_view_->contents_view()->ShouldShowCustomPageClickzone()); UpdateCustomPageClickzoneVisibility(); - ClearSelectedIndex(); + tiles_container_->ClearSelectedIndex(); } void StartPageView::OnHide() { @@ -169,8 +265,9 @@ } bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) { - if (selected_index() >= 0 && - tiles_container_->child_at(selected_index())->OnKeyPressed(event)) + int selected_index = tiles_container_->selected_index(); + if (selected_index >= 0 && + tiles_container_->child_at(selected_index)->OnKeyPressed(event)) return true; int dir = 0; @@ -183,7 +280,7 @@ break; case ui::VKEY_DOWN: // Down selects the first tile if nothing is selected. - if (!IsValidSelectionIndex(selected_index())) + if (!tiles_container_->IsValidSelectionIndex(selected_index)) dir = 1; break; case ui::VKEY_TAB: @@ -196,23 +293,21 @@ if (dir == 0) return false; - if (!IsValidSelectionIndex(selected_index())) { - SetSelectedIndex(dir == -1 ? num_results() - 1 : 0); + if (!tiles_container_->IsValidSelectionIndex(selected_index)) { + tiles_container_->SetSelectedIndex( + dir == -1 ? tiles_container_->num_results() - 1 : 0); return true; } - int selection_index = selected_index() + dir; - if (IsValidSelectionIndex(selection_index)) { - SetSelectedIndex(selection_index); + int selection_index = selected_index + dir; + if (tiles_container_->IsValidSelectionIndex(selection_index)) { + tiles_container_->SetSelectedIndex(selection_index); return true; } return false; } -void StartPageView::OnContainerSelected(bool from_bottom) { -} - gfx::Rect StartPageView::GetSearchBoxBounds() const { return search_box_spacer_view_->bounds(); } @@ -233,39 +328,8 @@ custom_page_clickzone->Hide(); } -int StartPageView::Update() { - std::vector<SearchResult*> display_results = - AppListModel::FilterSearchResultsByDisplayType( - results(), SearchResult::DISPLAY_RECOMMENDATION, kNumStartPageTiles); - - // Update the tile item results. - for (size_t i = 0; i < search_result_tile_views_.size(); ++i) { - SearchResult* item = NULL; - if (i < display_results.size()) - item = display_results[i]; - search_result_tile_views_[i]->SetSearchResult(item); - } - - tiles_container_->Layout(); - Layout(); - // Add 1 to the results size to account for the all apps button. - return display_results.size() + 1; -} - -void StartPageView::UpdateSelectedIndex(int old_selected, int new_selected) { - if (old_selected >= 0) - GetTileItemView(old_selected)->SetSelected(false); - - if (new_selected >= 0) - GetTileItemView(new_selected)->SetSelected(true); -} - TileItemView* StartPageView::GetTileItemView(size_t index) { - DCHECK_GT(kNumStartPageTiles + 1, index); - if (index == kNumStartPageTiles) - return all_apps_button_; - - return search_result_tile_views_[index]; + return tiles_container_->GetTileItemView(index); } } // namespace app_list
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h index 0acd323e..0022229e 100644 --- a/ui/app_list/views/start_page_view.h +++ b/ui/app_list/views/start_page_view.h
@@ -9,7 +9,7 @@ #include "base/basictypes.h" #include "ui/app_list/app_list_export.h" -#include "ui/app_list/views/search_result_container_view.h" +#include "ui/views/view.h" namespace app_list { @@ -20,7 +20,7 @@ class TileItemView; // The start page for the experimental app list. -class APP_LIST_EXPORT StartPageView : public SearchResultContainerView { +class APP_LIST_EXPORT StartPageView : public views::View { public: StartPageView(AppListMainView* app_list_main_view, AppListViewDelegate* view_delegate); @@ -30,9 +30,7 @@ void UpdateForTesting(); - const std::vector<SearchResultTileItemView*>& tile_views() const { - return search_result_tile_views_; - } + const std::vector<SearchResultTileItemView*>& tile_views() const; TileItemView* all_apps_button() const; // Called when the start page view is displayed. @@ -46,9 +44,6 @@ void Layout() override; bool OnKeyPressed(const ui::KeyEvent& event) override; - // Overridden from SearchResultContainerView: - void OnContainerSelected(bool from_bottom) override; - // Returns search box bounds to use when the start page is active. gfx::Rect GetSearchBoxBounds() const; @@ -56,12 +51,9 @@ void UpdateCustomPageClickzoneVisibility(); private: - // Overridden from SearchResultContainerView: - int Update() override; - void UpdateSelectedIndex(int old_selected, int new_selected) override; + class StartPageTilesContainer; void InitInstantContainer(); - void InitTilesContainer(); TileItemView* GetTileItemView(size_t index); @@ -72,10 +64,7 @@ views::View* search_box_spacer_view_; // Owned by views hierarchy. views::View* instant_container_; // Owned by views hierarchy. - views::View* tiles_container_; // Owned by views hierarchy. - - std::vector<SearchResultTileItemView*> search_result_tile_views_; - AllAppsTileItemView* all_apps_button_; + StartPageTilesContainer* tiles_container_; // Owned by views hierarchy. DISALLOW_COPY_AND_ASSIGN(StartPageView); };
diff --git a/ui/app_list/views/tile_item_view.cc b/ui/app_list/views/tile_item_view.cc index 68c2653..1932a7f 100644 --- a/ui/app_list/views/tile_item_view.cc +++ b/ui/app_list/views/tile_item_view.cc
@@ -55,6 +55,7 @@ selected_ = selected; UpdateBackgroundColor(); + NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); } void TileItemView::SetParentBackgroundColor(SkColor color) { @@ -68,6 +69,7 @@ void TileItemView::SetTitle(const base::string16& title) { title_->SetText(title); + SetAccessibleName(title); } void TileItemView::StateChanged() {
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index edab4926..4fe5f63 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -99,6 +99,7 @@ "//base/third_party/dynamic_annotations", "//skia", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events/platform",
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index 41a411f..7b01040 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp
@@ -16,6 +16,7 @@ '../../base/base.gyp:base_i18n', '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../../skia/skia.gyp:skia', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../events/events.gyp:events', @@ -149,6 +150,7 @@ 'dependencies': [ '../../skia/skia.gyp:skia', '../../testing/gtest.gyp:gtest', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../base/ui_base.gyp:ui_base_test_support', '../compositor/compositor.gyp:compositor_test_support', @@ -271,6 +273,7 @@ '../../base/base.gyp:test_support_base', '../../skia/skia.gyp:skia', '../../testing/gtest.gyp:gtest', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../base/ui_base.gyp:ui_base_test_support', '../compositor/compositor.gyp:compositor',
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index b16f5a50..4529844 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -316,143 +316,6 @@ "//url", ] - if (build_ime) { - sources += [ - "ime/candidate_window.cc", - "ime/candidate_window.h", - "ime/chromeos/character_composer.cc", - "ime/chromeos/character_composer.h", - "ime/chromeos/component_extension_ime_manager.cc", - "ime/chromeos/component_extension_ime_manager.h", - "ime/chromeos/composition_text.cc", - "ime/chromeos/composition_text.h", - "ime/chromeos/extension_ime_util.cc", - "ime/chromeos/extension_ime_util.h", - "ime/chromeos/fake_ime_keyboard.cc", - "ime/chromeos/fake_ime_keyboard.h", - "ime/chromeos/fake_input_method_delegate.cc", - "ime/chromeos/fake_input_method_delegate.h", - "ime/chromeos/ime_bridge.cc", - "ime/chromeos/ime_bridge.h", - "ime/chromeos/ime_keyboard.cc", - "ime/chromeos/ime_keyboard.h", - "ime/chromeos/ime_keyboard_ozone.cc", - "ime/chromeos/ime_keyboard_ozone.h", - "ime/chromeos/ime_keyboard_x11.cc", - "ime/chromeos/ime_keyboard_x11.h", - "ime/chromeos/ime_keymap.cc", - "ime/chromeos/ime_keymap.h", - "ime/chromeos/input_method_delegate.h", - "ime/chromeos/input_method_descriptor.cc", - "ime/chromeos/input_method_descriptor.h", - "ime/chromeos/input_method_manager.cc", - "ime/chromeos/input_method_manager.h", - "ime/chromeos/input_method_whitelist.cc", - "ime/chromeos/input_method_whitelist.h", - "ime/chromeos/mock_component_extension_ime_manager_delegate.cc", - "ime/chromeos/mock_component_extension_ime_manager_delegate.h", - "ime/chromeos/mock_ime_candidate_window_handler.cc", - "ime/chromeos/mock_ime_candidate_window_handler.h", - "ime/chromeos/mock_ime_engine_handler.cc", - "ime/chromeos/mock_ime_engine_handler.h", - "ime/chromeos/mock_ime_input_context_handler.cc", - "ime/chromeos/mock_ime_input_context_handler.h", - "ime/composition_text.cc", - "ime/composition_text.h", - "ime/composition_text_util_pango.cc", - "ime/composition_text_util_pango.h", - "ime/composition_underline.h", - "ime/dummy_input_method_delegate.cc", - "ime/dummy_input_method_delegate.h", - "ime/infolist_entry.cc", - "ime/infolist_entry.h", - "ime/input_method.h", - "ime/input_method_auralinux.cc", - "ime/input_method_auralinux.h", - "ime/input_method_base.cc", - "ime/input_method_base.h", - "ime/input_method_chromeos.cc", - "ime/input_method_chromeos.h", - "ime/input_method_delegate.h", - "ime/input_method_factory.cc", - "ime/input_method_factory.h", - "ime/input_method_initializer.cc", - "ime/input_method_initializer.h", - "ime/input_method_mac.h", - "ime/input_method_mac.mm", - "ime/input_method_minimal.cc", - "ime/input_method_minimal.h", - "ime/input_method_observer.h", - "ime/input_method_win.cc", - "ime/input_method_win.h", - "ime/linux/fake_input_method_context.cc", - "ime/linux/fake_input_method_context.h", - "ime/linux/fake_input_method_context_factory.cc", - "ime/linux/fake_input_method_context_factory.h", - "ime/linux/linux_input_method_context.h", - "ime/linux/linux_input_method_context_factory.cc", - "ime/linux/linux_input_method_context_factory.h", - "ime/mock_input_method.cc", - "ime/mock_input_method.h", - "ime/remote_input_method_delegate_win.h", - "ime/remote_input_method_win.cc", - "ime/remote_input_method_win.h", - "ime/text_input_client.cc", - "ime/text_input_client.h", - "ime/text_input_focus_manager.cc", - "ime/text_input_focus_manager.h", - "ime/text_input_type.h", - "ime/win/imm32_manager.cc", - "ime/win/imm32_manager.h", - "ime/win/tsf_input_scope.cc", - "ime/win/tsf_input_scope.h", - ] - - if (!use_aura || (!is_linux && !use_ozone)) { - sources -= [ - "ime/input_method_auralinux.cc", - "ime/input_method_auralinux.h", - ] - } - - if (!toolkit_views && !use_aura) { - sources -= [ - "ime/input_method_factory.cc", - "ime/input_method_factory.h", - "ime/input_method_minimal.cc", - "ime/input_method_minimal.h", - ] - } - - if (is_chromeos) { - deps += [ - "//chromeos", - "//chromeos/ime:gencode", - ] - if (!use_ozone) { - sources -= [ - "ime/chromeos/ime_keyboard_ozone.cc", - "ime/chromeos/ime_keyboard_ozone.h", - ] - } - if (!use_x11) { - sources -= [ - "ime/chromeos/ime_keyboard_x11.cc", - "ime/chromeos/ime_keyboard_x11.h", - ] - } - } - - if (use_pango) { - configs += [ "//build/config/linux:pangocairo" ] - } else { - sources -= [ - "ime/composition_text_util_pango.cc", - "ime/composition_text_util_pango.h", - ] - } - } - if (is_ios) { sources += [ "l10n/l10n_util_mac.h", @@ -563,7 +426,6 @@ "d2d1.lib", "d3d10_1.lib", "dwmapi.lib", - "imm32.lib", "d2d1.lib", "dwmapi.lib", "oleacc.lib", @@ -730,6 +592,8 @@ "ime/dummy_text_input_client.cc", "ime/dummy_text_input_client.h", ] + + deps += [ "//ui/base/ime" ] } if (!use_aura) { @@ -856,6 +720,10 @@ # TODO(GYP) lots of iOS-only steps for ui_base_unittests } + if (build_ime) { + deps += [ "//ui/base/ime" ] + } + if (is_win) { sources += [ "dragdrop/os_exchange_data_win_unittest.cc",
diff --git a/ui/base/cocoa/controls/hyperlink_text_view.h b/ui/base/cocoa/controls/hyperlink_text_view.h index a8f7a20..f04ad40 100644 --- a/ui/base/cocoa/controls/hyperlink_text_view.h +++ b/ui/base/cocoa/controls/hyperlink_text_view.h
@@ -20,16 +20,6 @@ @property(nonatomic, assign) BOOL drawsBackgroundUsingSuperview; -// Convenience function that sets the |HyperlinkTextView| contents to the -// specified |message| with a hypertext style |link| inserted at |linkOffset|. -// Uses the supplied |font|, |messageColor|, and |linkColor|. -- (void)setMessageAndLink:(NSString*)message - withLink:(NSString*)link - atOffset:(NSUInteger)linkOffset - font:(NSFont*)font - messageColor:(NSColor*)messageColor - linkColor:(NSColor*)linkColor; - // Set the |message| displayed by the HyperlinkTextView, using |font| and // |messageColor|. - (void)setMessage:(NSString*)message
diff --git a/ui/base/cocoa/controls/hyperlink_text_view.mm b/ui/base/cocoa/controls/hyperlink_text_view.mm index 0afaafa1..092c096 100644 --- a/ui/base/cocoa/controls/hyperlink_text_view.mm +++ b/ui/base/cocoa/controls/hyperlink_text_view.mm
@@ -101,22 +101,6 @@ [[NSCursor arrowCursor] set]; } -- (void)setMessageAndLink:(NSString*)message - withLink:(NSString*)link - atOffset:(NSUInteger)linkOffset - font:(NSFont*)font - messageColor:(NSColor*)messageColor - linkColor:(NSColor*)linkColor { - NSMutableString* finalMessage = [NSMutableString stringWithString:message]; - [finalMessage insertString:link atIndex:linkOffset]; - [self setMessage:finalMessage withFont:font messageColor:messageColor]; - if ([link length] != 0) { - [self addLinkRange:NSMakeRange(linkOffset, [link length]) - withName:@"" - linkColor:linkColor]; - } -} - - (void)setMessage:(NSString*)message withFont:(NSFont*)font messageColor:(NSColor*)messageColor {
diff --git a/ui/base/cocoa/controls/hyperlink_text_view_unittest.mm b/ui/base/cocoa/controls/hyperlink_text_view_unittest.mm index 37f4a544..1aca1a36 100644 --- a/ui/base/cocoa/controls/hyperlink_text_view_unittest.mm +++ b/ui/base/cocoa/controls/hyperlink_text_view_unittest.mm
@@ -64,64 +64,6 @@ EXPECT_FALSE([view_ isVerticallyResizable]); } -TEST_F(HyperlinkTextViewTest, LinkInsertion) { - // Test that setMessage:withLink:... inserts the link text. - [view_ setMessageAndLink:@"This is a short text message" - withLink:@"alarmingly " - atOffset:10 - font:GetDefaultFont() - messageColor:[NSColor blackColor] - linkColor:[NSColor blueColor]]; - EXPECT_NSEQ(@"This is a alarmingly short text message", - [[view_ textStorage] string]); - - // Test insertion at end - most common use case. - NSString* message=@"This is another test message "; - [view_ setMessageAndLink:message - withLink:@"with link" - atOffset:[message length] - font:GetDefaultFont() - messageColor:[NSColor blackColor] - linkColor:[NSColor blueColor]]; - EXPECT_NSEQ(@"This is another test message with link", - [[view_ textStorage] string]); -} - -TEST_F(HyperlinkTextViewTest, AttributesForMessageWithLink) { - // Verifies text attributes are set as expected for setMessageWithLink:... - [view_ setMessageAndLink:@"aaabbbbb" - withLink:@"xxxx" - atOffset:3 - font:GetDefaultFont() - messageColor:[NSColor blackColor] - linkColor:[NSColor blueColor]]; - - NSDictionary* attributes; - NSRange rangeLimit = NSMakeRange(0, 12); - NSRange range; - attributes = [[view_ textStorage] attributesAtIndex:0 - longestEffectiveRange:&range - inRange:rangeLimit]; - EXPECT_EQ(0U, range.location); - EXPECT_EQ(3U, range.length); - EXPECT_NSEQ(GetDefaultTextAttributes(), attributes); - - attributes = [[view_ textStorage] attributesAtIndex:3 - longestEffectiveRange:&range - inRange:rangeLimit]; - EXPECT_EQ(3U, range.location); - EXPECT_EQ(4U, range.length); - EXPECT_NSEQ(GetDefaultLinkAttributes(), attributes); - - attributes = [[view_ textStorage] attributesAtIndex:7 - longestEffectiveRange:&range - inRange:rangeLimit]; - EXPECT_EQ(7U, range.location); - EXPECT_EQ(5U, range.length); - EXPECT_NSEQ(GetDefaultTextAttributes(), attributes); - -} - TEST_F(HyperlinkTextViewTest, TestSetMessage) { // Verifies setMessage sets text and attributes properly. NSString* message = @"Test message";
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn new file mode 100644 index 0000000..53b002e --- /dev/null +++ b/ui/base/ime/BUILD.gn
@@ -0,0 +1,180 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") +import("//testing/test.gni") + +component("ime") { + output_name = "ui_base_ime" + sources = [ + "candidate_window.cc", + "candidate_window.h", + "chromeos/character_composer.cc", + "chromeos/character_composer.h", + "chromeos/component_extension_ime_manager.cc", + "chromeos/component_extension_ime_manager.h", + "chromeos/composition_text.cc", + "chromeos/composition_text.h", + "chromeos/extension_ime_util.cc", + "chromeos/extension_ime_util.h", + "chromeos/fake_ime_keyboard.cc", + "chromeos/fake_ime_keyboard.h", + "chromeos/fake_input_method_delegate.cc", + "chromeos/fake_input_method_delegate.h", + "chromeos/ime_bridge.cc", + "chromeos/ime_bridge.h", + "chromeos/ime_keyboard.cc", + "chromeos/ime_keyboard.h", + "chromeos/ime_keyboard_ozone.cc", + "chromeos/ime_keyboard_ozone.h", + "chromeos/ime_keyboard_x11.cc", + "chromeos/ime_keyboard_x11.h", + "chromeos/ime_keymap.cc", + "chromeos/ime_keymap.h", + "chromeos/input_method_delegate.h", + "chromeos/input_method_descriptor.cc", + "chromeos/input_method_descriptor.h", + "chromeos/input_method_manager.cc", + "chromeos/input_method_manager.h", + "chromeos/input_method_whitelist.cc", + "chromeos/input_method_whitelist.h", + "chromeos/mock_component_extension_ime_manager_delegate.cc", + "chromeos/mock_component_extension_ime_manager_delegate.h", + "chromeos/mock_ime_candidate_window_handler.cc", + "chromeos/mock_ime_candidate_window_handler.h", + "chromeos/mock_ime_engine_handler.cc", + "chromeos/mock_ime_engine_handler.h", + "chromeos/mock_ime_input_context_handler.cc", + "chromeos/mock_ime_input_context_handler.h", + "composition_text.cc", + "composition_text.h", + "composition_text_util_pango.cc", + "composition_text_util_pango.h", + "composition_underline.h", + "dummy_input_method_delegate.cc", + "dummy_input_method_delegate.h", + "infolist_entry.cc", + "infolist_entry.h", + "input_method.h", + "input_method_auralinux.cc", + "input_method_auralinux.h", + "input_method_base.cc", + "input_method_base.h", + "input_method_chromeos.cc", + "input_method_chromeos.h", + "input_method_delegate.h", + "input_method_factory.cc", + "input_method_factory.h", + "input_method_initializer.cc", + "input_method_initializer.h", + "input_method_mac.h", + "input_method_mac.mm", + "input_method_minimal.cc", + "input_method_minimal.h", + "input_method_observer.h", + "input_method_win.cc", + "input_method_win.h", + "linux/fake_input_method_context.cc", + "linux/fake_input_method_context.h", + "linux/fake_input_method_context_factory.cc", + "linux/fake_input_method_context_factory.h", + "linux/linux_input_method_context.h", + "linux/linux_input_method_context_factory.cc", + "linux/linux_input_method_context_factory.h", + "mock_input_method.cc", + "mock_input_method.h", + "remote_input_method_delegate_win.h", + "remote_input_method_win.cc", + "remote_input_method_win.h", + "text_input_client.cc", + "text_input_client.h", + "text_input_focus_manager.cc", + "text_input_focus_manager.h", + "text_input_type.h", + "ui_base_ime_export.h", + "win/imm32_manager.cc", + "win/imm32_manager.h", + "win/tsf_input_scope.cc", + "win/tsf_input_scope.h", + ] + + defines = [ "UI_BASE_IME_IMPLEMENTATION" ] + + deps = [ + "//base", + "//base/third_party/dynamic_annotations", + "//base:i18n", + "//net", + "//third_party/icu", + "//ui/base", + "//ui/events", + "//ui/gfx", + "//ui/gfx/geometry", + "//url", + ] + + if (!use_aura || (!is_linux && !use_ozone)) { + sources -= [ + "input_method_auralinux.cc", + "input_method_auralinux.h", + ] + } + + if (!toolkit_views && !use_aura) { + sources -= [ + "input_method_factory.cc", + "input_method_factory.h", + "input_method_minimal.cc", + "input_method_minimal.h", + ] + } + + if (is_chromeos) { + deps += [ + "//chromeos", + "//chromeos/ime:gencode", + ] + if (!use_ozone) { + sources -= [ + "chromeos/ime_keyboard_ozone.cc", + "chromeos/ime_keyboard_ozone.h", + ] + } + if (!use_x11) { + sources -= [ + "chromeos/ime_keyboard_x11.cc", + "chromeos/ime_keyboard_x11.h", + ] + } + } + + if (use_pango) { + configs += [ "//build/config/linux:pangocairo" ] + } else { + sources -= [ + "composition_text_util_pango.cc", + "composition_text_util_pango.h", + ] + } + if (use_x11) { + configs += [ "//build/config/linux:x11" ] + deps += [ "//ui/gfx/x" ] + } + + if (is_win) { + cflags = [ + "/wd4267", # TODO(jschuh): C4267: http://crbug.com/167187 size_t -> int. + "/wd4324", # Structure was padded due to __declspec(align()), which is + # uninteresting. + ] + libs = [ "imm32.lib" ] + } + + if (use_ozone) { + deps += [ + "//ui/ozone", + "//ui/events/ozone:events_ozone_layout", + ] + } +}
diff --git a/ui/base/ime/candidate_window.h b/ui/base/ime/candidate_window.h index 6ae6dd895..f8c967e 100644 --- a/ui/base/ime/candidate_window.h +++ b/ui/base/ime/candidate_window.h
@@ -10,19 +10,19 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "ui/base/ime/infolist_entry.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { // CandidateWindow represents the structure of candidates generated from IME. -class UI_BASE_EXPORT CandidateWindow { +class UI_BASE_IME_EXPORT CandidateWindow { public: enum Orientation { HORIZONTAL = 0, VERTICAL = 1, }; - struct UI_BASE_EXPORT CandidateWindowProperty { + struct UI_BASE_IME_EXPORT CandidateWindowProperty { CandidateWindowProperty(); virtual ~CandidateWindowProperty(); int page_size; @@ -38,7 +38,7 @@ }; // Represents a candidate entry. - struct UI_BASE_EXPORT Entry { + struct UI_BASE_IME_EXPORT Entry { Entry(); virtual ~Entry(); base::string16 value;
diff --git a/ui/base/ime/chromeos/character_composer.h b/ui/base/ime/chromeos/character_composer.h index 5d4267f..7c32d93 100644 --- a/ui/base/ime/chromeos/character_composer.h +++ b/ui/base/ime/chromeos/character_composer.h
@@ -8,14 +8,14 @@ #include <vector> #include "base/strings/string_util.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { class KeyEvent; // A class to recognize compose and dead key sequence. // Outputs composed character. -class UI_BASE_EXPORT CharacterComposer { +class UI_BASE_IME_EXPORT CharacterComposer { public: CharacterComposer(); ~CharacterComposer();
diff --git a/ui/base/ime/chromeos/component_extension_ime_manager.h b/ui/base/ime/chromeos/component_extension_ime_manager.h index 6d4032c..cdb9d757 100644 --- a/ui/base/ime/chromeos/component_extension_ime_manager.h +++ b/ui/base/ime/chromeos/component_extension_ime_manager.h
@@ -12,14 +12,14 @@ #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" class Profile; namespace chromeos { // Represents an engine in component extension IME. -struct UI_BASE_EXPORT ComponentExtensionEngine { +struct UI_BASE_IME_EXPORT ComponentExtensionEngine { ComponentExtensionEngine(); ~ComponentExtensionEngine(); std::string engine_id; // The engine id. @@ -33,7 +33,7 @@ }; // Represents a component extension IME. -struct UI_BASE_EXPORT ComponentExtensionIME { +struct UI_BASE_IME_EXPORT ComponentExtensionIME { ComponentExtensionIME(); ~ComponentExtensionIME(); std::string id; // extension id. @@ -45,7 +45,7 @@ }; // Provides an interface to list/load/unload for component extension IME. -class UI_BASE_EXPORT ComponentExtensionIMEManagerDelegate { +class UI_BASE_IME_EXPORT ComponentExtensionIMEManagerDelegate { public: ComponentExtensionIMEManagerDelegate(); virtual ~ComponentExtensionIMEManagerDelegate(); @@ -67,7 +67,7 @@ }; // This class manages component extension input method. -class UI_BASE_EXPORT ComponentExtensionIMEManager { +class UI_BASE_IME_EXPORT ComponentExtensionIMEManager { public: ComponentExtensionIMEManager(); virtual ~ComponentExtensionIMEManager();
diff --git a/ui/base/ime/chromeos/composition_text.h b/ui/base/ime/chromeos/composition_text.h index 6060928..90b8a8c 100644 --- a/ui/base/ime/chromeos/composition_text.h +++ b/ui/base/ime/chromeos/composition_text.h
@@ -10,11 +10,11 @@ #include "base/basictypes.h" #include "base/strings/string16.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { -class UI_BASE_EXPORT CompositionText { +class UI_BASE_IME_EXPORT CompositionText { public: enum UnderlineType { COMPOSITION_TEXT_UNDERLINE_SINGLE = 1,
diff --git a/ui/base/ime/chromeos/extension_ime_util.h b/ui/base/ime/chromeos/extension_ime_util.h index 3f52d390..08dbc7b 100644 --- a/ui/base/ime/chromeos/extension_ime_util.h +++ b/ui/base/ime/chromeos/extension_ime_util.h
@@ -8,7 +8,7 @@ #include <string> #include "base/auto_reset.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { @@ -38,60 +38,60 @@ // Returns InputMethodID for |engine_id| in |extension_id| of extension IME. // This function does not check |extension_id| is installed extension IME nor // |engine_id| is really a member of |extension_id|. -std::string UI_BASE_EXPORT GetInputMethodID(const std::string& extension_id, - const std::string& engine_id); +std::string UI_BASE_IME_EXPORT +GetInputMethodID(const std::string& extension_id, const std::string& engine_id); // Returns InputMethodID for |engine_id| in |extension_id| of component // extension IME, This function does not check |extension_id| is component one // nor |engine_id| is really a member of |extension_id|. -std::string UI_BASE_EXPORT GetComponentInputMethodID( - const std::string& extension_id, - const std::string& engine_id); +std::string UI_BASE_IME_EXPORT +GetComponentInputMethodID(const std::string& extension_id, + const std::string& engine_id); // Returns extension ID if |input_method_id| is extension IME ID or component // extension IME ID. Otherwise returns an empty string (""). -std::string UI_BASE_EXPORT GetExtensionIDFromInputMethodID( - const std::string& input_method_id); +std::string UI_BASE_IME_EXPORT +GetExtensionIDFromInputMethodID(const std::string& input_method_id); // Returns InputMethodID from engine id (e.g. xkb:fr:fra), or returns itself if // the |engine_id| is not a known engine id. // The caller must make sure the |engine_id| is from system input methods // instead of 3rd party input methods. -std::string UI_BASE_EXPORT GetInputMethodIDByEngineID( - const std::string& engine_id); +std::string UI_BASE_IME_EXPORT +GetInputMethodIDByEngineID(const std::string& engine_id); // Returns true if |input_method_id| is extension IME ID. This function does not // check |input_method_id| is installed extension IME. -bool UI_BASE_EXPORT IsExtensionIME(const std::string& input_method_id); +bool UI_BASE_IME_EXPORT IsExtensionIME(const std::string& input_method_id); // Returns true if |input_method_id| is component extension IME ID. This // function does not check |input_method_id| is really whitelisted one or not. // If you want to check |input_method_id| is whitelisted component extension // IME, please use ComponentExtensionIMEManager::IsWhitelisted instead. -bool UI_BASE_EXPORT IsComponentExtensionIME( - const std::string& input_method_id); +bool UI_BASE_IME_EXPORT +IsComponentExtensionIME(const std::string& input_method_id); // Returns true if the |input_method| is a member of |extension_id| of extension // IME, otherwise returns false. -bool UI_BASE_EXPORT IsMemberOfExtension(const std::string& input_method_id, +bool UI_BASE_IME_EXPORT IsMemberOfExtension(const std::string& input_method_id, const std::string& extension_id); // Returns true if the |input_method_id| is the extension based xkb keyboard, // otherwise returns false. -bool UI_BASE_EXPORT IsKeyboardLayoutExtension( - const std::string& input_method_id); +bool UI_BASE_IME_EXPORT +IsKeyboardLayoutExtension(const std::string& input_method_id); // Returns input method component id from the extension-based InputMethodID // for component IME extensions. This function does not check that // |input_method_id| is installed. -std::string UI_BASE_EXPORT - GetComponentIDByInputMethodID(const std::string& input_method_id); +std::string UI_BASE_IME_EXPORT +GetComponentIDByInputMethodID(const std::string& input_method_id); // Gets legacy xkb id (e.g. xkb:us::eng) from the new extension based xkb id // (e.g. _comp_ime_...xkb:us::eng). If the given id is not prefixed with // 'xkb:', just return the same as the given id. -std::string UI_BASE_EXPORT MaybeGetLegacyXkbId( - const std::string& input_method_id); +std::string UI_BASE_IME_EXPORT +MaybeGetLegacyXkbId(const std::string& input_method_id); } // namespace extension_ime_util
diff --git a/ui/base/ime/chromeos/fake_ime_keyboard.h b/ui/base/ime/chromeos/fake_ime_keyboard.h index 771aaab..02ba3080 100644 --- a/ui/base/ime/chromeos/fake_ime_keyboard.h +++ b/ui/base/ime/chromeos/fake_ime_keyboard.h
@@ -14,7 +14,7 @@ namespace chromeos { namespace input_method { -class UI_BASE_EXPORT FakeImeKeyboard : public ImeKeyboard { +class UI_BASE_IME_EXPORT FakeImeKeyboard : public ImeKeyboard { public: FakeImeKeyboard(); ~FakeImeKeyboard() override;
diff --git a/ui/base/ime/chromeos/fake_input_method_delegate.h b/ui/base/ime/chromeos/fake_input_method_delegate.h index 6ce324c..b9b7aa1 100644 --- a/ui/base/ime/chromeos/fake_input_method_delegate.h +++ b/ui/base/ime/chromeos/fake_input_method_delegate.h
@@ -11,12 +11,12 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "ui/base/ime/chromeos/input_method_delegate.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { namespace input_method { -class UI_BASE_EXPORT FakeInputMethodDelegate : public InputMethodDelegate { +class UI_BASE_IME_EXPORT FakeInputMethodDelegate : public InputMethodDelegate { public: typedef base::Callback<base::string16 (const std::string& language_code)> LanguageNameLocalizationCallback;
diff --git a/ui/base/ime/chromeos/ime_bridge.h b/ui/base/ime/chromeos/ime_bridge.h index c8c7203..caf631e 100644 --- a/ui/base/ime/chromeos/ime_bridge.h +++ b/ui/base/ime/chromeos/ime_bridge.h
@@ -12,7 +12,7 @@ #include "base/strings/string16.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace gfx { class Rect; @@ -27,7 +27,7 @@ class CompositionText; -class UI_BASE_EXPORT IMEInputContextHandlerInterface { +class UI_BASE_IME_EXPORT IMEInputContextHandlerInterface { public: // Called when the engine commit a text. virtual void CommitText(const std::string& text) = 0; @@ -43,7 +43,7 @@ // A interface to handle the engine handler method call. -class UI_BASE_EXPORT IMEEngineHandlerInterface { +class UI_BASE_IME_EXPORT IMEEngineHandlerInterface { public: typedef base::Callback<void (bool consumed)> KeyEventDoneCallback; @@ -111,7 +111,7 @@ }; // A interface to handle the candidate window related method call. -class UI_BASE_EXPORT IMECandidateWindowHandlerInterface { +class UI_BASE_IME_EXPORT IMECandidateWindowHandlerInterface { public: virtual ~IMECandidateWindowHandlerInterface() {} @@ -140,7 +140,7 @@ // IMEBridge provides access of each IME related handler. This class // is used for IME implementation. -class UI_BASE_EXPORT IMEBridge { +class UI_BASE_IME_EXPORT IMEBridge { public: virtual ~IMEBridge();
diff --git a/ui/base/ime/chromeos/ime_keyboard.h b/ui/base/ime/chromeos/ime_keyboard.h index 5fa5e13e..2c0e912 100644 --- a/ui/base/ime/chromeos/ime_keyboard.h +++ b/ui/base/ime/chromeos/ime_keyboard.h
@@ -10,7 +10,7 @@ #include "base/basictypes.h" #include "base/observer_list.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { namespace input_method { @@ -35,7 +35,7 @@ class InputMethodUtil; -class UI_BASE_EXPORT ImeKeyboard { +class UI_BASE_IME_EXPORT ImeKeyboard { public: class Observer { public: @@ -101,16 +101,16 @@ // On success, set current auto repeat rate on |out_rate| and returns true. // Returns false otherwise. This function is protected: for testability. - static UI_BASE_EXPORT bool GetAutoRepeatRateForTesting( + static UI_BASE_IME_EXPORT bool GetAutoRepeatRateForTesting( AutoRepeatRate* out_rate); // Returns false if |layout_name| contains a bad character. - static UI_BASE_EXPORT bool CheckLayoutNameForTesting( + static UI_BASE_IME_EXPORT bool CheckLayoutNameForTesting( const std::string& layout_name); // Note: At this moment, classes other than InputMethodManager should not // instantiate the ImeKeyboard class. - static UI_BASE_EXPORT ImeKeyboard* Create(); + static UI_BASE_IME_EXPORT ImeKeyboard* Create(); bool caps_lock_is_enabled_; std::string last_layout_;
diff --git a/ui/base/ime/chromeos/ime_keyboard_ozone.h b/ui/base/ime/chromeos/ime_keyboard_ozone.h index f41d9a0..e9813c7 100644 --- a/ui/base/ime/chromeos/ime_keyboard_ozone.h +++ b/ui/base/ime/chromeos/ime_keyboard_ozone.h
@@ -10,7 +10,7 @@ #include <string> #include "base/compiler_specific.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { class InputController; @@ -19,7 +19,7 @@ namespace chromeos { namespace input_method { -class UI_BASE_EXPORT ImeKeyboardOzone : public ImeKeyboard { +class UI_BASE_IME_EXPORT ImeKeyboardOzone : public ImeKeyboard { public: ImeKeyboardOzone(ui::InputController* controller); ~ImeKeyboardOzone() override;
diff --git a/ui/base/ime/chromeos/ime_keyboard_x11.h b/ui/base/ime/chromeos/ime_keyboard_x11.h index 6faad108..6b9da52 100644 --- a/ui/base/ime/chromeos/ime_keyboard_x11.h +++ b/ui/base/ime/chromeos/ime_keyboard_x11.h
@@ -24,12 +24,12 @@ #include "base/strings/stringprintf.h" #include "base/sys_info.h" #include "base/threading/thread_checker.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { namespace input_method { -class UI_BASE_EXPORT ImeKeyboardX11 : public ImeKeyboard { +class UI_BASE_IME_EXPORT ImeKeyboardX11 : public ImeKeyboard { public: ImeKeyboardX11(); ~ImeKeyboardX11() override;
diff --git a/ui/base/ime/chromeos/ime_keymap.h b/ui/base/ime/chromeos/ime_keymap.h index a4cdf0d9..4a87a6a 100644 --- a/ui/base/ime/chromeos/ime_keymap.h +++ b/ui/base/ime/chromeos/ime_keymap.h
@@ -7,16 +7,17 @@ #include <string> #include "base/basictypes.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/events/keycodes/keyboard_codes.h" namespace ui { // Translates the DOM4 key code string to ui::KeyboardCode. -UI_BASE_EXPORT KeyboardCode DomKeycodeToKeyboardCode(const std::string& code); +UI_BASE_IME_EXPORT KeyboardCode +DomKeycodeToKeyboardCode(const std::string& code); // Translates the ui::KeyboardCode to DOM4 key code string. -UI_BASE_EXPORT std::string KeyboardCodeToDomKeycode(KeyboardCode code); +UI_BASE_IME_EXPORT std::string KeyboardCodeToDomKeycode(KeyboardCode code); } // namespace ui
diff --git a/ui/base/ime/chromeos/input_method_descriptor.h b/ui/base/ime/chromeos/input_method_descriptor.h index 760da51e..188e370 100644 --- a/ui/base/ime/chromeos/input_method_descriptor.h +++ b/ui/base/ime/chromeos/input_method_descriptor.h
@@ -9,14 +9,14 @@ #include <vector> #include "base/basictypes.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "url/gurl.h" namespace chromeos { namespace input_method { // A structure which represents an input method. -class UI_BASE_EXPORT InputMethodDescriptor { +class UI_BASE_IME_EXPORT InputMethodDescriptor { public: InputMethodDescriptor(); InputMethodDescriptor(const std::string& id,
diff --git a/ui/base/ime/chromeos/input_method_manager.h b/ui/base/ime/chromeos/input_method_manager.h index d469e31..a7eb3a9 100644 --- a/ui/base/ime/chromeos/input_method_manager.h +++ b/ui/base/ime/chromeos/input_method_manager.h
@@ -12,7 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" class Profile; @@ -34,7 +34,7 @@ // This class manages input methodshandles. Classes can add themselves as // observers. Clients can get an instance of this library class by: // InputMethodManager::Get(). -class UI_BASE_EXPORT InputMethodManager { +class UI_BASE_IME_EXPORT InputMethodManager { public: enum UISessionState { STATE_LOGIN_SCREEN = 0, @@ -181,16 +181,16 @@ // Gets the global instance of InputMethodManager. Initialize() must be called // first. - static UI_BASE_EXPORT InputMethodManager* Get(); + static UI_BASE_IME_EXPORT InputMethodManager* Get(); // Sets the global instance. |instance| will be owned by the internal pointer // and deleted by Shutdown(). // TODO(nona): Instanciate InputMethodManagerImpl inside of this function once // crbug.com/164375 is fixed. - static UI_BASE_EXPORT void Initialize(InputMethodManager* instance); + static UI_BASE_IME_EXPORT void Initialize(InputMethodManager* instance); // Destroy the global instance. - static UI_BASE_EXPORT void Shutdown(); + static UI_BASE_IME_EXPORT void Shutdown(); // Get the current UI session state (e.g. login screen, lock screen, etc.). virtual UISessionState GetUISessionState() = 0;
diff --git a/ui/base/ime/chromeos/input_method_whitelist.h b/ui/base/ime/chromeos/input_method_whitelist.h index d2fc1ce..1da5fc117 100644 --- a/ui/base/ime/chromeos/input_method_whitelist.h +++ b/ui/base/ime/chromeos/input_method_whitelist.h
@@ -11,7 +11,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { namespace input_method { @@ -21,7 +21,7 @@ // A class which has white listed input method list. The list is generated by // gen_input_methods.py from input_methods.txt. -class UI_BASE_EXPORT InputMethodWhitelist { +class UI_BASE_IME_EXPORT InputMethodWhitelist { public: InputMethodWhitelist(); ~InputMethodWhitelist();
diff --git a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h index e2cead1..5bc4822 100644 --- a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h +++ b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h
@@ -6,12 +6,12 @@ #define UI_BASE_IME_CHROMEOS_MOCK_COMPONENT_EXTENSION_IME_MANAGER_DELEGATE_H_ #include "ui/base/ime/chromeos/component_extension_ime_manager.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { namespace input_method { -class UI_BASE_EXPORT MockComponentExtIMEManagerDelegate +class UI_BASE_IME_EXPORT MockComponentExtIMEManagerDelegate : public ComponentExtensionIMEManagerDelegate { public: MockComponentExtIMEManagerDelegate();
diff --git a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h index 2393eb3..9c53e33 100644 --- a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h +++ b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h
@@ -7,11 +7,11 @@ #include "ui/base/ime/candidate_window.h" #include "ui/base/ime/chromeos/ime_bridge.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { -class UI_BASE_EXPORT MockIMECandidateWindowHandler +class UI_BASE_IME_EXPORT MockIMECandidateWindowHandler : public IMECandidateWindowHandlerInterface { public: struct UpdateLookupTableArg {
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.h b/ui/base/ime/chromeos/mock_ime_engine_handler.h index 90eaf5c6..b37a62f 100644 --- a/ui/base/ime/chromeos/mock_ime_engine_handler.h +++ b/ui/base/ime/chromeos/mock_ime_engine_handler.h
@@ -6,12 +6,13 @@ #define UI_BASE_IME_CHROMEOS_MOCK_IME_ENGINE_HANDLER_H_ #include "ui/base/ime/chromeos/ime_bridge.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/events/event.h" namespace chromeos { -class UI_BASE_EXPORT MockIMEEngineHandler : public IMEEngineHandlerInterface { +class UI_BASE_IME_EXPORT MockIMEEngineHandler + : public IMEEngineHandlerInterface { public: MockIMEEngineHandler(); ~MockIMEEngineHandler() override;
diff --git a/ui/base/ime/chromeos/mock_ime_input_context_handler.h b/ui/base/ime/chromeos/mock_ime_input_context_handler.h index 3f993155..5eefe6e 100644 --- a/ui/base/ime/chromeos/mock_ime_input_context_handler.h +++ b/ui/base/ime/chromeos/mock_ime_input_context_handler.h
@@ -7,11 +7,11 @@ #include "ui/base/ime/chromeos/composition_text.h" #include "ui/base/ime/chromeos/ime_bridge.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace chromeos { -class UI_BASE_EXPORT MockIMEInputContextHandler +class UI_BASE_IME_EXPORT MockIMEInputContextHandler : public IMEInputContextHandlerInterface { public: struct UpdateCompositionTextArg {
diff --git a/ui/base/ime/composition_text.h b/ui/base/ime/composition_text.h index e4974bdd..063592e 100644 --- a/ui/base/ime/composition_text.h +++ b/ui/base/ime/composition_text.h
@@ -7,13 +7,13 @@ #include "base/strings/string16.h" #include "ui/base/ime/composition_underline.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/range/range.h" namespace ui { // A struct represents the status of an ongoing composition text. -struct UI_BASE_EXPORT CompositionText { +struct UI_BASE_IME_EXPORT CompositionText { CompositionText(); ~CompositionText();
diff --git a/ui/base/ime/composition_text_util_pango.h b/ui/base/ime/composition_text_util_pango.h index 1116fd9..ae53ebb 100644 --- a/ui/base/ime/composition_text_util_pango.h +++ b/ui/base/ime/composition_text_util_pango.h
@@ -6,7 +6,7 @@ #define UI_BASE_IME_COMPOSITION_TEXT_UTIL_PANGO_H_ #include "ui/base/glib/glib_integers.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" typedef struct _PangoAttrList PangoAttrList; @@ -16,7 +16,7 @@ // Extracts composition text information (text, underlines, selection range) // from given Gtk preedit data (utf-8 text, pango attributes, cursor position). -UI_BASE_EXPORT void ExtractCompositionTextFromGtkPreedit( +UI_BASE_IME_EXPORT void ExtractCompositionTextFromGtkPreedit( const gchar* utf8_text, PangoAttrList* attrs, int cursor_position,
diff --git a/ui/base/ime/dummy_input_method_delegate.h b/ui/base/ime/dummy_input_method_delegate.h index db5a5e3..5bbd382 100644 --- a/ui/base/ime/dummy_input_method_delegate.h +++ b/ui/base/ime/dummy_input_method_delegate.h
@@ -12,7 +12,7 @@ namespace ui { namespace internal { -class UI_BASE_EXPORT DummyInputMethodDelegate : public InputMethodDelegate { +class UI_BASE_IME_EXPORT DummyInputMethodDelegate : public InputMethodDelegate { public: DummyInputMethodDelegate(); ~DummyInputMethodDelegate() override;
diff --git a/ui/base/ime/infolist_entry.h b/ui/base/ime/infolist_entry.h index 3cb7672..a19d8541 100644 --- a/ui/base/ime/infolist_entry.h +++ b/ui/base/ime/infolist_entry.h
@@ -6,12 +6,12 @@ #define UI_BASE_IME_INFOLIST_ENTRY_H_ #include "base/strings/string16.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { // The data model of infolist window. -struct UI_BASE_EXPORT InfolistEntry { +struct UI_BASE_IME_EXPORT InfolistEntry { base::string16 title; base::string16 body; bool highlighted;
diff --git a/ui/base/ime/input_method_auralinux.h b/ui/base/ime/input_method_auralinux.h index be8851a..fbba625f 100644 --- a/ui/base/ime/input_method_auralinux.h +++ b/ui/base/ime/input_method_auralinux.h
@@ -14,7 +14,7 @@ // A ui::InputMethod implementation for Aura on Linux platforms. The // implementation details are separated to ui::LinuxInputMethodContext // interface. -class UI_BASE_EXPORT InputMethodAuraLinux +class UI_BASE_IME_EXPORT InputMethodAuraLinux : public InputMethodBase, public LinuxInputMethodContextDelegate { public:
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index 4d732cdd..ce76d40 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -10,7 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "ui/base/ime/input_method.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace gfx { class Rect; @@ -24,9 +24,9 @@ // A helper class providing functionalities shared among ui::InputMethod // implementations. -class UI_BASE_EXPORT InputMethodBase - : NON_EXPORTED_BASE(public InputMethod), - public base::SupportsWeakPtr<InputMethodBase> { +class UI_BASE_IME_EXPORT InputMethodBase + : NON_EXPORTED_BASE(public InputMethod), + public base::SupportsWeakPtr<InputMethodBase> { public: InputMethodBase(); ~InputMethodBase() override;
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h index 3de4157..f0912234 100644 --- a/ui/base/ime/input_method_chromeos.h +++ b/ui/base/ime/input_method_chromeos.h
@@ -20,7 +20,7 @@ namespace ui { // A ui::InputMethod implementation based on IBus. -class UI_BASE_EXPORT InputMethodChromeOS +class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase, public chromeos::IMEInputContextHandlerInterface { public:
diff --git a/ui/base/ime/input_method_delegate.h b/ui/base/ime/input_method_delegate.h index 080a8f6..eed2724 100644 --- a/ui/base/ime/input_method_delegate.h +++ b/ui/base/ime/input_method_delegate.h
@@ -5,7 +5,7 @@ #ifndef UI_BASE_IME_INPUT_METHOD_DELEGATE_H_ #define UI_BASE_IME_INPUT_METHOD_DELEGATE_H_ -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { @@ -15,7 +15,7 @@ // An interface implemented by the object that handles events sent back from an // ui::InputMethod implementation. -class UI_BASE_EXPORT InputMethodDelegate { +class UI_BASE_IME_EXPORT InputMethodDelegate { public: virtual ~InputMethodDelegate() {}
diff --git a/ui/base/ime/input_method_factory.h b/ui/base/ime/input_method_factory.h index 3debc82..d3a6e25 100644 --- a/ui/base/ime/input_method_factory.h +++ b/ui/base/ime/input_method_factory.h
@@ -9,7 +9,7 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "ui/base/ime/input_method_initializer.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/native_widget_types.h" namespace ui { @@ -20,12 +20,12 @@ class InputMethod; // Creates a new instance of InputMethod and returns it. -UI_BASE_EXPORT scoped_ptr<InputMethod> CreateInputMethod( +UI_BASE_IME_EXPORT scoped_ptr<InputMethod> CreateInputMethod( internal::InputMethodDelegate* delegate, gfx::AcceleratedWidget widget); // Makes CreateInputMethod return a MockInputMethod. -UI_BASE_EXPORT void SetUpInputMethodFactoryForTesting(); +UI_BASE_IME_EXPORT void SetUpInputMethodFactoryForTesting(); } // namespace ui;
diff --git a/ui/base/ime/input_method_initializer.h b/ui/base/ime/input_method_initializer.h index 065e53ed..787d7cc 100644 --- a/ui/base/ime/input_method_initializer.h +++ b/ui/base/ime/input_method_initializer.h
@@ -6,25 +6,25 @@ #define UI_BASE_IME_INPUT_METHOD_INITIALIZER_H_ #include "base/basictypes.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { // Initializes thread-local resources for input method. This function should be // called in the UI thread before input method is used. -UI_BASE_EXPORT void InitializeInputMethod(); +UI_BASE_IME_EXPORT void InitializeInputMethod(); // Shutdown thread-local resources for input method. This function should be // called in the UI thread after input method is used. -UI_BASE_EXPORT void ShutdownInputMethod(); +UI_BASE_IME_EXPORT void ShutdownInputMethod(); // Initializes thread-local resources for input method. This function is // intended to be called from Setup function of unit tests. -UI_BASE_EXPORT void InitializeInputMethodForTesting(); +UI_BASE_IME_EXPORT void InitializeInputMethodForTesting(); // Initializes thread-local resources for input method. This function is // intended to be called from TearDown function of unit tests. -UI_BASE_EXPORT void ShutdownInputMethodForTesting(); +UI_BASE_IME_EXPORT void ShutdownInputMethodForTesting(); } // namespace ui
diff --git a/ui/base/ime/input_method_mac.h b/ui/base/ime/input_method_mac.h index d910fa1..24c84309 100644 --- a/ui/base/ime/input_method_mac.h +++ b/ui/base/ime/input_method_mac.h
@@ -13,7 +13,7 @@ // On the Mac, key events don't pass through InputMethod. // Instead, NSTextInputClient calls are bridged to the currently focused // ui::TextInputClient object. -class UI_BASE_EXPORT InputMethodMac : public InputMethodBase { +class UI_BASE_IME_EXPORT InputMethodMac : public InputMethodBase { public: explicit InputMethodMac(internal::InputMethodDelegate* delegate); ~InputMethodMac() override;
diff --git a/ui/base/ime/input_method_minimal.h b/ui/base/ime/input_method_minimal.h index b797eb8..d66810e5 100644 --- a/ui/base/ime/input_method_minimal.h +++ b/ui/base/ime/input_method_minimal.h
@@ -11,7 +11,7 @@ // A minimal implementation of ui::InputMethod, which supports only the direct // input without any compositions or conversions. -class UI_BASE_EXPORT InputMethodMinimal : public InputMethodBase { +class UI_BASE_IME_EXPORT InputMethodMinimal : public InputMethodBase { public: explicit InputMethodMinimal(internal::InputMethodDelegate* delegate); ~InputMethodMinimal() override;
diff --git a/ui/base/ime/input_method_observer.h b/ui/base/ime/input_method_observer.h index d3432c9..945545ec 100644 --- a/ui/base/ime/input_method_observer.h +++ b/ui/base/ime/input_method_observer.h
@@ -5,14 +5,14 @@ #ifndef UI_BASE_IME_INPUT_METHOD_OBSERVER_H_ #define UI_BASE_IME_INPUT_METHOD_OBSERVER_H_ -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { class InputMethod; class TextInputClient; -class UI_BASE_EXPORT InputMethodObserver { +class UI_BASE_IME_EXPORT InputMethodObserver { public: virtual ~InputMethodObserver() {}
diff --git a/ui/base/ime/input_method_win.h b/ui/base/ime/input_method_win.h index b6d53208..4bddcfb 100644 --- a/ui/base/ime/input_method_win.h +++ b/ui/base/ime/input_method_win.h
@@ -17,7 +17,7 @@ namespace ui { // A common InputMethod implementation based on IMM32. -class UI_BASE_EXPORT InputMethodWin : public InputMethodBase { +class UI_BASE_IME_EXPORT InputMethodWin : public InputMethodBase { public: InputMethodWin(internal::InputMethodDelegate* delegate, HWND toplevel_window_handle);
diff --git a/ui/base/ime/linux/linux_input_method_context.h b/ui/base/ime/linux/linux_input_method_context.h index 0bcfd0a4..09fc04bc 100644 --- a/ui/base/ime/linux/linux_input_method_context.h +++ b/ui/base/ime/linux/linux_input_method_context.h
@@ -7,7 +7,7 @@ #include "base/strings/string16.h" #include "ui/base/ime/text_input_type.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace gfx { class Rect; @@ -20,7 +20,7 @@ // An interface of input method context for input method frameworks on // GNU/Linux and likes. -class UI_BASE_EXPORT LinuxInputMethodContext { +class UI_BASE_IME_EXPORT LinuxInputMethodContext { public: virtual ~LinuxInputMethodContext() {} @@ -42,7 +42,7 @@ }; // An interface of callback functions called from LinuxInputMethodContext. -class UI_BASE_EXPORT LinuxInputMethodContextDelegate { +class UI_BASE_IME_EXPORT LinuxInputMethodContextDelegate { public: virtual ~LinuxInputMethodContextDelegate() {}
diff --git a/ui/base/ime/linux/linux_input_method_context_factory.h b/ui/base/ime/linux/linux_input_method_context_factory.h index af2a3a0c..8f07943 100644 --- a/ui/base/ime/linux/linux_input_method_context_factory.h +++ b/ui/base/ime/linux/linux_input_method_context_factory.h
@@ -6,7 +6,7 @@ #define UI_BASE_IME_LINUX_LINUX_INPUT_METHOD_CONTEXT_FACTORY_H_ #include "base/memory/scoped_ptr.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { @@ -16,7 +16,7 @@ // An interface that lets different Linux platforms override the // CreateInputMethodContext function declared here to return native input method // contexts. -class UI_BASE_EXPORT LinuxInputMethodContextFactory { +class UI_BASE_IME_EXPORT LinuxInputMethodContextFactory { public: // Returns the current active factory or NULL. static const LinuxInputMethodContextFactory* instance();
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index b88787c7..5d85482 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h
@@ -12,7 +12,7 @@ #include "base/observer_list.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method_observer.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { @@ -23,7 +23,8 @@ // of this class as the global input method with calling // SetUpInputMethodFactoryForTesting() which is declared in // ui/base/ime/input_method_factory.h -class UI_BASE_EXPORT MockInputMethod : NON_EXPORTED_BASE(public InputMethod) { +class UI_BASE_IME_EXPORT MockInputMethod + : NON_EXPORTED_BASE(public InputMethod) { public: explicit MockInputMethod(internal::InputMethodDelegate* delegate); ~MockInputMethod() override;
diff --git a/ui/base/ime/remote_input_method_delegate_win.h b/ui/base/ime/remote_input_method_delegate_win.h index 0946331..b65d8c35 100644 --- a/ui/base/ime/remote_input_method_delegate_win.h +++ b/ui/base/ime/remote_input_method_delegate_win.h
@@ -8,7 +8,7 @@ #include <vector> #include "base/basictypes.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/geometry/rect.h" namespace ui { @@ -16,7 +16,7 @@ // An interface implemented by the object to forward events that should be // handled by the IME which is running in the remote metro_driver process. -class UI_BASE_EXPORT RemoteInputMethodDelegateWin { +class UI_BASE_IME_EXPORT RemoteInputMethodDelegateWin { public: virtual ~RemoteInputMethodDelegateWin() {}
diff --git a/ui/base/ime/remote_input_method_win.h b/ui/base/ime/remote_input_method_win.h index 5258f3d..3f822cf 100644 --- a/ui/base/ime/remote_input_method_win.h +++ b/ui/base/ime/remote_input_method_win.h
@@ -13,7 +13,7 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/native_widget_types.h" namespace ui { @@ -46,11 +46,11 @@ // Returns the public interface of RemoteInputMethodWin. // Caveats: Currently only one instance of RemoteInputMethodWin is able to run // at the same time. -UI_BASE_EXPORT scoped_ptr<InputMethod> CreateRemoteInputMethodWin( +UI_BASE_IME_EXPORT scoped_ptr<InputMethod> CreateRemoteInputMethodWin( internal::InputMethodDelegate* delegate); // Private interface of RemoteInputMethodWin. -class UI_BASE_EXPORT RemoteInputMethodPrivateWin { +class UI_BASE_IME_EXPORT RemoteInputMethodPrivateWin { public: RemoteInputMethodPrivateWin();
diff --git a/ui/base/ime/text_input_client.h b/ui/base/ime/text_input_client.h index 582a0d3..19c602c 100644 --- a/ui/base/ime/text_input_client.h +++ b/ui/base/ime/text_input_client.h
@@ -11,7 +11,7 @@ #include "ui/base/ime/composition_text.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/range/range.h" @@ -22,7 +22,7 @@ namespace ui { // An interface implemented by a View that needs text input support. -class UI_BASE_EXPORT TextInputClient { +class UI_BASE_IME_EXPORT TextInputClient { public: virtual ~TextInputClient();
diff --git a/ui/base/ime/text_input_focus_manager.h b/ui/base/ime/text_input_focus_manager.h index 22f47e3..88bf3fce 100644 --- a/ui/base/ime/text_input_focus_manager.h +++ b/ui/base/ime/text_input_focus_manager.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/threading/thread_checker.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" template <typename T> struct DefaultSingletonTraits; @@ -16,7 +16,7 @@ class TextInputClient; // Manages the focused TextInputClient across windows and their contents. -class UI_BASE_EXPORT TextInputFocusManager { +class UI_BASE_IME_EXPORT TextInputFocusManager { public: static TextInputFocusManager* GetInstance();
diff --git a/ui/base/ime/ui_base_ime.gyp b/ui/base/ime/ui_base_ime.gyp new file mode 100644 index 0000000..e58be98 --- /dev/null +++ b/ui/base/ime/ui_base_ime.gyp
@@ -0,0 +1,186 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + # GN version: //ui/base/ime + 'target_name': 'ui_base_ime', + 'type': '<(component)', + 'dependencies': [ + '../../../base/base.gyp:base', + '../../../base/base.gyp:base_i18n', + '../../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../../../skia/skia.gyp:skia', + '../../../third_party/icu/icu.gyp:icui18n', + '../../../third_party/icu/icu.gyp:icuuc', + '../../../url/url.gyp:url_lib', + '../../events/events.gyp:events', + '../../events/events.gyp:events_base', + '../../gfx/gfx.gyp:gfx', + '../../gfx/gfx.gyp:gfx_geometry', + '../ui_base.gyp:ui_base', + ], + 'defines': [ + 'UI_BASE_IME_IMPLEMENTATION', + ], + 'sources' : [ + 'candidate_window.cc', + 'candidate_window.h', + 'chromeos/character_composer.cc', + 'chromeos/character_composer.h', + 'chromeos/component_extension_ime_manager.cc', + 'chromeos/component_extension_ime_manager.h', + 'chromeos/composition_text.cc', + 'chromeos/composition_text.h', + 'chromeos/extension_ime_util.cc', + 'chromeos/extension_ime_util.h', + 'chromeos/fake_ime_keyboard.cc', + 'chromeos/fake_ime_keyboard.h', + 'chromeos/fake_input_method_delegate.cc', + 'chromeos/fake_input_method_delegate.h', + 'chromeos/ime_bridge.cc', + 'chromeos/ime_bridge.h', + 'chromeos/ime_keyboard.cc', + 'chromeos/ime_keyboard.h', + 'chromeos/ime_keyboard_ozone.cc', + 'chromeos/ime_keyboard_ozone.h', + 'chromeos/ime_keyboard_x11.cc', + 'chromeos/ime_keyboard_x11.h', + 'chromeos/ime_keymap.cc', + 'chromeos/ime_keymap.h', + 'chromeos/input_method_delegate.h', + 'chromeos/input_method_descriptor.cc', + 'chromeos/input_method_descriptor.h', + 'chromeos/input_method_manager.cc', + 'chromeos/input_method_manager.h', + 'chromeos/input_method_whitelist.cc', + 'chromeos/input_method_whitelist.h', + 'chromeos/mock_component_extension_ime_manager_delegate.cc', + 'chromeos/mock_component_extension_ime_manager_delegate.h', + 'chromeos/mock_ime_candidate_window_handler.cc', + 'chromeos/mock_ime_candidate_window_handler.h', + 'chromeos/mock_ime_engine_handler.cc', + 'chromeos/mock_ime_engine_handler.h', + 'chromeos/mock_ime_input_context_handler.cc', + 'chromeos/mock_ime_input_context_handler.h', + 'composition_text.cc', + 'composition_text.h', + 'composition_text_util_pango.cc', + 'composition_text_util_pango.h', + 'composition_underline.h', + 'dummy_input_method_delegate.cc', + 'dummy_input_method_delegate.h', + 'infolist_entry.cc', + 'infolist_entry.h', + 'input_method.h', + 'input_method_auralinux.cc', + 'input_method_auralinux.h', + 'input_method_base.cc', + 'input_method_base.h', + 'input_method_chromeos.cc', + 'input_method_chromeos.h', + 'input_method_delegate.h', + 'input_method_factory.cc', + 'input_method_factory.h', + 'input_method_initializer.cc', + 'input_method_initializer.h', + 'input_method_mac.h', + 'input_method_mac.mm', + 'input_method_minimal.cc', + 'input_method_minimal.h', + 'input_method_observer.h', + 'input_method_win.cc', + 'input_method_win.h', + 'linux/fake_input_method_context.cc', + 'linux/fake_input_method_context.h', + 'linux/fake_input_method_context_factory.cc', + 'linux/fake_input_method_context_factory.h', + 'linux/linux_input_method_context.h', + 'linux/linux_input_method_context_factory.cc', + 'linux/linux_input_method_context_factory.h', + 'mock_input_method.cc', + 'mock_input_method.h', + 'remote_input_method_delegate_win.h', + 'remote_input_method_win.cc', + 'remote_input_method_win.h', + 'text_input_client.cc', + 'text_input_client.h', + 'text_input_focus_manager.cc', + 'text_input_focus_manager.h', + 'text_input_type.h', + 'ui_base_ime_export.h', + 'win/imm32_manager.cc', + 'win/imm32_manager.h', + 'win/tsf_input_scope.cc', + 'win/tsf_input_scope.h', + ], + 'conditions': [ + ['use_ozone==1', { + 'dependencies': [ + '../../events/ozone/events_ozone.gyp:events_ozone_layout', + '../../ozone/ozone.gyp:ozone', + ], + }], + ['use_pango==1', { + 'dependencies': [ + '../../../build/linux/system.gyp:pangocairo', + ], + }], + ['OS=="win"', { + # TODO(jschuh): C4267: http://crbug.com/167187 size_t -> int + # C4324 is structure was padded due to __declspec(align()), which is + # uninteresting. + 'msvs_disabled_warnings': [ 4267, 4324 ], + 'link_settings': { + 'libraries': [ + '-limm32.lib', + ], + }, + }], + ['use_x11==1', { + 'dependencies': [ + '../../../build/linux/system.gyp:x11', + '../../gfx/x/gfx_x11.gyp:gfx_x11', + ], + }], + ['toolkit_views==0 and use_aura==0', { + 'sources!': [ + 'input_method_factory.cc', + 'input_method_factory.h', + 'input_method_minimal.cc', + 'input_method_minimal.h', + ], + }], + ['chromeos==1', { + 'dependencies': [ + '../../../chromeos/chromeos.gyp:chromeos', + ], + }], + ['use_aura==0 or (desktop_linux==0 and use_ozone==0)', { + 'sources!': [ + 'input_method_auralinux.cc', + 'input_method_auralinux.h', + 'linux/fake_input_method_context.cc', + 'linux/fake_input_method_context.h', + 'linux/fake_input_method_context_factory.cc', + 'linux/fake_input_method_context_factory.h', + 'linux/linux_input_method_context.h', + 'linux/linux_input_method_context_factory.cc', + 'linux/linux_input_method_context_factory.h', + ], + }], + ['use_x11==0', { + 'sources!': [ + 'composition_text_util_pango.cc', + 'composition_text_util_pango.h', + ], + }], + ], + }, + ], +}
diff --git a/ui/base/ime/ui_base_ime_export.h b/ui/base/ime/ui_base_ime_export.h new file mode 100644 index 0000000..955502f --- /dev/null +++ b/ui/base/ime/ui_base_ime_export.h
@@ -0,0 +1,34 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_IME_UI_BASE_IME_EXPORT_H_ +#define UI_BASE_IME_UI_BASE_IME_EXPORT_H_ + +#if defined(COMPONENT_BUILD) + +#if defined(WIN32) + +#if defined(UI_BASE_IME_IMPLEMENTATION) +#define UI_BASE_IME_EXPORT __declspec(dllexport) +#else +#define UI_BASE_IME_EXPORT __declspec(dllimport) +#endif + +#else // !defined(WIN32) + +#if defined(UI_BASE_IME_IMPLEMENTATION) +#define UI_BASE_IME_EXPORT __attribute__((visibility("default"))) +#else +#define UI_BASE_IME_EXPORT +#endif + +#endif + +#else // !defined(COMPONENT_BUILD) + +#define UI_BASE_IME_EXPORT + +#endif + +#endif // UI_BASE_IME_UI_BASE_IME_EXPORT_H_
diff --git a/ui/base/ime/win/imm32_manager.h b/ui/base/ime/win/imm32_manager.h index 83a03f4..a1e473c 100644 --- a/ui/base/ime/win/imm32_manager.h +++ b/ui/base/ime/win/imm32_manager.h
@@ -14,7 +14,7 @@ #include "base/i18n/rtl.h" #include "base/strings/string16.h" #include "ui/base/ime/text_input_mode.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" #include "ui/gfx/geometry/rect.h" namespace ui { @@ -74,7 +74,7 @@ // hand, we can NEVER disable either TSF or CUAS in Windows Vista, i.e. // THIS CLASS IS NOT ONLY USED ON THE INPUT CONTEXTS OF EAST-ASIAN // LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES. -class UI_BASE_EXPORT IMM32Manager { +class UI_BASE_IME_EXPORT IMM32Manager { public: IMM32Manager(); virtual ~IMM32Manager();
diff --git a/ui/base/ime/win/tsf_input_scope.h b/ui/base/ime/win/tsf_input_scope.h index 536d395..6d954055 100644 --- a/ui/base/ime/win/tsf_input_scope.h +++ b/ui/base/ime/win/tsf_input_scope.h
@@ -12,7 +12,7 @@ #include "base/basictypes.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" -#include "ui/base/ui_base_export.h" +#include "ui/base/ime/ui_base_ime_export.h" namespace ui { namespace tsf_inputscope { @@ -20,7 +20,7 @@ // Returns InputScope list corresoponding to ui::TextInputType and // ui::TextInputMode. // This function is only used from following functions but declared for test. -UI_BASE_EXPORT std::vector<InputScope> GetInputScopes( +UI_BASE_IME_EXPORT std::vector<InputScope> GetInputScopes( TextInputType text_input_type, TextInputMode text_input_mode); @@ -30,14 +30,15 @@ // in the target field. // The returned instance has 0 reference count. The caller must maintain its // reference count. -UI_BASE_EXPORT ITfInputScope* CreateInputScope(TextInputType text_input_type, - TextInputMode text_input_mode); +UI_BASE_IME_EXPORT ITfInputScope* CreateInputScope( + TextInputType text_input_type, + TextInputMode text_input_mode); // A wrapper of the SetInputScopes API exported by msctf.dll. // http://msdn.microsoft.com/en-us/library/windows/desktop/ms629026.aspx // Does nothing on Windows XP in case TSF is disabled. // NOTE: For TSF-aware window, you should use ITfInputScope instead. -UI_BASE_EXPORT void SetInputScopeForTsfUnawareWindow( +UI_BASE_IME_EXPORT void SetInputScopeForTsfUnawareWindow( HWND window_handle, TextInputType text_input_type, TextInputMode text_input_mode);
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp index 3b004735..1d7614cd 100644 --- a/ui/base/ui_base.gyp +++ b/ui/base/ui_base.gyp
@@ -200,94 +200,6 @@ 'idle/idle_win.cc', 'idle/screensaver_window_finder_x11.cc', 'idle/screensaver_window_finder_x11.h', - 'ime/candidate_window.cc', - 'ime/candidate_window.h', - 'ime/chromeos/character_composer.cc', - 'ime/chromeos/character_composer.h', - 'ime/chromeos/component_extension_ime_manager.cc', - 'ime/chromeos/component_extension_ime_manager.h', - 'ime/chromeos/composition_text.cc', - 'ime/chromeos/composition_text.h', - 'ime/chromeos/extension_ime_util.cc', - 'ime/chromeos/extension_ime_util.h', - 'ime/chromeos/fake_ime_keyboard.cc', - 'ime/chromeos/fake_ime_keyboard.h', - 'ime/chromeos/fake_input_method_delegate.cc', - 'ime/chromeos/fake_input_method_delegate.h', - 'ime/chromeos/ime_bridge.cc', - 'ime/chromeos/ime_bridge.h', - 'ime/chromeos/ime_keyboard.cc', - 'ime/chromeos/ime_keyboard.h', - 'ime/chromeos/ime_keyboard_ozone.cc', - 'ime/chromeos/ime_keyboard_ozone.h', - 'ime/chromeos/ime_keyboard_x11.cc', - 'ime/chromeos/ime_keyboard_x11.h', - 'ime/chromeos/ime_keymap.cc', - 'ime/chromeos/ime_keymap.h', - 'ime/chromeos/input_method_delegate.h', - 'ime/chromeos/input_method_descriptor.cc', - 'ime/chromeos/input_method_descriptor.h', - 'ime/chromeos/input_method_manager.cc', - 'ime/chromeos/input_method_manager.h', - 'ime/chromeos/input_method_whitelist.cc', - 'ime/chromeos/input_method_whitelist.h', - 'ime/chromeos/mock_component_extension_ime_manager_delegate.cc', - 'ime/chromeos/mock_component_extension_ime_manager_delegate.h', - 'ime/chromeos/mock_ime_candidate_window_handler.cc', - 'ime/chromeos/mock_ime_candidate_window_handler.h', - 'ime/chromeos/mock_ime_engine_handler.cc', - 'ime/chromeos/mock_ime_engine_handler.h', - 'ime/chromeos/mock_ime_input_context_handler.cc', - 'ime/chromeos/mock_ime_input_context_handler.h', - 'ime/composition_text.cc', - 'ime/composition_text.h', - 'ime/composition_text_util_pango.cc', - 'ime/composition_text_util_pango.h', - 'ime/composition_underline.h', - 'ime/dummy_input_method_delegate.cc', - 'ime/dummy_input_method_delegate.h', - 'ime/infolist_entry.cc', - 'ime/infolist_entry.h', - 'ime/input_method.h', - 'ime/input_method_auralinux.cc', - 'ime/input_method_auralinux.h', - 'ime/input_method_base.cc', - 'ime/input_method_base.h', - 'ime/input_method_chromeos.cc', - 'ime/input_method_chromeos.h', - 'ime/input_method_delegate.h', - 'ime/input_method_factory.cc', - 'ime/input_method_factory.h', - 'ime/input_method_initializer.cc', - 'ime/input_method_initializer.h', - 'ime/input_method_mac.h', - 'ime/input_method_mac.mm', - 'ime/input_method_minimal.cc', - 'ime/input_method_minimal.h', - 'ime/input_method_observer.h', - 'ime/input_method_win.cc', - 'ime/input_method_win.h', - 'ime/linux/fake_input_method_context.cc', - 'ime/linux/fake_input_method_context.h', - 'ime/linux/fake_input_method_context_factory.cc', - 'ime/linux/fake_input_method_context_factory.h', - 'ime/linux/linux_input_method_context.h', - 'ime/linux/linux_input_method_context_factory.cc', - 'ime/linux/linux_input_method_context_factory.h', - 'ime/mock_input_method.cc', - 'ime/mock_input_method.h', - 'ime/remote_input_method_delegate_win.h', - 'ime/remote_input_method_win.cc', - 'ime/remote_input_method_win.h', - 'ime/text_input_client.cc', - 'ime/text_input_client.h', - 'ime/text_input_focus_manager.cc', - 'ime/text_input_focus_manager.h', - 'ime/text_input_type.h', - 'ime/win/imm32_manager.cc', - 'ime/win/imm32_manager.h', - 'ime/win/tsf_input_scope.cc', - 'ime/win/tsf_input_scope.h', 'l10n/formatter.cc', 'l10n/formatter.h', 'l10n/l10n_font_util.cc', @@ -582,7 +494,6 @@ }, 'link_settings': { 'libraries': [ - '-limm32.lib', '-ld2d1.lib', '-ldwmapi.lib', '-loleacc.lib', @@ -706,14 +617,6 @@ # ui to be a hard dependency for all its users. 'hard_dependency': 1, }], - ['toolkit_views==0 and use_aura==0', { - 'sources!': [ - 'ime/input_method_factory.cc', - 'ime/input_method_factory.h', - 'ime/input_method_minimal.cc', - 'ime/input_method_minimal.h', - ], - }], ['chromeos==1', { 'dependencies': [ '../../chromeos/chromeos.gyp:chromeos', @@ -726,31 +629,6 @@ 'idle/screensaver_window_finder_x11.h', ], }], - ['OS!="win"', { - 'sources!': [ - 'ime/input_method_imm32.cc', - 'ime/input_method_imm32.h', - ], - }], - ['use_aura==0 or (desktop_linux==0 and use_ozone==0)', { - 'sources!': [ - 'ime/input_method_auralinux.cc', - 'ime/input_method_auralinux.h', - 'ime/linux/fake_input_method_context.cc', - 'ime/linux/fake_input_method_context.h', - 'ime/linux/fake_input_method_context_factory.cc', - 'ime/linux/fake_input_method_context_factory.h', - 'ime/linux/linux_input_method_context.h', - 'ime/linux/linux_input_method_context_factory.cc', - 'ime/linux/linux_input_method_context_factory.h', - ], - }], - ['use_x11==0', { - 'sources!': [ - 'ime/composition_text_util_pango.cc', - 'ime/composition_text_util_pango.h', - ], - }], ], }, { @@ -780,6 +658,9 @@ 'conditions': [ ['OS!="ios"', { 'type': 'static_library', + 'dependecies': [ + 'ime/ui_base_ime.gyp:ui_base_ime', + ], 'sources': [ 'ime/dummy_input_method.cc', 'ime/dummy_input_method.h',
diff --git a/ui/base/ui_base_tests.gyp b/ui/base/ui_base_tests.gyp index 287761d4..fe1ccc2 100644 --- a/ui/base/ui_base_tests.gyp +++ b/ui/base/ui_base_tests.gyp
@@ -26,6 +26,7 @@ '../resources/ui_resources.gyp:ui_resources', '../resources/ui_resources.gyp:ui_test_pak', '../strings/ui_strings.gyp:ui_strings', + 'ime/ui_base_ime.gyp:ui_base_ime', 'ui_base.gyp:ui_base', 'ui_base.gyp:ui_base_test_support', ],
diff --git a/ui/chromeos/BUILD.gn b/ui/chromeos/BUILD.gn index 7cd2171..a25e2813 100644 --- a/ui/chromeos/BUILD.gn +++ b/ui/chromeos/BUILD.gn
@@ -49,6 +49,7 @@ "//skia", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/chromeos/resources", "//ui/chromeos/strings", "//ui/events",
diff --git a/ui/chromeos/ui_chromeos.gyp b/ui/chromeos/ui_chromeos.gyp index 7c5fcba..1b7ee6c 100644 --- a/ui/chromeos/ui_chromeos.gyp +++ b/ui/chromeos/ui_chromeos.gyp
@@ -51,6 +51,7 @@ '../../chromeos/chromeos.gyp:power_manager_proto', '../../skia/skia.gyp:skia', '../aura/aura.gyp:aura', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../events/events.gyp:events', '../events/events.gyp:gesture_detection',
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index b7ed3737..bea2eb7 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -31,6 +31,7 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator_collection.h" #include "ui/gfx/frame_time.h" +#include "ui/gfx/hud_font.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_switches.h" @@ -137,6 +138,7 @@ settings.impl_side_painting = IsUIImplSidePaintingEnabled(); settings.use_zero_copy = IsUIZeroCopyEnabled(); + settings.hud_typeface = ui::GetHudTypeface(); base::TimeTicks before_create = base::TimeTicks::Now(); if (compositor_thread_loop_.get()) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index ec36a0a..9bc7f884 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -244,8 +244,8 @@ void DidBeginMainFrame() override {} void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override; - void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) override {}
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index c5de632..4625e0d 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -726,9 +726,10 @@ cc_layer_->RequestCopyOfOutput(request.Pass()); } -void Layer::PaintContents(SkCanvas* sk_canvas, - const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) { +void Layer::PaintContents( + SkCanvas* sk_canvas, + const gfx::Rect& clip, + ContentLayerClient::PaintingControlSetting painting_control) { TRACE_EVENT1("ui", "Layer::PaintContents", "name", name_); scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( sk_canvas, device_scale_factor_)); @@ -738,7 +739,7 @@ scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList( const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) { + ContentLayerClient::PaintingControlSetting painting_control) { NOTIMPLEMENTED(); return cc::DisplayItemList::Create(); }
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index d49101b..598739e 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -340,10 +340,10 @@ void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - ContentLayerClient::GraphicsContextStatus gc_status) override; + ContentLayerClient::PaintingControlSetting painting_control) override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, - GraphicsContextStatus gc_status) override; + ContentLayerClient::PaintingControlSetting painting_control) override; bool FillsBoundsCompletely() const override; cc::Layer* cc_layer() { return cc_layer_; }
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index a837e9b..c7e14c0 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc
@@ -74,17 +74,6 @@ DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone) << "If running tests, ensure that main() is calling " << "gfx::GLSurface::InitializeOneOffForTests()"; - -#if defined(OS_CHROMEOS) - bool use_thread = !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUIDisableThreadedCompositing); -#else - bool use_thread = false; -#endif - if (use_thread) { - compositor_thread_.reset(new base::Thread("Browser Compositor")); - compositor_thread_->Start(); - } } InProcessContextFactory::~InProcessContextFactory() {
diff --git a/ui/events/android/scroller.h b/ui/events/android/scroller.h index f276a836..37d41cd 100644 --- a/ui/events/android/scroller.h +++ b/ui/events/android/scroller.h
@@ -28,12 +28,12 @@ }; explicit Scroller(const Config& config); - virtual ~Scroller(); + ~Scroller() override; // GestureCurve implementation. - virtual bool ComputeScrollOffset(base::TimeTicks time, - gfx::Vector2dF* offset, - gfx::Vector2dF* velocity) override; + bool ComputeScrollOffset(base::TimeTicks time, + gfx::Vector2dF* offset, + gfx::Vector2dF* velocity) override; // Start scrolling by providing a starting point and the distance to travel. // The default value of 250 milliseconds will be used for the duration.
diff --git a/ui/events/devices/input_device.cc b/ui/events/devices/input_device.cc index e940c956..d57af431 100644 --- a/ui/events/devices/input_device.cc +++ b/ui/events/devices/input_device.cc
@@ -15,10 +15,8 @@ : id(kInvalidId), type(InputDeviceType::INPUT_DEVICE_UNKNOWN) { } -InputDevice::InputDevice(unsigned int id, - InputDeviceType type, - const std::string& name) - : id(id), type(type), name(name) { +InputDevice::InputDevice(unsigned int id, InputDeviceType type) + : id(id), type(type) { } InputDevice::~InputDevice() {
diff --git a/ui/events/devices/input_device.h b/ui/events/devices/input_device.h index c5775844..70ae192 100644 --- a/ui/events/devices/input_device.h +++ b/ui/events/devices/input_device.h
@@ -24,7 +24,7 @@ // Creates an invalid input device. InputDevice(); - InputDevice(unsigned int id, InputDeviceType type, const std::string& name); + InputDevice(unsigned int id, InputDeviceType type); virtual ~InputDevice(); // ID of the device. This ID is unique between all input devices. @@ -32,9 +32,6 @@ // The type of the input device. InputDeviceType type; - - // Name of the device. - std::string name; }; } // namespace ui
diff --git a/ui/events/devices/keyboard_device.cc b/ui/events/devices/keyboard_device.cc index 2ba9fe1..0774548d 100644 --- a/ui/events/devices/keyboard_device.cc +++ b/ui/events/devices/keyboard_device.cc
@@ -10,10 +10,8 @@ namespace ui { -KeyboardDevice::KeyboardDevice(int id, - InputDeviceType type, - const std::string& name) - : InputDevice(id, type, name) { +KeyboardDevice::KeyboardDevice(int id, InputDeviceType type) + : InputDevice(id, type) { } } // namespace ui
diff --git a/ui/events/devices/keyboard_device.h b/ui/events/devices/keyboard_device.h index 23f2750..fa1c4b7 100644 --- a/ui/events/devices/keyboard_device.h +++ b/ui/events/devices/keyboard_device.h
@@ -14,7 +14,7 @@ // Represents a Keyboard device state. struct EVENTS_DEVICES_EXPORT KeyboardDevice : public InputDevice { - KeyboardDevice(int id, InputDeviceType type, const std::string& name); + KeyboardDevice(int id, InputDeviceType type); }; } // namespace ui
diff --git a/ui/events/devices/touchscreen_device.cc b/ui/events/devices/touchscreen_device.cc index b8f1d41..3725c78 100644 --- a/ui/events/devices/touchscreen_device.cc +++ b/ui/events/devices/touchscreen_device.cc
@@ -15,10 +15,9 @@ TouchscreenDevice::TouchscreenDevice(unsigned int id, InputDeviceType type, - const std::string& name, const gfx::Size& size, int touch_points) - : InputDevice(id, type, name), size(size), touch_points(touch_points) { + : InputDevice(id, type), size(size), touch_points(touch_points) { } } // namespace ui
diff --git a/ui/events/devices/touchscreen_device.h b/ui/events/devices/touchscreen_device.h index d7b1fc4..8c14545 100644 --- a/ui/events/devices/touchscreen_device.h +++ b/ui/events/devices/touchscreen_device.h
@@ -20,7 +20,6 @@ TouchscreenDevice(unsigned int id, InputDeviceType type, - const std::string& name, const gfx::Size& size, int touch_points);
diff --git a/ui/events/devices/x11/device_data_manager_x11_unittest.cc b/ui/events/devices/x11/device_data_manager_x11_unittest.cc index 8149111..75a43d14 100644 --- a/ui/events/devices/x11/device_data_manager_x11_unittest.cc +++ b/ui/events/devices/x11/device_data_manager_x11_unittest.cc
@@ -80,10 +80,10 @@ DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); - keyboards.push_back(ui::KeyboardDevice( - 2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back( + ui::KeyboardDevice(2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); SetKeyboardDevices(keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -111,10 +111,10 @@ DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back(ui::KeyboardDevice( - 1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); - keyboards.push_back(ui::KeyboardDevice( - 2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + keyboards.push_back( + ui::KeyboardDevice(1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back( + ui::KeyboardDevice(2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); SetKeyboardDevices(keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -150,10 +150,10 @@ DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> all_keyboards; - all_keyboards.push_back(ui::KeyboardDevice( - 1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); - all_keyboards.push_back(ui::KeyboardDevice( - 2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + all_keyboards.push_back( + ui::KeyboardDevice(1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + all_keyboards.push_back( + ui::KeyboardDevice(2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); SetKeyboardDevices(all_keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -168,8 +168,8 @@ // Unplug the disabled device. Should not be notified, since the active list // did not change. std::vector<ui::KeyboardDevice> subset_keyboards; - subset_keyboards.push_back(ui::KeyboardDevice( - 1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + subset_keyboards.push_back( + ui::KeyboardDevice(1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); SetKeyboardDevices(subset_keyboards); EXPECT_FALSE(observer.change_notified()); // Replug in the first device. Should be notified of the new device.
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index daaaa267..fe566ab 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -440,9 +440,9 @@ // TODO(spang): Extract the number of touch-points supported by the // device. const int touch_points = 11; - touchscreens.push_back(TouchscreenDevice( - it->second->id(), it->second->type(), std::string() /* Device name */, - it->second->GetTouchscreenSize(), touch_points)); + touchscreens.push_back( + TouchscreenDevice(it->second->id(), it->second->type(), + it->second->GetTouchscreenSize(), touch_points)); } } @@ -453,8 +453,7 @@ std::vector<KeyboardDevice> keyboards; for (auto it = converters_.begin(); it != converters_.end(); ++it) { if (it->second->HasKeyboard()) { - keyboards.push_back(KeyboardDevice(it->second->id(), it->second->type(), - std::string() /* Device name */)); + keyboards.push_back(KeyboardDevice(it->second->id(), it->second->type())); } } @@ -464,10 +463,8 @@ void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() { std::vector<InputDevice> mice; for (auto it = converters_.begin(); it != converters_.end(); ++it) { - if (it->second->HasMouse()) { - mice.push_back(InputDevice(it->second->id(), it->second->type(), - std::string() /* Device name */)); - } + if (it->second->HasMouse()) + mice.push_back(InputDevice(it->second->id(), it->second->type())); } dispatcher_->DispatchMouseDevicesUpdated(mice); @@ -476,10 +473,8 @@ void InputDeviceFactoryEvdev::NotifyTouchpadDevicesUpdated() { std::vector<InputDevice> touchpads; for (auto it = converters_.begin(); it != converters_.end(); ++it) { - if (it->second->HasTouchpad()) { - touchpads.push_back(InputDevice(it->second->id(), it->second->type(), - std::string() /* Device name */)); - } + if (it->second->HasTouchpad()) + touchpads.push_back(InputDevice(it->second->id(), it->second->type())); } dispatcher_->DispatchTouchpadDevicesUpdated(touchpads);
diff --git a/ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.cc b/ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.cc index 766ffb2..4db958db 100644 --- a/ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.cc +++ b/ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.cc
@@ -431,31 +431,45 @@ // Check if a device falls into one device type category. bool IsDeviceOfType(const ui::GesturePropertyProvider::DevicePtr device, - const ui::EventDeviceType type) { + const ui::EventDeviceType type, + const GesturesProp* device_mouse_property, + const GesturesProp* device_touchpad_property) { + // Get the device type info from gesture properties if they are available. + // Otherwise, fallback to the libevdev device info. + bool is_mouse = false, is_touchpad = false; EvdevClass evdev_class = device->info.evdev_class; + if (device_mouse_property) { + is_mouse = device_mouse_property->GetBoolValue()[0]; + } else { + is_mouse = (evdev_class == EvdevClassMouse || + evdev_class == EvdevClassMultitouchMouse); + } + if (device_touchpad_property) { + is_touchpad = device_touchpad_property->GetBoolValue()[0]; + } else { + is_touchpad = (evdev_class == EvdevClassTouchpad || + evdev_class == EvdevClassTouchscreen || + evdev_class == EvdevClassMultitouchMouse); + } + switch (type) { case ui::DT_KEYBOARD: return (evdev_class == EvdevClassKeyboard); break; case ui::DT_MOUSE: - return (evdev_class == EvdevClassMouse || - evdev_class == EvdevClassMultitouchMouse); + return is_mouse; break; case ui::DT_TOUCHPAD: - // Note that the behavior here is different from the inputcontrol script - // which actually returns touchscreen devices as well. - return (evdev_class == EvdevClassTouchpad); + return (!is_mouse) && is_touchpad; break; case ui::DT_TOUCHSCREEN: return (evdev_class == EvdevClassTouchscreen); break; case ui::DT_MULTITOUCH: - return (evdev_class == EvdevClassTouchpad || - evdev_class == EvdevClassTouchscreen || - evdev_class == EvdevClassMultitouchMouse); + return is_touchpad; break; case ui::DT_MULTITOUCH_MOUSE: - return (evdev_class == EvdevClassMultitouchMouse); + return is_mouse && is_touchpad; break; case ui::DT_ALL: return true; @@ -855,7 +869,7 @@ bool exists = false; DeviceMap::const_iterator it = device_map_.begin(); for (; it != device_map_.end(); ++it) { - if (IsDeviceOfType(it->second, type)) { + if (IsDeviceIdOfType(it->first, type)) { exists = true; if (device_ids) device_ids->push_back(it->first); @@ -869,7 +883,9 @@ DeviceMap::const_iterator it = device_map_.find(device_id); if (it == device_map_.end()) return false; - return IsDeviceOfType(it->second, type); + return IsDeviceOfType(it->second, type, + GetProperty(device_id, "Device Mouse"), + GetProperty(device_id, "Device Touchpad")); } GesturesProp* GesturePropertyProvider::GetProperty(const DeviceId device_id,
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc index 3cca7ac0..8522a60 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -60,7 +60,8 @@ namespace ui { TouchEventConverterEvdev::InProgressEvents::InProgressEvents() - : x_(0), + : altered_(false), + x_(0), y_(0), id_(-1), finger_(-1), @@ -113,9 +114,9 @@ native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_); - for (int i = 0; - i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS); - ++i) { + events_.resize( + std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS)); + for (size_t i = 0; i < events_.size(); ++i) { events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i); events_[i].type_ = events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED; @@ -170,11 +171,12 @@ } else if(syn_dropped_) { // Do nothing. This branch indicates we have lost sync with the driver. } else if (input.type == EV_ABS) { - if (current_slot_ >= MAX_FINGERS) { - LOG(ERROR) << "too many touch events: " << current_slot_; - return; + if (events_.size() <= current_slot_) { + LOG(ERROR) << "current_slot_ (" << current_slot_ + << ") >= events_.size() (" << events_.size() << ")"; + } else { + ProcessAbs(input); } - ProcessAbs(input); } else if (input.type == EV_KEY) { switch (input.code) { case BTN_TOUCH: @@ -190,26 +192,21 @@ void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { switch (input.code) { case ABS_MT_TOUCH_MAJOR: - altered_slots_.set(current_slot_); // TODO(spang): If we have all of major, minor, and orientation, // we can scale the ellipse correctly. However on the Pixel we get // neither minor nor orientation, so this is all we can do. events_[current_slot_].radius_x_ = input.value / 2.0f; break; case ABS_MT_TOUCH_MINOR: - altered_slots_.set(current_slot_); events_[current_slot_].radius_y_ = input.value / 2.0f; break; case ABS_MT_POSITION_X: - altered_slots_.set(current_slot_); events_[current_slot_].x_ = input.value; break; case ABS_MT_POSITION_Y: - altered_slots_.set(current_slot_); events_[current_slot_].y_ = input.value; break; case ABS_MT_TRACKING_ID: - altered_slots_.set(current_slot_); if (input.value < 0) { events_[current_slot_].type_ = ET_TOUCH_RELEASED; } else { @@ -218,22 +215,23 @@ } break; case ABS_MT_PRESSURE: - altered_slots_.set(current_slot_); events_[current_slot_].pressure_ = input.value - pressure_min_; events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_; break; case ABS_MT_SLOT: - if (input.value >= MAX_FINGERS) { - LOG(ERROR) << "multi-touch slot " << input.value - << " exceeds MAX_FINGERS"; - break; + if (input.value >= 0 && + static_cast<size_t>(input.value) < events_.size()) { + current_slot_ = input.value; + } else { + LOG(ERROR) << "invalid touch event index: " << input.value; + return; } - current_slot_ = input.value; - altered_slots_.set(current_slot_); break; default: DVLOG(5) << "unhandled code for EV_ABS: " << input.code; + return; } + events_[current_slot_].altered_ = true; } void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { @@ -243,7 +241,8 @@ // Have to re-initialize. if (Reinitialize()) { syn_dropped_ = false; - altered_slots_.reset(); + for(InProgressEvents& event: events_) + event.altered_ = false; } else { LOG(ERROR) << "failed to re-initialize device info"; } @@ -257,7 +256,9 @@ case SYN_MT_REPORT: // For type A devices, we just get a stream of all current contacts, // in some arbitrary order. - events_[current_slot_++].type_ = ET_TOUCH_PRESSED; + events_[current_slot_].type_ = ET_TOUCH_PRESSED; + if (events_.size() - 1 > current_slot_) + current_slot_++; is_type_a_ = true; break; case SYN_DROPPED: @@ -280,16 +281,16 @@ } void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { - for (int i = 0; i < MAX_FINGERS; i++) { - if (altered_slots_[i]) { + for (size_t i = 0; i < events_.size(); i++) { + if (events_[i].altered_) { ReportEvent(i, events_[i], delta); // Subsequent events for this finger will be touch-move until it // is released. events_[i].type_ = ET_TOUCH_MOVED; + events_[i].altered_ = false; } } - altered_slots_.reset(); } } // namespace ui
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h index edf0ef9..4d521f55 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.h +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -24,9 +24,7 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev : public EventConverterEvdev { public: - enum { - MAX_FINGERS = 11 - }; + enum { MAX_FINGERS = 20 }; TouchEventConverterEvdev(int fd, base::FilePath path, int id, @@ -47,6 +45,7 @@ struct InProgressEvents { InProgressEvents(); + bool altered_; float x_; float y_; int id_; // Device reported "unique" touch point id; -1 means not active @@ -96,14 +95,10 @@ gfx::Size native_size_; // Touch point currently being updated from the /dev/input/event* stream. - int current_slot_; - - // Bit field tracking which in-progress touch points have been modified - // without a syn event. - std::bitset<MAX_FINGERS> altered_slots_; + size_t current_slot_; // In-progress touch points. - InProgressEvents events_[MAX_FINGERS]; + std::vector<InProgressEvents> events_; DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdev); };
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index dba98201..d389eabe 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -120,6 +120,8 @@ << "SetNonBlocking for pipe fd[0] failed, errno: " << errno; read_pipe_ = fds[0]; write_pipe_ = fds[1]; + + events_.resize(MAX_FINGERS); } void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc index 6b54e58..5efe25d 100644 --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc
@@ -225,8 +225,7 @@ if (IsKnownInvalidKeyboardDevice(device_name)) continue; // Skip invalid devices. InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); - devices.push_back( - KeyboardDevice(device_info.id, type, device_name)); + devices.push_back(KeyboardDevice(device_info.id, type)); } reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); @@ -278,10 +277,9 @@ InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); // |max_x| and |max_y| are inclusive values, so we need to add 1 to get // the size. - devices.push_back( - TouchscreenDevice(device_info.id, type, device_info.name, - gfx::Size(max_x + 1, max_y + 1), - device_info.touch_class_info.num_touches)); + devices.push_back(TouchscreenDevice( + device_info.id, type, gfx::Size(max_x + 1, max_y + 1), + device_info.touch_class_info.num_touches)); } }
diff --git a/ui/file_manager/file_manager/background/js/media_scanner.js b/ui/file_manager/file_manager/background/js/media_scanner.js index 84c0b21..b311fc6 100644 --- a/ui/file_manager/file_manager/background/js/media_scanner.js +++ b/ui/file_manager/file_manager/background/js/media_scanner.js
@@ -94,13 +94,17 @@ */ importer.DefaultMediaScanner = function( hashGenerator, historyLoader, watcherFactory) { + + /** @private {!importer.HistoryLoader} */ + this.historyLoader_ = historyLoader; + /** * A little factory for DefaultScanResults which allows us to forgo * the saving it's dependencies in our fields. * @return {!importer.DefaultScanResult} */ this.createScanResult_ = function() { - return new importer.DefaultScanResult(hashGenerator, historyLoader); + return new importer.DefaultScanResult(hashGenerator); }; /** @private {!Array.<!importer.ScanObserver>} */ @@ -134,75 +138,85 @@ throw new Error('Cannot scan empty list of entries.'); } - var scanResult = this.createScanResult_(); + var scan = this.createScanResult_(); var watcher = this.watcherFactory_( /** @this {importer.DefaultMediaScanner} */ function() { - scanResult.invalidateScan(); - this.observers_.forEach( - /** @param {!importer.ScanObserver} observer */ - function(observer) { - observer(importer.ScanEvent.INVALIDATED, scanResult); - }); + scan.invalidateScan(); + this.notify_(importer.ScanEvent.INVALIDATED, scan); }.bind(this)); + var scanPromises = entries.map( - this.scanEntry_.bind(this, scanResult, watcher)); + this.scanEntry_.bind(this, scan, watcher)); Promise.all(scanPromises) - .then(scanResult.resolve) - .catch(scanResult.reject); + .then(scan.resolve) + .catch(scan.reject); - scanResult.whenFinal() + scan.whenFinal() .then( + /** @this {importer.DefaultMediaScanner} */ function() { - this.onScanFinished_(scanResult); + this.notify_(importer.ScanEvent.FINALIZED, scan); }.bind(this)); - return scanResult; + return scan; }; /** - * Called when a scan is finished. + * Notifies all listeners at some point in the near future. * + * @param {!importer.ScanEvent} event * @param {!importer.DefaultScanResult} result * @private */ -importer.DefaultMediaScanner.prototype.onScanFinished_ = function(result) { +importer.DefaultMediaScanner.prototype.notify_ = function(event, result) { this.observers_.forEach( /** @param {!importer.ScanObserver} observer */ function(observer) { - observer(importer.ScanEvent.FINALIZED, result); + observer(event, result); }); }; /** - * Resolves the entry to a list of {@code FileEntry}. + * Resolves the entry by either: + * a) recursing on it (when a directory) + * b) adding it to the results (when a media type file) + * c) ignoring it, if neither a or b * - * @param {!importer.DefaultScanResult} result + * @param {!importer.DefaultScanResult} scan * @param {!importer.DirectoryWatcher} watcher * @param {!Entry} entry + * * @return {!Promise} * @private */ importer.DefaultMediaScanner.prototype.scanEntry_ = - function(result, watcher, entry) { - return entry.isFile ? - result.onFileEntryFound(/** @type {!FileEntry} */ (entry)) : - this.scanDirectory_( - result, watcher, /** @type {!DirectoryEntry} */ (entry)); + function(scan, watcher, entry) { + + if (entry.isDirectory) { + return this.scanDirectory_( + scan, + watcher, + /** @type {!DirectoryEntry} */ (entry)); + } + + // Since this entry is by client code (and presumably the user) + // we add it directly (skipping over the history dupe check). + return this.onUniqueFileFound_(scan, /** @type {!FileEntry} */ (entry)); }; /** * Finds all files beneath directory. * - * @param {!importer.DefaultScanResult} result + * @param {!importer.DefaultScanResult} scan * @param {!importer.DirectoryWatcher} watcher * @param {!DirectoryEntry} entry * @return {!Promise} * @private */ importer.DefaultMediaScanner.prototype.scanDirectory_ = - function(result, watcher, entry) { + function(scan, watcher, entry) { // Collect promises for all files being added to results. // The directory scan promise can't resolve until all // file entries are completely promised. @@ -210,22 +224,113 @@ return fileOperationUtil.findEntriesRecursively( entry, - /** @param {!Entry} entry */ + /** + * @param {!Entry} entry + * @this {importer.DefaultMediaScanner} + */ function(entry) { if (watcher.triggered) { return; } + if (entry.isDirectory) { + // Note, there is no need for us to recurse, the utility + // function findEntriesRecursively does that. So we + // just watch the directory for modifications, and that's it. watcher.addDirectory(/** @type {!DirectoryEntry} */(entry)); - } else { - promises.push( - result.onFileEntryFound(/** @type {!FileEntry} */(entry))); + return; } - }) + + promises.push( + this.onFileEntryFound_(scan, /** @type {!FileEntry} */(entry))); + + }.bind(this)) .then(Promise.all.bind(Promise, promises)); }; /** + * Finds all files beneath directory. + * + * @param {!importer.DefaultScanResult} scan + * @param {!FileEntry} entry + * @return {!Promise} + * @private + */ +importer.DefaultMediaScanner.prototype.onFileEntryFound_ = + function(scan, entry) { + return this.hasHistoryDuplicate_(entry) + .then( + /** + * @param {boolean} duplicate + * @return {!Promise} + * @this {importer.DefaultMediaScanner} + */ + function(duplicate) { + if (!duplicate) { + return this.onUniqueFileFound_(scan, entry); + } + }.bind(this)); +}; + +/** + * Finds all files beneath directory. + * + * @param {!importer.DefaultScanResult} scan + * @param {!FileEntry} entry + * @return {!Promise} + * @private + */ +importer.DefaultMediaScanner.prototype.onUniqueFileFound_ = + function(scan, entry) { + + if (!FileType.isImageOrVideo(entry)) { + return Promise.resolve(); + } + + return scan.addFileEntry(entry) + .then( + /** + * @param {boolean} added + * @this {importer.DefaultMediaScanner} + */ + function(added) { + if (added) { + this.notify_(importer.ScanEvent.UPDATED, scan); + } + }.bind(this)); +}; + +/** + * @param {!FileEntry} entry + * @return {!Promise.<boolean>} True if there is a history-entry-duplicate + * for the file. + * @private + */ +importer.DefaultMediaScanner.prototype.hasHistoryDuplicate_ = function(entry) { + return this.historyLoader_.getHistory() + .then( + /** + * @param {!importer.ImportHistory} history + * @return {!Promise} + * @this {importer.DefaultMediaScanner} + */ + function(history) { + return Promise.all([ + history.wasCopied(entry, importer.Destination.GOOGLE_DRIVE), + history.wasImported(entry, importer.Destination.GOOGLE_DRIVE) + ]).then( + /** + * @param {!Array.<boolean>} results + * @return {!Promise} + * @this {importer.DefaultMediaScanner} + */ + function(results) { + return results[0] || results[1]; + }.bind(this)); + }.bind(this)); +}; + +/** * Results of a scan operation. The object is "live" in that data can and * will change as the scan operation discovers files. * @@ -236,17 +341,14 @@ * @struct * @implements {importer.ScanResult} * - * @param {function(!FileEntry): !Promise.<string>} hashGenerator - * @param {!importer.HistoryLoader} historyLoader + * @param {function(!FileEntry): !Promise.<string>} hashGenerator Hash-code + * generator used to dedupe within the scan results itself. */ -importer.DefaultScanResult = function(hashGenerator, historyLoader) { +importer.DefaultScanResult = function(hashGenerator) { /** @private {function(!FileEntry): !Promise.<string>} */ this.createHashcode_ = hashGenerator; - /** @private {!importer.HistoryLoader} */ - this.historyLoader_ = historyLoader; - /** * List of file entries found while scanning. * @private {!Array.<!FileEntry>} @@ -254,11 +356,6 @@ this.fileEntries_ = []; /** - * @private {boolean} - */ - this.invalidated_ = false; - - /** * Hashcodes of all files included captured by this result object so-far. * Used to dedupe newly discovered files against other files withing * the ScanResult. @@ -281,6 +378,11 @@ */ this.lastScanActivity_ = this.scanStarted_; + /** + * @private {boolean} + */ + this.invalidated_ = false; + /** @private {!importer.Resolver.<!importer.ScanResult>} */ this.resolver_ = new importer.Resolver(); }; @@ -332,92 +434,44 @@ }; /** - * Handles files discovered during scanning. - * - * @param {!FileEntry} entry - * @return {!Promise} Resolves once file entry has been processed - * and is represented in results. - */ -importer.DefaultScanResult.prototype.onFileEntryFound = function(entry) { - this.lastScanActivity_ = new Date(); - - if (!FileType.isImageOrVideo(entry)) { - return Promise.resolve(); - } - - return this.historyLoader_.getHistory() - .then( - /** - * @param {!importer.ImportHistory} history - * @return {!Promise} - * @this {importer.DefaultScanResult} - */ - function(history) { - return Promise.all([ - history.wasCopied(entry, importer.Destination.GOOGLE_DRIVE), - history.wasImported(entry, importer.Destination.GOOGLE_DRIVE) - ]).then( - /** - * @param {!Array.<boolean>} results - * @return {!Promise} - * @this {importer.DefaultScanResult} - */ - function(results) { - return results[0] || results[1] ? - Promise.resolve() : - this.addFileEntry_(entry); - }.bind(this)); - }.bind(this)); -}; - -/** * Adds a file to results. * * @param {!FileEntry} entry - * @return {!Promise} Resolves once file entry has been processed - * and is represented in results. - * @private + * @return {!Promise.<boolean>} True if the file as added, false if it was + * rejected as a dupe. */ -importer.DefaultScanResult.prototype.addFileEntry_ = function(entry) { - return new Promise( - function(resolve, reject) { - this.createHashcode_(entry).then( - /** - * @param {string} hashcode - * @this {importer.DefaultScanResult} - */ - function(hashcode) { - // Ignore the entry if it is a duplicate. - if (hashcode in this.fileHashcodes_) { - resolve(); - return; - } +importer.DefaultScanResult.prototype.addFileEntry = function(entry) { + return new Promise(entry.getMetadata.bind(entry)).then( + /** + * @param {!Metadata} metadata + * @this {importer.DefaultScanResult} + */ + function(metadata) { + console.assert( + 'size' in metadata, + 'size attribute missing from metadata.'); - entry.getMetadata( - /** - * @param {!Metadata} metadata - * @this {importer.DefaultScanResult} - */ - function(metadata) { - console.assert( - 'size' in metadata, - 'size attribute missing from metadata.'); - this.lastScanActivity_ = new Date(); + return this.createHashcode_(entry) + .then( + /** + * @param {string} hashcode + * @this {importer.DefaultScanResult} + */ + function(hashcode) { + this.lastScanActivity_ = new Date(); - // Double check that a dupe entry wasn't added while we were - // busy looking up metadata. - if (hashcode in this.fileHashcodes_) { - resolve(); - return; - } - entry.size = metadata.size; - this.totalBytes_ += metadata['size']; - this.fileHashcodes_[hashcode] = entry; - this.fileEntries_.push(entry); - resolve(); + if (hashcode in this.fileHashcodes_) { + return false; + } + + entry.size = metadata.size; + this.totalBytes_ += metadata['size']; + this.fileHashcodes_[hashcode] = entry; + this.fileEntries_.push(entry); + return true; }.bind(this)); - }.bind(this)); - }.bind(this)); + + }.bind(this)); }; /**
diff --git a/ui/file_manager/file_manager/background/js/mock_media_scanner.js b/ui/file_manager/file_manager/background/js/mock_media_scanner.js index 59f21e9..407c02f 100644 --- a/ui/file_manager/file_manager/background/js/mock_media_scanner.js +++ b/ui/file_manager/file_manager/background/js/mock_media_scanner.js
@@ -47,11 +47,11 @@ /** @override */ TestMediaScanner.prototype.scan = function(entries) { - var result = new TestScanResult(this.fileEntries); - result.totalBytes = this.totalBytes; - result.scanDuration = this.scanDuration; - this.scans_.push(result); - return result; + var scan = new TestScanResult(this.fileEntries); + scan.totalBytes = this.totalBytes; + scan.scanDuration = this.scanDuration; + this.scans_.push(scan); + return scan; }; /** @@ -62,6 +62,19 @@ }; /** + * Notifies observers that the most recently started scan has been updated. + * @param {!importer.ScanResult} result + */ +TestMediaScanner.prototype.update = function() { + assertTrue(this.scans_.length > 0); + var scan = this.scans_[this.scans_.length - 1]; + this.observers.forEach( + function(observer) { + observer(importer.ScanEvent.UPDATED, scan); + }); +}; + +/** * Notifies observers that a scan has finished. * @param {!importer.ScanResult} result */
diff --git a/ui/file_manager/file_manager/common/js/importer_common.js b/ui/file_manager/file_manager/common/js/importer_common.js index 8142d07..3f6d302e 100644 --- a/ui/file_manager/file_manager/common/js/importer_common.js +++ b/ui/file_manager/file_manager/common/js/importer_common.js
@@ -8,7 +8,8 @@ /** @enum {string} */ importer.ScanEvent = { FINALIZED: 'finalized', - INVALIDATED: 'invalidated' + INVALIDATED: 'invalidated', + UPDATED: 'updated' }; /**
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 08487e4..4993ae1 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1029,3 +1029,24 @@ target.removeEventListener(type, handler); }); }; + +/** + * Repeats a given event to a given target with event.ctrlKey set true. + * @param {!EventTarget} target Event target which receives the repeated event. + * @param {!Event} event Original mouse event. + */ +util.repeatMouseEventWithCtrlKey = function(target, event) { + event.stopPropagation(); + event.preventDefault(); + event = assertInstanceof(event, MouseEvent); + var eventWithCtrl = new MouseEvent(event.type, { + bubbles: event.bubbles, + button: event.button, + clientX: event.clientX, + clientY: event.clientY, + ctrlKey: true, + shiftKey: event.shiftKey, + target: event.target + }); + target.dispatchEvent(eventWithCtrl); +};
diff --git a/ui/file_manager/file_manager/foreground/css/combobutton.css b/ui/file_manager/file_manager/foreground/css/combobutton.css index 9b24d22..6094677 100644 --- a/ui/file_manager/file_manager/foreground/css/combobutton.css +++ b/ui/file_manager/file_manager/foreground/css/combobutton.css
@@ -2,50 +2,58 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -.buttonbar button.combobutton { +.dialog-header button.combobutton { + -webkit-user-select: none; align-items: stretch; + background: transparent; + border: none; + border-radius: 3px; + cursor: pointer; display: flex; + margin: 0 0.29em; + min-width: 16px; + outline: none; + padding: 8px; } -.buttonbar .combobutton > .action { +.dialog-header .combobutton > .action { background-position: left center; background-repeat: no-repeat; background-size: 16px 16px; } -.buttonbar .combobutton > .with-icon { +.dialog-header .combobutton > .with-icon { -webkit-padding-start: 21px; } -html[dir='rtl'] .buttonbar .combobutton > .action { +html[dir='rtl'] .dialog-header .combobutton > .action { background-position: right center; } -.buttonbar .combobutton > .trigger { - -webkit-border-start: solid 1px #dcdcdc; +.dialog-header .combobutton > .trigger { -webkit-margin-end: -8px; - -webkit-margin-start: 8px; + -webkit-margin-start: 2px; width: 22px; } /* This pseudo element expands clickable area of the .trigger */ -.buttonbar .combobutton > .trigger::before { +.dialog-header .combobutton > .trigger::before { content: ''; display: block; height: 31px; position: absolute; - top: -5px; + top: -2px; width: 30px; } -.buttonbar .combobutton:not([multiple]) > .trigger { +.dialog-header .combobutton:not([multiple]) > .trigger { display: none; } -.buttonbar .combobutton > div > span.disclosureindicator { +.dialog-header .combobutton > div > span.disclosureindicator { -webkit-transform: rotate(90deg); } -.buttonbar .combobutton[hidden] { +.dialog-header .combobutton[hidden] { display: none; }
diff --git a/ui/file_manager/file_manager/foreground/css/drive_welcome.css b/ui/file_manager/file_manager/foreground/css/drive_welcome.css index 900185b..22a49d0 100644 --- a/ui/file_manager/file_manager/foreground/css/drive_welcome.css +++ b/ui/file_manager/file_manager/foreground/css/drive_welcome.css
@@ -44,7 +44,7 @@ border-color: #C6C6C6; box-shadow: 0 1px 1px rgba(0,0,0,0.1); color: #222; - transition: all 0; + transition: all 0ms; } .drive-welcome-button:active { @@ -74,7 +74,7 @@ height: 100px; overflow: hidden; position: relative; - transition: height 180ms ease, visibility 0 linear 180ms; + transition: height 180ms ease, visibility 0ms linear 180ms; } .dialog-container:not([drive-welcome='header']) .drive-welcome.header {
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index aa22019..ef0c64fe 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -48,6 +48,7 @@ display: flex; flex: auto; flex-direction: column; + font-size: 81%; height: 100%; margin: 0; padding: 0; @@ -141,7 +142,7 @@ min-width: 100px; overflow: hidden; position: relative; - width: 272px; + width: 240px; } .dialog-navigation-list-contents { @@ -265,25 +266,26 @@ /* Breadcrumbs and things under the title but above the list view. */ .dialog-header { align-items: center; - background: rgb(27, 168, 243); + background: rgba(27, 168, 243, 1.0); color: white; display: flex; flex: none; flex-direction: row; height: 48px; margin: 0; + transition: background 220ms ease; +} + +body.selecting .dialog-header { + background: rgba(27, 168, 243, 0.9); } .dialog-header > .spacer { flex: auto; } -.dialog-header button, -.dialog-header paper-button { - height: 32px; - margin-right: 4px; - min-width: 32px; - width: 32px; +.dialog-header button { + text-transform: uppercase; } .dialog-header button, @@ -291,8 +293,28 @@ color: white; } -.dialog-header button > core-icon, -.dialog-header paper-button > core-icon { +.dialog-header .icon-button { + -webkit-margin-end: 4px; + -webkit-margin-start: 0; + background: transparent; + border: 0; + height: 32px; + line-height: 16px; + min-width: 32px; + padding: 0; + width: 32px; +} + +.dialog-header .icon-button:hover, +.dialog-header .icon-button:focus { + background: rgba(204, 204, 204, 0.15); +} + +.dialog-header .icon-button[disabled] { + display: none !important; +} + +.dialog-header core-icon { height: 16px; width: 16px; } @@ -301,10 +323,8 @@ padding: 8px; } -#gear-button, -#cloud-import-button { +.dialog-header button.icon-button { -webkit-app-region: no-drag; - -webkit-margin-end: 10px; background-color: transparent; background-image: none; background-position: center; @@ -319,17 +339,77 @@ width: 32px; } -#gear-button > core-icon, -#cloud-import-button > core-icon { +.dialog-header button.icon-button > core-icon { margin: 8px; } +#cloud-import-details-button { + margin-left: -15px; +} + +#cloud-import-details { + background-color: white; + height: 300px; + opacity: .85; + padding: 10px; + position: absolute; + right: 0px; + top: 49px; + transition: all 0.2s ease; + width: 250px; + z-index: 5; +} + +#cloud-import-details.offscreen { + opacity: 0; + right: -202px; +} + +#cloud-import-details div { + border: 0px 0px 1px 0px solid gray; + padding: 10px; +}; + +#files-selected-label { + display: none; + /* TODO(fukino): Move dynamically with the navigation area's separator. */ + left: 252px; + position: absolute; + top: 18px; +} + +body.selecting #files-selected-label { + display: block; +} + +#cancel-selection-button { + text-transform: none; + display: none +} + +#cancel-selection-button > core-icon { + -webkit-margin-end: 6px; +} + +body.selecting #cancel-selection-button { + display: inline-block; +} + +/* Search button */ +body.selecting #search-button { + display: none; +} + /* Search box */ #search-box { display: flex; flex: none; } +body.selecting #search-box { + display: none; +} + #search-box input { cursor: default; display: inline-block; @@ -469,6 +549,10 @@ padding-top: 1px; } +body.selecting .breadcrumbs { + display: none; +} + .breadcrumbs > [collapsed]::before { content: '...'; } @@ -708,10 +792,7 @@ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.3); } -.thumbnail-grid .thumbnail-frame .checkmark { - background-image: -webkit-image-set( - url(../images/files/ui/thumbnail_checked.png) 1x, - url(../images/files/ui/2x/thumbnail_checked.png) 2x); +.thumbnail-grid .checkmark { height: 34px; left: 9px; opacity: 0; @@ -721,7 +802,17 @@ width: 34px; } -.thumbnail-grid .thumbnail-item[selected] .thumbnail-frame .checkmark { +body.selecting .thumbnail-grid .checkmark { + background-image: -webkit-image-set( + url(../images/files/ui/thumbnail_unchecked.png) 1x, + url(../images/files/ui/2x/thumbnail_unchecked.png) 2x); + opacity: 1; +} + +body.selecting .thumbnail-grid .thumbnail-item[selected] .checkmark { + background-image: -webkit-image-set( + url(../images/files/ui/thumbnail_checked.png) 1x, + url(../images/files/ui/2x/thumbnail_checked.png) 2x); opacity: 1; } @@ -1135,24 +1226,6 @@ flex: auto; } -#delete-button { - min-width: 21px; /* overrride */ - padding: 0; /* overrride */ - width: 21px; -} - -#delete-button::before { - /* Background image should be specified in the before pseudo element because - * border image fill is specified to delete-button. */ - background: -webkit-image-set( - url(../images/files/ui/onbutton_trash.png) 1x, - url(../images/files/ui/2x/onbutton_trash.png) 2x) no-repeat center; - content: ''; - display: block; - height: 100%; - width: 100%; -} - #delete-button[disabled] { display: none; }
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/thumbnail_unchecked.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/thumbnail_unchecked.png new file mode 100644 index 0000000..872c57ae --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/2x/thumbnail_unchecked.png Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/thumbnail_unchecked.png b/ui/file_manager/file_manager/foreground/images/files/ui/thumbnail_unchecked.png new file mode 100644 index 0000000..53b3535d --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/thumbnail_unchecked.png Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp index 2230324..585cef25 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -87,6 +87,7 @@ './launch_param.js', './metadata/content_metadata_provider.js', './metadata/external_metadata_provider.js', + './metadata/file_system_metadata.js', './metadata/file_system_metadata_provider.js', './metadata/metadata_cache.js', './metadata/metadata_cache_item.js', @@ -95,13 +96,13 @@ './metadata_update_controller.js', './naming_controller.js', './navigation_list_model.js', - './preview_panel_model.js', './progress_center_item_group.js', './scan_controller.js', './search_controller.js', './spinner_controller.js', './share_client.js', './task_controller.js', + './toolbar_controller.js', './thumbnail_loader.js', './list_thumbnail_loader.js', './ui/banners.js', @@ -118,7 +119,6 @@ './ui/list_container.js', './ui/location_line.js', './ui/multi_profile_share_dialog.js', - './ui/preview_panel.js', './ui/progress_center_panel.js', './ui/scrollbar.js', './ui/search_box.js',
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js index 5d7aa4e..3e8eb434 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -16,13 +16,16 @@ * @param {FileFilter} fileFilter Instance of FileFilter. * @param {FileWatcher} fileWatcher Instance of FileWatcher. * @param {MetadataCache} metadataCache The metadata cache service. + * @param {!FileSystemMetadata} fileSystemMetadata The metadata cache + * service. * @param {VolumeManagerWrapper} volumeManager The volume manager. * @param {!FileOperationManager} fileOperationManager File operation manager. * @constructor * @extends {cr.EventTarget} */ -function DirectoryModel(singleSelection, fileFilter, fileWatcher, - metadataCache, volumeManager, fileOperationManager) { +function DirectoryModel(singleSelection, fileFilter, fileWatcher, metadataCache, + fileSystemMetadata, volumeManager, + fileOperationManager) { this.fileListSelection_ = singleSelection ? new cr.ui.ListSingleSelectionModel() : new cr.ui.ListSelectionModel(); @@ -46,6 +49,7 @@ DirectoryContents.createForDirectory(this.currentFileListContext_, null); this.metadataCache_ = metadataCache; + this.fileSystemMetadata_ = fileSystemMetadata; this.volumeManager_ = volumeManager; this.volumeManager_.volumeInfoList.addEventListener( @@ -81,7 +85,7 @@ }; /** - * @return {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} Selection + * @return {!cr.ui.ListSelectionModel|!cr.ui.ListSingleSelectionModel} Selection * in the fileList. */ DirectoryModel.prototype.getFileListSelection = function() { @@ -821,6 +825,7 @@ return; } + var dirContents = this.currentDirContents_; var sequence = this.changeDirectorySequence_; new Promise(entry.getDirectory.bind( @@ -829,10 +834,10 @@ then(function(newEntry) { // Refresh the cache. this.metadataCache_.clear([newEntry], '*'); + this.fileSystemMetadata_.notifyEntryCreated([newEntry]); return new Promise(function(onFulfilled, onRejected) { - this.metadataCache_.getOne(newEntry, - 'filesystem', - onFulfilled.bind(null, newEntry)); + dirContents.prefetchMetadata( + [newEntry], false, onFulfilled.bind(null, newEntry)); }.bind(this)); }.bind(this)).
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index b9290b8..7392b1b 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -61,6 +61,17 @@ this.metadataCache_ = null; /** + * @private {!MetadataProviderCache} + * @const + */ + this.metadataProviderCache_ = new MetadataProviderCache(); + + /** + * @private {FileSystemMetadata} + */ + this.fileSystemMetadata_ = null; + + /** * File operation manager. * @type {FileOperationManager} * @private @@ -177,6 +188,13 @@ this.gearMenuController_ = null; /** + * Toolbar controller. + * @type {ToolbarController} + * @private + */ + this.toolbarController_ = null; + + /** * App state controller. * @type {AppStateController} * @private @@ -415,6 +433,11 @@ this.ui_.gearMenu, this.directoryModel_, this.commandHandler); + this.toolbarController_ = new ToolbarController( + this.ui_.cancelSelectionButton, + this.ui_.filesSelectedLabel, + this.selectionHandler_, + this.directoryModel_.getFileListSelection()); importer.importEnabled().then( function(enabled) { @@ -680,7 +703,13 @@ DialogType.FULL_PAGE]); // Create the metadata cache. + assert(this.volumeManager_); this.metadataCache_ = MetadataCache.createFull(this.volumeManager_); + this.fileSystemMetadata_ = new FileSystemMetadata( + this.metadataProviderCache_, + new FileSystemMetadataProvider(this.metadataProviderCache_), + new ExternalMetadataProvider(this.metadataProviderCache_), + this.volumeManager_); // Create the root view of FileManager. assert(this.dialogDom_); @@ -737,14 +766,6 @@ this.ui_.initAdditionalUI( assertInstanceof(table, FileTable), assertInstanceof(grid, FileGrid), - new PreviewPanel( - queryRequiredElement(dom, '.preview-panel'), - DialogType.isOpenDialog(this.dialogType) ? - PreviewPanelModel.VisibilityType.ALWAYS_VISIBLE : - PreviewPanelModel.VisibilityType.AUTO, - this.metadataCache_, - this.volumeManager_, - this.historyLoader_), new LocationLine( queryRequiredElement(dom, '#location-breadcrumbs'), this.metadataCache_, @@ -832,11 +853,13 @@ assert(this.volumeManager_); assert(this.fileOperationManager_); + assert(this.fileSystemMetadata_); this.directoryModel_ = new DirectoryModel( singleSelection, this.fileFilter_, this.fileWatcher_, this.metadataCache_, + this.fileSystemMetadata_, this.volumeManager_, this.fileOperationManager_);
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js index 409ad34..8217259 100644 --- a/ui/file_manager/file_manager/foreground/js/file_selection.js +++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -19,12 +19,6 @@ this.fileManager_ = fileManager; /** - * @type {number} - * @private - */ - this.computeBytesSequence_ = 0; - - /** * @type {!Array.<number>} * @const */ @@ -52,16 +46,6 @@ this.directoryCount = 0; /** - * @type {number} - */ - this.bytes = 0; - - /** - * @type {boolean} - */ - this.showBytes = false; - - /** * @type {boolean} */ this.allDriveFilesPresent = false; @@ -73,11 +57,6 @@ /** * @type {boolean} - */ - this.bytesKnown = false; - - /** - * @type {boolean} * @private */ this.mustBeHidden_ = false; @@ -155,69 +134,6 @@ }; /** - * Computes the total size of selected files. - * - * @param {function()} callback Completion callback. Not called when cancelled, - * or a new call has been invoked in the meantime. - */ -FileSelection.prototype.computeBytes = function(callback) { - if (this.entries.length == 0) { - this.bytesKnown = true; - this.showBytes = false; - this.bytes = 0; - return; - } - - var computeBytesSequence = ++this.computeBytesSequence_; - var pendingMetadataCount = 0; - - var maybeDone = function() { - if (pendingMetadataCount == 0) { - this.bytesKnown = true; - callback(); - } - }.bind(this); - - var onProps = function(properties) { - // Ignore if the call got cancelled, or there is another new one fired. - if (computeBytesSequence != this.computeBytesSequence_) - return; - - // It may happen that the metadata is not available because a file has been - // deleted in the meantime. - if (properties) - this.bytes += properties.size; - pendingMetadataCount--; - maybeDone(); - }.bind(this); - - for (var index = 0; index < this.entries.length; index++) { - var entry = this.entries[index]; - if (entry.isFile) { - this.showBytes |= !FileType.isHosted(entry); - pendingMetadataCount++; - this.fileManager_.metadataCache_.getOne(entry, 'filesystem', onProps); - } else if (entry.isDirectory) { - // Don't compute the directory size as it's expensive. - // crbug.com/179073. - this.showBytes = false; - break; - } - } - maybeDone(); -}; - -/** - * Cancels any async computation by increasing the sequence number. Results - * of any previous call to computeBytes() will be discarded. - * - * @private - */ -FileSelection.prototype.cancelComputing_ = function() { - this.computeBytesSequence_++; -}; - -/** * This object encapsulates everything related to current selection. * * @param {!FileManager} fileManager File manager instance. @@ -230,9 +146,6 @@ cr.EventTarget.call(this); this.fileManager_ = fileManager; - // TODO(dgozman): create a shared object with most of UI elements. - this.previewPanel_ = fileManager.ui.previewPanel; - this.taskMenuButton_ = fileManager.ui.taskMenuButton; this.selection = new FileSelection(this.fileManager_, []); /** @@ -279,30 +192,11 @@ FileSelectionHandler.prototype.__proto__ = cr.EventTarget.prototype; /** - * Maximum amount of thumbnails in the preview pane. - * - * @const - * @type {number} - */ -FileSelectionHandler.MAX_PREVIEW_THUMBNAIL_COUNT = 4; - -/** - * Maximum width or height of an image what pops up when the mouse hovers - * thumbnail in the bottom panel (in pixels). - * - * @const - * @type {number} - */ -FileSelectionHandler.IMAGE_HOVER_PREVIEW_SIZE = 200; - -/** * Update the UI when the selection model changes. */ FileSelectionHandler.prototype.onFileSelectionChanged = function() { var indexes = this.fileManager_.getCurrentList().selectionModel.selectedIndexes; - if (this.selection) - this.selection.cancelComputing_(); var selection = new FileSelection(this.fileManager_, indexes); this.selection = selection; @@ -342,16 +236,6 @@ if (this.selection !== selection) return; - // Update preview panels. - var wasVisible = this.previewPanel_.visible; - this.previewPanel_.setSelection(selection); - - // Scroll to item - if (!wasVisible && this.selection.totalCount == 1) { - var list = this.fileManager_.getCurrentList(); - list.scrollIndexIntoView(list.selectionModel.selectedIndex); - } - // Sync the commands availability. if (this.fileManager_.commandHandler) this.fileManager_.commandHandler.updateAvailability();
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller.js b/ui/file_manager/file_manager/foreground/js/import_controller.js index 439fc43e..a31f0072 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller.js +++ b/ui/file_manager/file_manager/foreground/js/import_controller.js
@@ -56,7 +56,7 @@ this.commandWidget_ = commandWidget; /** @type {!importer.ScanManager} */ - this.scanManager_ = new importer.ScanManager(scanner); + this.scanManager_ = new importer.ScanManager(environment, scanner); /** * The active import task, if any. @@ -82,27 +82,80 @@ this.environment_.addSelectionChangedListener( this.onSelectionChanged_.bind(this)); - this.commandWidget_.addExecuteListener( + this.commandWidget_.addImportClickedListener( this.execute.bind(this)); }; /** * @param {!importer.ScanEvent} event Command event. - * @param {importer.ScanResult} result + * @param {importer.ScanResult} scan * * @private */ -importer.ImportController.prototype.onScanEvent_ = function(event, result) { - if (event === importer.ScanEvent.INVALIDATED) { - this.scanManager_.reset(); +importer.ImportController.prototype.onScanEvent_ = function(event, scan) { + if (!this.scanManager_.isActiveScan(scan)) { + return; } - if (event === importer.ScanEvent.FINALIZED || - event === importer.ScanEvent.INVALIDATED) { - this.pushUpdate_(); + + switch (event) { + case importer.ScanEvent.INVALIDATED: + this.scanManager_.reset(); + case importer.ScanEvent.FINALIZED: + case importer.ScanEvent.UPDATED: + this.checkState_(scan); + break; } }; /** + * @param {string} volumeId + * @private + */ +importer.ImportController.prototype.onVolumeUnmounted_ = function(volumeId) { + this.scanManager_.reset(); + this.checkState_(); +}; + +/** @private */ +importer.ImportController.prototype.onDirectoryChanged_ = function() { + this.scanManager_.clearSelectionScan(); + if (this.isCurrentDirectoryScannable_()) { + this.checkState_( + this.scanManager_.getCurrentDirectoryScan()); + } else { + this.checkState_(); + } +}; + +/** @private */ +importer.ImportController.prototype.onSelectionChanged_ = function() { + // NOTE: We clear the scan here, but don't immediately initiate + // a new scan. checkState will attempt to initialize the scan + // during normal processing. + // Also, in the case the selection is transitioning to empty, + // we want to reinstate the underlying directory scan (if + // in fact, one is possible). + this.scanManager_.clearSelectionScan(); + if (this.environment_.getSelection().length === 0 && + this.isCurrentDirectoryScannable_()) { + this.checkState_( + this.scanManager_.getCurrentDirectoryScan()); + } else { + this.checkState_(); + } +}; + +/** + * @param {!importer.MediaImportHandler.ImportTask} task + * @private + */ +importer.ImportController.prototype.onImportFinished_ = function(task) { + this.activeImportTask_ = null; + this.scanManager_.reset(); + this.checkState_(); +}; + +/** * Executes import against the current directory. Should only * be called when the current directory has been validated * by calling "update" on this class. @@ -111,8 +164,10 @@ console.assert(!this.activeImportTask_, 'Cannot execute while an import task is already active.'); metrics.recordEnum('CloudImport.UserAction', 'IMPORT_INITIATED'); - var scan = this.getScan_(); + + var scan = this.scanManager_.getActiveScan(); assert(scan != null); + var importTask = this.importRunner_.importFromScanResult( scan, importer.Destination.GOOGLE_DRIVE); @@ -120,136 +175,155 @@ this.activeImportTask_ = importTask; var taskFinished = this.onImportFinished_.bind(this, importTask); importTask.whenFinished.then(taskFinished).catch(taskFinished); - this.pushUpdate_(); + this.checkState_(); }; /** - * @param {!importer.MediaImportHandler.ImportTask} task + * Checks the environment and updates UI as needed. + * @param {importer.ScanResult=} opt_scan If supplied, * @private */ -importer.ImportController.prototype.onImportFinished_ = function(task) { - this.activeImportTask_ = null; - this.scanManager_.reset(); - this.pushUpdate_(); -}; +importer.ImportController.prototype.checkState_ = function(opt_scan) { + // If there is no Google Drive mount, Drive may be disabled + // or the machine may be running in guest mode. + if (!this.environment_.isGoogleDriveMounted()) { + this.updateUi_(importer.ResponseId.HIDDEN); + return; + } -/** - * Push an update to the command widget. - * @private - */ -importer.ImportController.prototype.pushUpdate_ = function() { - this.getCommandUpdate().then( - this.commandWidget_.update.bind(this.commandWidget_)); -}; + if (!!this.activeImportTask_) { + this.updateUi_(importer.ResponseId.ACTIVE_IMPORT); + return; + } -/** - * Returns an update describing the state of the CommandWidget. - * - * @return {!Promise.<!importer.CommandUpdate>} response - */ -importer.ImportController.prototype.getCommandUpdate = function() { - return Promise.resolve().then( - function() { - if (!!this.activeImportTask_) { - return importer.ImportController.createUpdate_( - importer.ResponseId.ACTIVE_IMPORT); - } + // If we don't have an existing scan, we'll try to create + // one. When we do end up creating one (not getting + // one from the cache) it'll be empty...even if there is + // a current selection. This is because scans are + // resolved asynchronously. And we like it that way. + // We'll get notification when the scan is updated. When + // that happens, we'll be called back with opt_scan + // set to that scan....and subsequently skip over this + // block to update the UI. + if (!opt_scan) { + // NOTE, that tryScan_ lazily initializes scans...so if + // no scan is returned, no scan is possible for the + // current context. + var scan = this.tryScan_(); + // If no scan is created, then no scan is possible in + // the current context...so hide the UI. + if (!scan) { + this.updateUi_(importer.ResponseId.HIDDEN); + } + return; + } - // If there is no Google Drive mount, Drive may be disabled - // or the machine may be running in guest mode. - if (!this.environment_.isGoogleDriveMounted()) { - return importer.ImportController.createUpdate_( - importer.ResponseId.HIDDEN); - } + // At this point we have an existing scan, and a relatively + // validate environment for an import...so we'll proceed + // with making updates to the UI. + if (!opt_scan.isFinal()) { + this.updateUi_(importer.ResponseId.SCANNING, opt_scan); + return; + } - var scan = this.getScan_(); - if (!scan) { - return importer.ImportController.createUpdate_( - importer.ResponseId.HIDDEN); - } + if (opt_scan.getFileEntries().length === 0) { + this.updateUi_(importer.ResponseId.NO_MEDIA); + return; + } - if (!scan.isFinal()) { - return importer.ImportController.createUpdate_( - importer.ResponseId.SCANNING); - } + // We have a final scan that is either too big, or juuuussttt right. + this.fitsInAvailableSpace_(opt_scan).then( + /** @param {boolean} fits */ + function(fits) { + if (!fits) { + this.updateUi_( + importer.ResponseId.INSUFFICIENT_SPACE, + opt_scan); + return; + } - if (scan.getFileEntries().length === 0) { - return importer.ImportController.createUpdate_( - importer.ResponseId.NO_MEDIA); - } - - return this.fitsInAvailableSpace_(scan).then( - /** @param {boolean} fits */ - function(fits) { - return fits ? - importer.ImportController.createUpdate_( - importer.ResponseId.EXECUTABLE, - scan.getFileEntries().length) : - importer.ImportController.createUpdate_( - importer.ResponseId.INSUFFICIENT_SPACE, - scan.getTotalBytes()); - }); + this.updateUi_( + importer.ResponseId.EXECUTABLE, + opt_scan); }.bind(this)); }; /** * @param {importer.ResponseId} responseId - * @param {number=} opt_value Numeric value passed to string, if any. + * @param {importer.ScanResult=} opt_scan * * @return {!importer.CommandUpdate} * @private */ -importer.ImportController.createUpdate_ = - function(responseId, opt_value) { +importer.ImportController.prototype.updateUi_ = + function(responseId, opt_scan) { switch(responseId) { case importer.ResponseId.EXECUTABLE: - return { + this.commandWidget_.update({ id: responseId, - label: strf('CLOUD_IMPORT_BUTTON_LABEL', opt_value), + label: strf( + 'CLOUD_IMPORT_BUTTON_LABEL', + opt_scan.getFileEntries().length), visible: true, executable: true, coreIcon: 'cloud-upload' - }; + }); + this.commandWidget_.updateDetails(opt_scan); + break; case importer.ResponseId.HIDDEN: - return { + this.commandWidget_.update({ id: responseId, visible: false, executable: false, label: '** SHOULD NOT BE VISIBLE **', coreIcon: 'cloud-off' - }; + }); + this.commandWidget_.setDetailsVisible(false); + break; case importer.ResponseId.ACTIVE_IMPORT: - return { + this.commandWidget_.update({ id: responseId, visible: true, executable: false, label: str('CLOUD_IMPORT_ACTIVE_IMPORT_BUTTON_LABEL'), - coreIcon: 'trending-up' - }; + coreIcon: 'swap-vert' + }); + this.commandWidget_.setDetailsVisible(false); + break; case importer.ResponseId.INSUFFICIENT_SPACE: - return { + this.commandWidget_.update({ id: responseId, visible: true, executable: false, - label: strf('CLOUD_IMPORT_INSUFFICIENT_SPACE_BUTTON_LABEL', opt_value), + label: strf( + 'CLOUD_IMPORT_INSUFFICIENT_SPACE_BUTTON_LABEL', + opt_scan.getTotalBytes()), coreIcon: 'report-problem' - }; + }); + this.commandWidget_.updateDetails(opt_scan); + break; case importer.ResponseId.NO_MEDIA: - return { + this.commandWidget_.update({ id: responseId, visible: true, executable: false, label: str('CLOUD_IMPORT_EMPTY_SCAN_BUTTON_LABEL'), coreIcon: 'cloud-done' - }; + }); + this.commandWidget_.updateDetails( + /** @type {!importer.ScanResult} */ (opt_scan)); + break; case importer.ResponseId.SCANNING: - return { + this.commandWidget_.update({ id: responseId, visible: true, executable: false, label: str('CLOUD_IMPORT_SCANNING_BUTTON_LABEL'), coreIcon: 'autorenew' - }; + }); + this.commandWidget_.updateDetails( + /** @type {!importer.ScanResult} */ (opt_scan)); + break; default: assertNotReached('Unrecognized response id: ' + responseId); } @@ -286,14 +360,13 @@ }; /** - * Get or create scan for the current directory or file selection. + * Attempts to scan the current context. * - * @return {importer.ScanResult} A scan result object that may be - * actively scanning. Null if scan is not possible in current - * context. + * @return {importer.ScanResult} A scan object, + * or null if scan is not possible in current context. * @private */ -importer.ImportController.prototype.getScan_ = function() { +importer.ImportController.prototype.tryScan_ = function() { var entries = this.environment_.getSelection(); if (entries.length) { @@ -302,36 +375,13 @@ return this.scanManager_.getSelectionScan(entries); } } else if (this.isCurrentDirectoryScannable_()) { - var directory = this.environment_.getCurrentDirectory(); - var volumeId = this.environment_.getVolumeInfo(directory).volumeId; - - return this.scanManager_.getDirectoryScan(volumeId, directory); + return this.scanManager_.getCurrentDirectoryScan(); } return null; }; /** - * @param {string} volumeId - * @private - */ -importer.ImportController.prototype.onVolumeUnmounted_ = function(volumeId) { - this.scanManager_.reset(); - this.pushUpdate_(); -}; - -/** @private */ -importer.ImportController.prototype.onDirectoryChanged_ = function() { - this.pushUpdate_(); -}; - -/** @private */ -importer.ImportController.prototype.onSelectionChanged_ = function() { - this.scanManager_.clearSelectionScan(); - this.pushUpdate_(); -}; - -/** * Interface abstracting away the concrete file manager available * to commands. By hiding file manager we make it easy to test * ImportController. @@ -514,13 +564,17 @@ * * @param {function()} listener */ -importer.CommandWidget.prototype.addExecuteListener; +importer.CommandWidget.prototype.addImportClickedListener; -/** - * @param {!importer.CommandUpdate} update - */ +/** @param {!importer.CommandUpdate} update */ importer.CommandWidget.prototype.update; +/** @param {!importer.ScanResult} scan */ +importer.CommandWidget.prototype.updateDetails; + +/** Resets details to default. */ +importer.CommandWidget.prototype.resetDetails; + /** * Runtime implementation of CommandWidget. * @@ -529,39 +583,89 @@ * @struct */ importer.RuntimeCommandWidget = function() { - /** @private {Element} */ - this.buttonElement_ = document.querySelector('#cloud-import-button'); - - this.buttonElement_.onclick = this.notifyExecuteListener_.bind(this); /** @private {Element} */ - this.iconElement_ = document.querySelector('#cloud-import-button core-icon'); + this.importButton_ = document.getElementById('cloud-import-button'); + this.importButton_.onclick = this.onImportClicked_.bind(this); + + /** @private {Element} */ + this.detailsButton_ = document.getElementById('cloud-import-details-button'); + this.detailsButton_.onclick = this.toggleDetails_.bind(this); + + /** @private {Element} */ + this.detailsImportButton_ = + document.querySelector('#cloud-import-details .import'); + this.detailsImportButton_.onclick = this.onImportClicked_.bind(this); + + /** @private {Element} */ + this.detailsPanel_ = document.getElementById('cloud-import-details'); + + /** @private {Element} */ + this.photoCount_ = + document.querySelector('#cloud-import-details .photo-count'); + + /** @private {Element} */ + this.spaceRequired_ = + document.querySelector('#cloud-import-details .space-required'); + + /** @private {Element} */ + this.icon_ = document.querySelector('#cloud-import-button core-icon'); /** @private {function()} */ - this.listener_; + this.importListener_; }; /** @override */ -importer.RuntimeCommandWidget.prototype.addExecuteListener = +importer.RuntimeCommandWidget.prototype.addImportClickedListener = function(listener) { - console.assert(!this.listener_); - this.listener_ = listener; + console.assert(!this.importListener_); + this.importListener_ = listener; }; /** @private */ -importer.RuntimeCommandWidget.prototype.notifyExecuteListener_ = function() { - console.assert(!!this.listener_); - this.listener_(); +importer.RuntimeCommandWidget.prototype.onImportClicked_ = function() { + console.assert(!!this.importListener_); + this.importListener_(); +}; + +/** @private */ +importer.RuntimeCommandWidget.prototype.toggleDetails_ = function() { + this.setDetailsVisible(this.detailsPanel_.className === 'offscreen'); +}; + +importer.RuntimeCommandWidget.prototype.setDetailsVisible = function(visible) { + if (visible) { + this.detailsPanel_.className = ''; + } else { + this.detailsPanel_.className = 'offscreen'; + } }; /** @override */ importer.RuntimeCommandWidget.prototype.update = function(update) { - this.buttonElement_.setAttribute('title', update.label); - this.buttonElement_.disabled = !update.executable; - this.buttonElement_.style.display = update.visible ? 'block' : 'none'; - this.iconElement_.setAttribute('icon', update.coreIcon); + this.importButton_.setAttribute('title', update.label); + this.importButton_.disabled = !update.executable; + this.importButton_.style.display = + update.visible ? 'block' : 'none'; + + this.icon_.setAttribute('icon', update.coreIcon); + + this.detailsButton_.disabled = !update.executable; + this.detailsButton_.style.display = + update.visible ? 'block' : 'none'; }; +/** @override */ +importer.RuntimeCommandWidget.prototype.updateDetails = function(scan) { + this.photoCount_.textContent = scan.getFileEntries().length; + this.spaceRequired_.textContent = scan.getTotalBytes(); +}; + +/** @override */ +importer.RuntimeCommandWidget.prototype.resetDetails = function() { + this.photoCount_.textContent = 0; + this.spaceRequired_.textContent = 0; +}; /** * A cache for ScanResults. @@ -569,24 +673,30 @@ * @constructor * @struct * + * @param {!importer.ControllerEnvironment} environment * @param {!importer.MediaScanner} scanner */ -importer.ScanManager = function(scanner) { +importer.ScanManager = function(environment, scanner) { + + /** @private {!importer.ControllerEnvironment} */ + this.environment_ = environment; + /** @private {!importer.MediaScanner} */ this.scanner_ = scanner; /** - * The most recent scan based on user selected files (instead of directories). + * A cache of selection scans by directory (url). + * * @private {importer.ScanResult} */ - this.lastSelectionScan_ = null; + this.selectionScan_ = null; /** - * A cache of scans by volumeId, directory URL. - * Currently only scans of directories are cached. - * @private {!Object.<string, !Object.<string, !importer.ScanResult>>} + * A cache of scans by directory (url). + * + * @private {!Object.<string, !importer.ScanResult>} */ - this.cachedScans_ = {}; + this.directoryScans_ = {}; }; /** @@ -598,54 +708,68 @@ }; /** - * Forgets the selection scans. + * Forgets the selection scans for the current directory. */ importer.ScanManager.prototype.clearSelectionScan = function() { - this.lastSelectionScan_ = null; + this.selectionScan_ = null; }; /** * Forgets directory scans. */ importer.ScanManager.prototype.clearDirectoryScans = function() { - this.cachedScans_ = {}; + this.directoryScans_ = {}; }; /** - * Returns a scan for the directory. + * @return {importer.ScanResult} Current active scan, or null + * if none. + */ +importer.ScanManager.prototype.getActiveScan = function() { + return this.selectionScan_ || + this.directoryScans_[this.environment_.getCurrentDirectory().toURL()] || + null; +}; + +/** + * @param {importer.ScanResult} scan + * @return {boolean} True if scan is the active scan...meaning the current + * selection scan or the scan for the current directory. + */ +importer.ScanManager.prototype.isActiveScan = function(scan) { + return scan === this.selectionScan_ || + scan === this.directoryScans_[ + this.environment_.getCurrentDirectory().toURL()]; +}; + +/** + * Returns the existing selection scan or a new one for the supplied + * selection. * * @param {!Array.<!FileEntry>} entries * * @return {!importer.ScanResult} */ -importer.ScanManager.prototype.getSelectionScan = - function(entries) { - if (!this.lastSelectionScan_) { - this.lastSelectionScan_ = this.scanner_.scan(entries); - } - return this.lastSelectionScan_; +importer.ScanManager.prototype.getSelectionScan = function(entries) { + console.assert(!this.selectionScan_, + 'Cannot create new selection scan with another in the cache.'); + this.selectionScan_ = this.scanner_.scan(entries); + return this.selectionScan_; }; /** * Returns a scan for the directory. * - * @param {string} volumeId - * @param {!DirectoryEntry} directory - * * @return {!importer.ScanResult} */ -importer.ScanManager.prototype.getDirectoryScan = - function(volumeId, directory) { - // Lazily initialize the cache for volumeId. - if (!(volumeId in this.cachedScans_)) { - this.cachedScans_[volumeId] = {}; - } - +importer.ScanManager.prototype.getCurrentDirectoryScan = function() { + var directory = this.environment_.getCurrentDirectory(); var url = directory.toURL(); - var scan = this.cachedScans_[volumeId][url]; + var scan = this.directoryScans_[url]; if (!scan) { scan = this.scanner_.scan([directory]); - this.cachedScans_[volumeId][url] = scan; + this.directoryScans_[url] = scan; } + return scan; };
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js index d2c47fc..b7d71649 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js
@@ -57,227 +57,6 @@ mediaImporter = new TestImportRunner(); } -function testGetCommandUpdate_HiddenWhenDriveUnmounted(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos1/IMG00001.jpg' - ], - '/DCIM'); - - environment.isDriveMounted = false; - var promise = controller.getCommandUpdate().then( - function(response) { - assertFalse(response.visible); - assertFalse(response.executable); - - mediaScanner.assertScanCount(0); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_HiddenForNonMediaVolume(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'drive', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg' - ], - '/DCIM'); - - environment.isDriveMounted = false; - - var promise = controller.getCommandUpdate().then( - function(response) { - assertFalse(response.visible); - assertFalse(response.executable); - - mediaScanner.assertScanCount(0); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_InitiatesScan(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg', - '/DCIM/photos0/IMG00002.jpg', - '/DCIM/photos1/', - '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' - ], - '/DCIM'); - - var promise = controller.getCommandUpdate().then( - function(response) { - assertTrue(response.visible); - assertFalse(response.executable); - assertEquals( - response.label, - MESSAGES.CLOUD_IMPORT_SCANNING_BUTTON_LABEL); - mediaScanner.assertScanCount(1); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_CanExecuteAfterScanIsFinalized(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg', - '/DCIM/photos0/IMG00002.jpg', - '/DCIM/photos1/', - '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' - ], - '/DCIM'); - - var fileSystem = new MockFileSystem('testFs'); - mediaScanner.fileEntries.push( - new MockFileEntry(fileSystem, '/DCIM/photos0/IMG00001.jpg', {size: 0})); - - environment.directoryChangedListener_(); // initiates a scan. - var promise = widget.updatePromise.then( - function() { - widget.resetPromise(); - mediaScanner.finalizeScans(); - return widget.updatePromise; - }).then( - function(response) { - assertTrue(response.visible); - assertTrue(response.executable); - assertEquals( - response.label, - MESSAGES.CLOUD_IMPORT_BUTTON_LABEL); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_DisabledForInsufficientLocalStorage(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg', - '/DCIM/photos0/IMG00002.jpg', - '/DCIM/photos1/', - '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' - ], - '/DCIM'); - - var fileSystem = new MockFileSystem('testFs'); - mediaScanner.fileEntries.push( - new MockFileEntry( - fileSystem, - '/DCIM/photos0/IMG00001.jpg', - {size: 1000000})); - - environment.freeStorageSpace = 100; - environment.directoryChangedListener_(); // initiates a scan. - var promise = widget.updatePromise.then( - function() { - widget.resetPromise(); - mediaScanner.finalizeScans(); - return widget.updatePromise; - }).then( - function(response) { - assertTrue(response.visible); - assertFalse(response.executable); - assertEquals( - response.label, - MESSAGES.CLOUD_IMPORT_INSUFFICIENT_SPACE_BUTTON_LABEL); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_CannotExecuteEmptyScanResult(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.trader', - '/DCIM/photos0/IMG00002.joes', - '/DCIM/photos1/', - '/DCIM/photos1/IMG00001.parking', - '/DCIM/photos1/IMG00003.lots' - ], - '/DCIM'); - - var promise = controller.getCommandUpdate().then( - function() { - mediaScanner.finalizeScans(); - - return controller.getCommandUpdate().then( - function(response) { - assertTrue(response.visible); - assertFalse(response.executable); - assertEquals( - response.label, - MESSAGES.CLOUD_IMPORT_EMPTY_SCAN_BUTTON_LABEL); - }); - }); - - reportPromise(promise, callback); -} - -function testGetCommandUpdate_DisabledWhileImporting(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg', - '/DCIM/photos0/IMG00002.jpg', - ], - '/DCIM'); - -// First we need to force the controller into a scanning state. -environment.directoryChangedListener_(); - -var promise = widget.updatePromise.then( - function() { - widget.resetPromise(); - widget.executeListener(); - mediaImporter.assertImportsStarted(1); - // return the reset promise so as to allow execution - // to complete before the test is finished...even though - // we're not waiting on anything in particular. - return controller.getCommandUpdate(); - }).then( - function(response) { - assertTrue(response.visible); - assertFalse(response.executable); - assertEquals( - response.label, - MESSAGES.CLOUD_IMPORT_ACTIVE_IMPORT_BUTTON_LABEL); - }); - - reportPromise(promise, callback); -} - function testClick_StartsImport(callback) { var controller = createController( VolumeManagerCommon.VolumeType.MTP, @@ -302,7 +81,6 @@ // return the reset promise so as to allow execution // to complete before the test is finished...even though // we're not waiting on anything in particular. - return widget.updatePromise; }), callback); } @@ -332,6 +110,7 @@ // A fresh new scan should be started. environment.simulateUnmount(); + environment.directoryChangedListener_(); // Return the new promise, so subsequent "thens" only // fire once the widget has been updated again. return widget.updatePromise; @@ -373,23 +152,6 @@ reportPromise(widget.updatePromise, callback); } -function testVolumeUnmount_TriggersUpdate(callback) { - var controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', - [ - '/DCIM/', - '/DCIM/photos0/', - '/DCIM/photos0/IMG00001.jpg', - ], - '/DCIM'); - - // Faux unmount the volume, then request an update again. - // A fresh new scan should be started. - environment.simulateUnmount(); - reportPromise(widget.updatePromise, callback); -} - function testFinalizeScans_TriggersUpdate(callback) { var controller = createController( VolumeManagerCommon.VolumeType.MTP, @@ -467,7 +229,11 @@ }).then( function() { widget.resetPromise(); + // This will invalidate scans...and trigger a state check... + // itself triggering a scan. mediaImporter.finishImportTasks(); + // Trigger the update needed to cause a UI update. + mediaScanner.update(); return widget.updatePromise; }); @@ -501,6 +267,8 @@ function() { widget.resetPromise(); mediaImporter.cancelImportTasks(); + // Trigger the update needed to cause a UI update. + mediaScanner.update(); return widget.updatePromise; }); @@ -729,7 +497,8 @@ }; /** @override */ -importer.TestCommandWidget.prototype.addExecuteListener = function(listener) { +importer.TestCommandWidget.prototype.addImportClickedListener = + function(listener) { this.executeListener = listener; }; @@ -739,6 +508,27 @@ this.updateResolver_.resolve(update); }; +/** @override */ +importer.TestCommandWidget.prototype.updateDetails = function(scan) { + // TODO(smckay) +}; + +/** @override */ +importer.TestCommandWidget.prototype.resetDetails = function() { + // TODO(smckay) +}; + +/** @override */ +importer.TestCommandWidget.prototype.setDetailsVisible = function(visible) { + // TODO(smckay) +}; + +/** @override */ +importer.TestCommandWidget.prototype.isDetailsVisible = function() { + // TODO(smckay) +}; + + /** * @param {!VolumeManagerCommon.VolumeType} volumeType * @param {string} volumeId
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js index ca75009..8c6b44a 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js
@@ -10,17 +10,6 @@ * is responsible to return dataUrls of valid thumbnails and fetch them with * proper priority. * - * TODOs - * The following list is a todo list for this class. This list will be deleted - * after all of them are implemented. - * * Done: Fetch thumbnails with range based priority control. - * * Implement cache size limitation. - * * Modest queueing for low priority thumbnail fetches (i.e. not to use up IO - * by low priority tasks). - * * Handle other event types of FileListModel, e.g. sort. - * * Change ThumbnailLoader to directly return dataUrl. - * * Handle file types for which generic images are used. - * * @param {!FileListModel} dataModel A file list model. * @param {!MetadataCache} metadataCache Metadata cache. * @param {!Document} document Document. @@ -66,12 +55,10 @@ this.active_ = {}; /** - * @type {Object<string, !Object>} + * @type {LRUCache<!ListThumbnailLoader.ThumbnailData>} * @private - * - * TODO(yawano) Add size limitation to the cache. */ - this.cache_ = {}; + this.cache_ = new LRUCache(ListThumbnailLoader.CACHE_SIZE); /** * @type {number} @@ -92,8 +79,10 @@ */ this.cursor_ = 0; - // TODO(yawano) Handle other event types of FileListModel, e.g. sort. + // TODO(yawano): Change FileListModel to dispatch change event for file + // change, and change this class to handle it. this.dataModel_.addEventListener('splice', this.onSplice_.bind(this)); + this.dataModel_.addEventListener('sorted', this.onSorted_.bind(this)); } ListThumbnailLoader.prototype.__proto__ = cr.EventTarget.prototype; @@ -105,19 +94,36 @@ ListThumbnailLoader.NUM_OF_MAX_ACTIVE_TASKS = 5; /** + * Number of prefetch requests. + * @const {number} + */ +ListThumbnailLoader.NUM_OF_PREFETCH = 10; + +/** + * Cache size. Cache size must be larger than sum of high priority range size + * and number of prefetch tasks. + * @const {number} + */ +ListThumbnailLoader.CACHE_SIZE = 100; + +/** * An event handler for splice event of data model. When list is changed, start * to rescan items. * * @param {!Event} event Event */ ListThumbnailLoader.prototype.onSplice_ = function(event) { - // Delete thumbnails of removed items from cache. - for (var i = 0; i < event.removed.length; i++) { - var removedItem = event.removed[i]; - if (this.cache_[removedItem.toURL()]) - delete this.cache_[removedItem.toURL()]; - } + this.cursor_ = this.beginIndex_; + this.continue_(); +} +/** + * An event handler for sorted event of data model. When list is sorted, start + * to rescan items. + * + * @param {!Event} event Event + */ +ListThumbnailLoader.prototype.onSorted_ = function(event) { this.cursor_ = this.beginIndex_; this.continue_(); } @@ -146,7 +152,9 @@ * @return {Object} If the thumbnail is not in cache, this returns null. */ ListThumbnailLoader.prototype.getThumbnailFromCache = function(entry) { - return this.cache_[entry.toURL()] || null; + // Since we want to evict cache based on high priority range, we use peek here + // instead of get. + return this.cache_.peek(entry.toURL()) || null; } /** @@ -156,7 +164,8 @@ // If tasks are running full or all items are scanned, do nothing. if (!(Object.keys(this.active_).length < ListThumbnailLoader.NUM_OF_MAX_ACTIVE_TASKS) || - !(this.cursor_ < this.dataModel_.length)) { + !(this.cursor_ < this.dataModel_.length) || + !(this.cursor_ < this.endIndex_ + ListThumbnailLoader.NUM_OF_PREFETCH)) { return; } @@ -164,7 +173,7 @@ // If the entry is a directory, already in cache or fetching, skip it. if (entry.isDirectory || - this.cache_[entry.toURL()] || + this.cache_.get(entry.toURL()) || this.active_[entry.toURL()]) { this.continue_(); return; @@ -184,13 +193,17 @@ entry, this.metadataCache_, this.document_, this.thumbnailLoaderConstructor_); - this.active_[entry.toURL()] = task; + var url = entry.toURL(); + this.active_[url] = task; task.fetch().then(function(thumbnail) { - delete this.active_[thumbnail.fileUrl]; - this.cache_[thumbnail.fileUrl] = thumbnail; + delete this.active_[url]; + this.cache_.put(url, thumbnail); this.dispatchThumbnailLoaded_(thumbnail); this.continue_(); + }.bind(this), function() { + delete this.active_[url]; + this.continue_(); }.bind(this)); } @@ -200,7 +213,7 @@ * @param {Object} thumbnail Thumbnail. */ ListThumbnailLoader.prototype.dispatchThumbnailLoaded_ = function(thumbnail) { - // TODO(yawano) Create ThumbnailLoadedEvent class. + // TODO(yawano): Create ThumbnailLoadedEvent class. var event = new Event('thumbnailLoaded'); event.fileUrl = thumbnail.fileUrl; event.dataUrl = thumbnail.dataUrl; @@ -210,6 +223,37 @@ }; /** + * A class to represent thumbnail data. + * @param {string} fileUrl File url of an original image. + * @param {string} dataUrl Data url of thumbnail. + * @param {number} width Width of thumbnail. + * @param {number} height Height of thumbnail. + * @constructor + * @struct + */ +ListThumbnailLoader.ThumbnailData = function(fileUrl, dataUrl, width, height) { + /** + * @const {string} + */ + this.fileUrl = fileUrl; + + /** + * @const {string} + */ + this.dataUrl = dataUrl; + + /** + * @const {number} + */ + this.width = width; + + /** + * @const {number} + */ + this.height = height; +} + +/** * A task to load thumbnail. * * @param {!Entry} entry An entry. @@ -230,43 +274,20 @@ /** * Fetches thumbnail. - * TODO(yawano) Add error handling. * - * @return {!Promise} A promise which is resolved when thumbnail is fetched. + * @return {!Promise<!ListThumbnailLoader.ThumbnailData>} A promise which is + * resolved when thumbnail is fetched. */ ListThumbnailLoader.Task.prototype.fetch = function() { return new Promise(function(resolve, reject) { - this.metadataCache_.getOne(this.entry_, - 'thumbnail|filesystem|external|media', - function(metadata) { - // TODO(yawano) Change ThumbnailLoader to directly return data url of - // an image. - var box = this.document_.createElement('div'); - - var thumbnailLoader = new this.thumbnailLoaderConstructor_( - this.entry_, - ThumbnailLoader.LoaderType.IMAGE, - metadata); - thumbnailLoader.load(box, - ThumbnailLoader.FillMode.FIT, - ThumbnailLoader.OptimizationMode.DISCARD_DETACHED, - function(image, transform) { - // TODO(yawano) Transform an image if necessary. - var canvas = this.document_.createElement('canvas'); - canvas.width = image.width; - canvas.height = image.height; - - var context = canvas.getContext('2d'); - context.drawImage(image, 0, 0); - - // TODO(yawano) Create ThumbnailData class. - resolve({ - fileUrl: this.entry_.toURL(), - dataUrl: canvas.toDataURL('image/jpeg', 0.5), - width: image.width, - height: image.height - }); - }.bind(this)); - }.bind(this)); + this.metadataCache_.getOne( + this.entry_, 'thumbnail|filesystem|external|media', resolve); + }.bind(this)).then(function(metadata) { + return new this.thumbnailLoaderConstructor_( + this.entry_, ThumbnailLoader.LoaderType.IMAGE, metadata) + .loadAsDataUrl(); + }.bind(this)).then(function(result) { + return new ListThumbnailLoader.ThumbnailData( + this.entry_.toURL(), result.data, result.width, result.height); }.bind(this)); }
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html index ec8bb367..372391c6 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html
@@ -9,6 +9,8 @@ <script src="../../../../webui/resources/js/cr/event_target.js"></script> <script src="../../../../webui/resources/js/cr/ui.js"></script> <script src="../../../../webui/resources/js/cr/ui/array_data_model.js"></script> +<script src="../../common/js/lru_cache.js"></script> +<script src="../../common/js/util.js"></script> <script src="../../common/js/mock_entry.js"></script> <script src="../../common/js/unittest_util.js"></script> <script src="directory_contents.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js index 8392ab1..0f506988 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js
@@ -52,10 +52,16 @@ var entry3 = new MockEntry(fileSystem, '/Test3.jpg'); var entry4 = new MockEntry(fileSystem, '/Test4.jpg'); var entry5 = new MockEntry(fileSystem, '/Test5.jpg'); +var entry6 = new MockEntry(fileSystem, '/Test6.jpg'); function setUp() { ListThumbnailLoader.NUM_OF_MAX_ACTIVE_TASKS = 2; - MockThumbnailLoader.setTestImageDataUrl(generateSampleImageDataUrl(document)); + ListThumbnailLoader.NUM_OF_PREFETCH = 1; + ListThumbnailLoader.CACHE_SIZE = 5; + MockThumbnailLoader.errorUrls = []; + MockThumbnailLoader.testImageDataUrl = generateSampleImageDataUrl(document); + MockThumbnailLoader.testImageWidth = 160; + MockThumbnailLoader.testImageHeight = 160; getOneCallbacks = {}; var metadataCache = { @@ -81,6 +87,14 @@ delete getOneCallbacks[url]; } +function areEntriesInCache(entries) { + for (var i = 0; i < entries.length; i++) { + if (null === listThumbnailLoader.getThumbnailFromCache(entries[i])) + return false; + } + return true; +} + /** * Story test for list thumbnail loader. */ @@ -142,14 +156,6 @@ !!getOneCallbacks[entry4.toURL()] && Object.keys(getOneCallbacks).length === 2; }); - }).then(function() { - // Cache is deleted when the item is removed from the list. - var result = fileListModel.splice(2, 1); // Remove Test2.jpg. - - // Fail to fetch thumbnail from cache. - return waitUntil(function() { - return listThumbnailLoader.getThumbnailFromCache(entry2) === null; - }); }), callback); } @@ -167,3 +173,99 @@ assertEquals('filesystem:volume-id/Test5.jpg', Object.keys(getOneCallbacks)[0]); } + +function testCache(callback) { + ListThumbnailLoader.NUM_OF_MAX_ACTIVE_TASKS = 5; + + // Set high priority range to 0 - 2. + listThumbnailLoader.setHighPriorityRange(0, 2); + fileListModel.push(entry1, entry2, entry3, entry4, entry5, entry6); + + resolveGetOneCallback(entry1.toURL()); + // In this test case, entry 3 is resolved earlier than entry 2. + resolveGetOneCallback(entry3.toURL()); + resolveGetOneCallback(entry2.toURL()); + assertEquals(0, Object.keys(getOneCallbacks).length); + + reportPromise(waitUntil(function() { + return areEntriesInCache([entry3, entry2, entry1]); + }).then(function() { + // Move high priority range to 1 - 3. + listThumbnailLoader.setHighPriorityRange(1, 3); + resolveGetOneCallback(entry4.toURL()); + assertEquals(0, Object.keys(getOneCallbacks).length); + + return waitUntil(function() { + return areEntriesInCache([entry4, entry3, entry2, entry1]); + }); + }).then(function() { + // Move high priority range to 4 - 6. + listThumbnailLoader.setHighPriorityRange(4, 6); + resolveGetOneCallback(entry5.toURL()); + resolveGetOneCallback(entry6.toURL()); + assertEquals(0, Object.keys(getOneCallbacks).length); + + return waitUntil(function() { + return areEntriesInCache([entry6, entry5, entry4, entry3, entry2]); + }); + }).then(function() { + // Move high priority range to 3 - 5. + listThumbnailLoader.setHighPriorityRange(3, 5); + assertEquals(0, Object.keys(getOneCallbacks).length); + assertTrue(areEntriesInCache([entry6, entry5, entry4, entry3, entry2])); + + // Move high priority range to 0 - 2. + listThumbnailLoader.setHighPriorityRange(0, 2); + resolveGetOneCallback(entry1.toURL()); + assertEquals(0, Object.keys(getOneCallbacks).length); + + return waitUntil(function() { + return areEntriesInCache([entry3, entry2, entry1, entry6, entry5]); + }); + }), callback); +} + +/** + * Test case for thumbnail fetch error. In this test case, thumbnail fetch for + * entry 2 is failed. + */ +function testErrorHandling(callback) { + MockThumbnailLoader.errorUrls = [entry2.toURL()]; + + listThumbnailLoader.setHighPriorityRange(0, 2); + fileListModel.push(entry1, entry2, entry3, entry4); + + resolveGetOneCallback(entry2.toURL()); + + // Assert that new task is enqueued for entry3. + reportPromise(waitUntil(function() { + return !!getOneCallbacks[entry3.toURL()]; + }), callback); +} + +/** + * Test case for handling sorted event in data model. + */ +function testSortedEvent(callback) { + listThumbnailLoader.setHighPriorityRange(0, 2); + fileListModel.push(directory1, entry1, entry2, entry3, entry4, entry5); + + resolveGetOneCallback(entry1.toURL()); + resolveGetOneCallback(entry2.toURL()); + assertEquals(0, Object.keys(getOneCallbacks).length); + + // In order to assert that following task enqueues are fired by sorted event, + // wait until all thumbnail loads are completed. + reportPromise(waitUntil(function() { + return thumbnailLoadedEvents.length === 2; + }).then(function() { + // After the sort, list should be + // directory1, entry5, entry4, entry3, entry2, entry1. + fileListModel.sort('name', 'desc'); + + return waitUntil(function() { + return !!getOneCallbacks[entry5.toURL()] && + !!getOneCallbacks[entry4.toURL()] + }); + }), callback); +}
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index 1baecae..dfbe1a38 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -82,6 +82,8 @@ //<include src="ui/combobutton.js"> //<include src="ui/commandbutton.js"> //<include src="ui/file_manager_dialog_base.js"> +//<include src="metadata/metadata_cache_set.js"> +//<include src="metadata/new_metadata_provider.js"> // //<include src="app_installer.js"> //<include src="app_state_controller.js"> @@ -100,17 +102,21 @@ //<include src="gear_menu_controller.js"> //<include src="import_controller.js"> //<include src="launch_param.js"> +//<include src="metadata/external_metadata_provider.js"> +//<include src="metadata/file_system_metadata.js"> +//<include src="metadata/file_system_metadata_provider.js"> //<include src="metadata/metadata_cache.js"> +//<include src="metadata/metadata_cache_item.js"> //<include src="metadata_update_controller.js"> //<include src="naming_controller.js"> //<include src="navigation_list_model.js"> -//<include src="preview_panel_model.js"> //<include src="progress_center_item_group.js"> //<include src="scan_controller.js"> //<include src="search_controller.js"> //<include src="share_client.js"> //<include src="spinner_controller.js"> //<include src="task_controller.js"> +//<include src="toolbar_controller.js"> //<include src="thumbnail_loader.js"> //<include src="ui/banners.js" > //<include src="ui/conflict_dialog.js"> @@ -126,7 +132,6 @@ //<include src="ui/list_container.js"> //<include src="ui/location_line.js"> //<include src="ui/multi_profile_share_dialog.js"> -//<include src="ui/preview_panel.js"> //<include src="ui/progress_center_panel.js"> //<include src="ui/scrollbar.js"> //<include src="ui/search_box.js">
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js index f2473b5..b8eb48b 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js
@@ -23,14 +23,14 @@ * sharedWithMe: (boolean|undefined) * }} */ -var ExternalMetadata; +var ExternalMetadataProperties; /** * Metadata provider for FileEntry#getMetadata. * * @param {!MetadataProviderCache} cache * @constructor - * @extends {NewMetadataProvider<!ExternalMetadata>} + * @extends {NewMetadataProvider<!ExternalMetadataProperties>} * @struct */ function ExternalMetadataProvider(cache) { @@ -80,7 +80,7 @@ /** * @param {!Array<!MetadataRequest>} requests * @param {!Array<!EntryProperties>} propertiesList - * @return {!Array<!ExternalMetadata>} + * @return {!Array<!ExternalMetadataProperties>} */ ExternalMetadataProvider.prototype.convertResults_ = function(requests, propertiesList) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js new file mode 100644 index 0000000..93e03ee9 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js
@@ -0,0 +1,100 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @param {!MetadataProviderCache} cache + * @param {!FileSystemMetadataProvider} fileSystemMetadataProvider + * @param {!ExternalMetadataProvider} externalMetadataProvider + * @param {!VolumeManagerWrapper} volumeManager + * @constructor + * @struct + */ +function FileSystemMetadata( + cache, + fileSystemMetadataProvider, + externalMetadataProvider, + volumeManager) { + /** + * @private {!MetadataProviderCache} + * @const + */ + this.cache_ = cache; + + /** + * @private {!FileSystemMetadataProvider} + * @const + */ + this.fileSystemMetadataProvider_ = fileSystemMetadataProvider; + + /** + * @private {!ExternalMetadataProvider} + * @const + */ + this.externalMetadataProvider_ = externalMetadataProvider; + + /** + * @private {!VolumeManagerWrapper} + * @const + */ + this.volumeManager_ = volumeManager; +} + +/** + * Obtains metadata for entries. + * @param {!Array<!Entry>} entries Entries. + * @param {!Array<string>} names Metadata property names to be obtained. + * @return {!Promise<!Array<!ExternalMetadataProperties>>} + */ +FileSystemMetadata.prototype.get = function(entries, names) { + var localEntries = []; + var localEntryIndexes = []; + var externalEntries = []; + var externalEntryIndexes = []; + for (var i = 0; i < entries.length; i++) { + var volumeInfo = this.volumeManager_.getVolumeInfo(entries[i]); + if (volumeInfo && + (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE || + volumeInfo.volumeType === VolumeManagerCommon.VolumeType.PROVIDED)) { + externalEntries.push(entries[i]); + externalEntryIndexes.push(i); + } else { + localEntries.push(entries[i]); + localEntryIndexes.push(i); + } + } + + return Promise.all([ + this.fileSystemMetadataProvider_.get(localEntries, names), + this.externalMetadataProvider_.get(externalEntries, names) + ]).then(function(results) { + var integratedResults = []; + var localResults = results[0]; + for (var i = 0; i < localResults.length; i++) { + integratedResults[localEntryIndexes[i]] = localResults[i]; + } + var externalResults = results[1]; + for (var i = 0; i < externalResults.length; i++) { + integratedResults[externalEntryIndexes[i]] = externalResults[i]; + } + return integratedResults; + }); +}; + +/** + * Obtains metadata cache for entries. + * @param {!Array<!Entry>} entries Entries. + * @param {!Array<string>} names Metadata property names to be obtained. + * @return {!Array<!ExternalMetadataProperties>} + */ +FileSystemMetadata.prototype.getCache = function(entries, names) { + return this.cache_.get(entries, names); +}; + +/** + * Clears old metadata for newly created entries. + * @param {!Array<!Entry>} entries + */ +FileSystemMetadata.prototype.notifyEntryCreated = function(entries) { + this.cache_.clear(entries); +};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js index 03531d54..a51b13fe 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js
@@ -5,14 +5,14 @@ /** * @typedef {{modificationTime:Date, size:number}} */ -var FileSystemMetadata; +var FileSystemMetadataProperties; /** * Metadata provider for FileEntry#getMetadata. * * @param {!MetadataProviderCache} cache * @constructor - * @extends {NewMetadataProvider<!FileSystemMetadata>} + * @extends {NewMetadataProvider<!FileSystemMetadataProperties>} * @struct */ function FileSystemMetadataProvider(cache) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html new file mode 100644 index 0000000..da4617f --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + -- Use of this source code is governed by a BSD-style license that can be + -- found in the LICENSE file. + --> +<!-- Base classes --> +<script src="metadata_cache_set.js"></script> +<script src="new_metadata_provider.js"></script> + +<!-- Others --> +<script src="../../../../../../ui/webui/resources/js/assert.js"></script> +<script src="../../../common/js/lru_cache.js"></script> +<script src="../../../common/js/unittest_util.js"></script> +<script src="../../../common/js/volume_manager_common.js"></script> +<script src="external_metadata_provider.js"></script> +<script src="file_system_metadata.js"></script> +<script src="file_system_metadata_provider.js"></script> +<script src="metadata_cache_item.js"></script> + +<script src="file_system_metadata_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js new file mode 100644 index 0000000..a9a4d3e --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js
@@ -0,0 +1,63 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var entryA = { + toURL: function() { return 'filesystem://A'; } +}; + +var entryB = { + toURL: function() { return 'filesystem://B'; } +}; + +function testFileSystemMetadataBasic(callback) { + var cache = new MetadataProviderCache(); + var model = new FileSystemMetadata( + cache, + // Mocking FileSystemMetadataProvider. + { + get: function(urls) { + assertEquals(1, urls.length); + assertEquals('filesystem://A', urls[0].toURL()); + return Promise.resolve( + [{modificationTime: new Date(2015, 0, 1), size: 1024}]); + } + }, + // Mocking ExternalMetadataProvider. + { + get: function(urls) { + assertEquals(1, urls.length); + assertEquals('filesystem://B', urls[0].toURL()); + return Promise.resolve( + [{modificationTime: new Date(2015, 1, 2), size: 2048}]); + } + }, + // Mocking VolumeManagerWrapper. + { + getVolumeInfo: function(entry) { + if (entry.toURL() === 'filesystem://A') { + return { + volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS + }; + } else if (entry.toURL() === 'filesystem://B') { + return { + volumeType: VolumeManagerCommon.VolumeType.DRIVE + }; + } + assertNotReached(); + } + }); + reportPromise( + model.get([entryA, entryB], ['size', 'modificationTime']).then( + function(results) { + assertEquals(2, results.length); + assertEquals( + new Date(2015, 0, 1).toString(), + results[0].modificationTime.toString()); + assertEquals(1024, results[0].size); + assertEquals( + new Date(2015, 1, 2).toString(), + results[1].modificationTime.toString()); + assertEquals(2048, results[1].size); + }), callback); +}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item.js index 663320f..1efae04 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item.js
@@ -62,8 +62,11 @@ for (var name in object) { if (!this.properties_[name]) this.properties_[name] = new MetadataCacheItemProperty(); - if (requestId < this.properties_[name].requestId) + if (requestId < this.properties_[name].requestId || + this.properties_[name].state === + MetadataCacheItemPropertyState.FULFILLED) { continue; + } changed = true; this.properties_[name].requestId = requestId; this.properties_[name].value = object[name];
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js index ca30f5f1..4a5a04a 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js
@@ -80,3 +80,11 @@ assertFalse(item.hasFreshCache(['propertyA', 'propertyB'])); assertTrue(item.hasFreshCache(['propertyA'])); } + +function testMetadataCacheShouldNotUpdateBeforeInvalidation() { + var item = new MetadataCacheItem(); + item.startRequests(1, item.createRequests(['property'])); + item.storeProperties(1, {property: 'value1'}); + item.storeProperties(2, {property: 'value2'}); + assertEquals('value1', item.get(['property']).property); +}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set.js index 15f4693..2893ec32 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set.js
@@ -19,7 +19,7 @@ /** * Creates list of MetadataRequest based on the cache state. - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries * @param {!Array<string>} names * @return {!Array<!MetadataRequest>} */ @@ -56,7 +56,7 @@ * Stores results from NewMetadataProvider with the request Id. * @param {number} requestId Request ID. If a newer operation has already been * done, the results must be ingored. - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries * @param {!Array<!Object>} results * @return {boolean} Whether at least one result is stored or not. */ @@ -75,7 +75,7 @@ /** * Obtains cached properties for entries and names. * Note that it returns invalidated properties also. - * @param {!Array<!FileEntry>} entries Entries. + * @param {!Array<!Entry>} entries Entries. * @param {!Array<string>} names Property names. */ MetadataCacheSet.prototype.get = function(entries, names) { @@ -92,7 +92,7 @@ * time of startRequests. * @param {number} requestId Request ID of the invalidation request. This must * be larger than other requets ID passed to the set before. - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries */ MetadataCacheSet.prototype.invalidate = function(requestId, entries) { for (var i = 0; i < entries.length; i++) { @@ -103,8 +103,18 @@ }; /** + * Clears the caches of entries. + * @param {!Array<!Entry>} entries + */ +MetadataCacheSet.prototype.clear = function(entries) { + for (var i = 0; i < entries.length; i++) { + this.items_.remove(entries[i].toURL()); + } +}; + +/** * Creates snapshot of the cache for entries. - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries */ MetadataCacheSet.prototype.createSnapshot = function(entries) { var items = {}; @@ -119,7 +129,7 @@ /** * Returns whether all the given properties are fulfilled. - * @param {!Array<!FileEntry>} entries Entries. + * @param {!Array<!Entry>} entries Entries. * @param {!Array<string>} names Property names. * @return {boolean} */ @@ -162,6 +172,12 @@ MetadataCacheSetStorage.prototype.put = function(url, item) {}; /** + * Removes an item from the cache. + * @param {string} url Entry URL. + */ +MetadataCacheSetStorage.prototype.remove = function(url) {}; + +/** * Implementation of MetadataCacheSetStorage by using raw object. * @param {Object} items Map of URL and MetadataCacheItem. * @constructor @@ -194,6 +210,13 @@ }; /** + * @override + */ +MetadataCacheSetStorageForObject.prototype.remove = function(url) { + delete this.items_[url]; +}; + +/** * Implementation of MetadataCacheSetStorage by using LRUCache. * @param {!LRUCache<!MetadataCacheItem>} cache LRUCache. * @constructor @@ -230,14 +253,21 @@ }; /** - * @param {!FileEntry} entry Entry + * @override + */ +MetadataCacheSetStorageForLRUCache.prototype.remove = function(url) { + this.cache_.remove(url); +}; + +/** + * @param {!Entry} entry Entry * @param {!Array<string>} names Property name list to be requested. * @constructor * @struct */ function MetadataRequest(entry, names) { /** - * @public {!FileEntry} + * @public {!Entry} * @const */ this.entry = entry;
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set_unittest.js index c429e65..f2618f2 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_set_unittest.js
@@ -122,3 +122,18 @@ assertTrue(set.hasFreshCache([entryA], ['property'])); } + +function testMetadataCacheSetClear() { + var set = new MetadataCacheSet(new MetadataCacheSetStorageForObject({})); + set.startRequests(1, set.createRequests([entryA], ['propertyA'])); + set.storeProperties(1, [entryA], [{propertyA: 'value'}]); + assertTrue(set.hasFreshCache([entryA], ['propertyA'])); + + set.startRequests(1, set.createRequests([entryA], ['propertyB'])); + set.clear([entryA]); + // PropertyB should not be stored because it is requsted before clear. + set.storeProperties(1, [entryA], [{propertyB: 'value'}]); + + assertFalse(set.hasFreshCache([entryA], ['propertyA'])); + assertFalse(set.hasFreshCache([entryA], ['propertyB'])); +}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js index a3c767d81..ccfd227 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js
@@ -45,7 +45,7 @@ /** * Obtains metadata for entries. - * @param {!Array<!FileEntry>} entries Entries. + * @param {!Array<!Entry>} entries Entries. * @param {!Array<string>} names Metadata property names to be obtained. * @return {!Promise<!Array<!T>>} */ @@ -116,7 +116,7 @@ /** * Obtains metadata cache for entries. - * @param {!Array<!FileEntry>} entries Entries. + * @param {!Array<!Entry>} entries Entries. * @param {!Array<string>} names Metadata property names to be obtained. * @return {!Array<!T>} */ @@ -125,7 +125,7 @@ }; /** - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries * @param {!Array<string>} names * @param {!MetadataCacheSet} cache * @param {function(!T):undefined} fulfill @@ -137,7 +137,7 @@ function MetadataProviderCallbackRequest( entries, names, cache, fulfill, reject) { /** - * @private {!Array<!FileEntry>} + * @private {!Array<!Entry>} * @const */ this.entries_ = entries; @@ -171,7 +171,7 @@ * Stores properties to snapshot cache of the callback request. * If all the requested property are served, it invokes the callback. * @param {number} requestId - * @param {!Array<!FileEntry>} entries + * @param {!Array<!Entry>} entries * @param {!Array<!Object>} objects * @return {boolean} Whether the callback is invoked or not. */
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js index be81c33..54cda9f8 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js
@@ -34,6 +34,20 @@ })); }; +function ManualTestMetadataProvider(cache) { + NewMetadataProvider.call( + this, cache, ['propertyA', 'propertyB', 'propertyC']); + this.callback = []; +} + +ManualTestMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +ManualTestMetadataProvider.prototype.getImpl = function(requests) { + return new Promise(function(fulfill) { + this.callback.push(fulfill); + }.bind(this)); +}; + var entryA = { toURL: function() { return "filesystem://A"; } }; @@ -113,6 +127,28 @@ }), callback); } +function testNewMetadataProviderNotUpdateCachedResultAfterRequest( + callback) { + var cache = new MetadataProviderCache(); + var provider = new ManualTestMetadataProvider(cache); + var promise = provider.get([entryA], ['propertyA']); + provider.callback[0]([{propertyA: 'valueA1'}]); + reportPromise(promise.then(function() { + // 'propertyA' is cached here. + var promise1 = provider.get([entryA], ['propertyA', 'propertyB']); + var promise2 = provider.get([entryA], ['propertyC']); + // Returns propertyC. + provider.callback[2]([{propertyA: 'valueA2', propertyC: 'valueC'}]); + provider.callback[1]([{propertyB: 'valueB'}]); + return Promise.all([promise1, promise2]); + }).then(function(results) { + // The result should be cached value at the time when get was called. + assertEquals('valueA1', results[0][0].propertyA); + assertEquals('valueB', results[0][0].propertyB); + assertEquals('valueC', results[1][0].propertyC); + }), callback); +} + function testNewMetadataProviderGetCache(callback) { var cache = new MetadataProviderCache(); var provider = new TestMetadataProvider(cache);
diff --git a/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js index bf49a7ec..d2b4414 100644 --- a/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/mock_thumbnail_loader.js
@@ -14,43 +14,46 @@ */ function MockThumbnailLoader(entry, opt_loaderType, opt_metadata, opt_mediaType, opt_loadTargets, opt_priority) { - this.testImageDataUrl_ = null; + this.entry_ = entry; } /** - * @type {string} Data url of an image. + * Data url of test image. + * @private {string} */ -MockThumbnailLoader.testImageDataUrl_ = null; +MockThumbnailLoader.testImageDataUrl = null; /** - * Set data url of an image which is returned for testing. - * - * @param {string} dataUrl Data url of an image. + * Width of test image. + * @private {number} */ -MockThumbnailLoader.setTestImageDataUrl = function(dataUrl) { - MockThumbnailLoader.testImageDataUrl_ = dataUrl; -}; +MockThumbnailLoader.testImageWidth = 0; /** - * Load an image. (This mock implementation does not attach an image to the - * box). - * - * @param {Element} box Box. - * @param {ThumbnailLoader.FillMode} fillMode Fill mode. - * @param {ThumbnailLoader.OptimizationMode=} opt_optimizationMode Optimization. - * @param {function(Image, Object)=} opt_onSuccess Success callback. - * @param {function()=} opt_onError Error callback. - * @param {function()=} opt_onGeneric Callback which is called when generic - * image is used. + * Height of test image. + * @private {number} */ -MockThumbnailLoader.prototype.load = function( - box, fillMode, opt_optimizationMode, opt_onSuccess, opt_onError, - opt_onGeneric) { - if (opt_onSuccess && MockThumbnailLoader.testImageDataUrl_) { - var image = new Image(); - image.onload = function() { - opt_onSuccess(image, null); - }; - image.src = MockThumbnailLoader.testImageDataUrl_; - } +MockThumbnailLoader.testImageHeight = 0; + +/** + * Error urls. + * @private {Array<string>} + */ +MockThumbnailLoader.errorUrls = []; + +/** + * Loads thumbnail as data url. + * + * @return {!Promise<{data:string, width:number, height:number}>} A promise + * which is resolved with data url. + */ +MockThumbnailLoader.prototype.loadAsDataUrl = function() { + if (MockThumbnailLoader.errorUrls.indexOf(this.entry_.toURL()) !== -1) + throw new Error('Failed to load thumbnail.'); + + return Promise.resolve({ + data: MockThumbnailLoader.testImageDataUrl, + width: MockThumbnailLoader.testImageWidth, + height: MockThumbnailLoader.testImageHeight + }); };
diff --git a/ui/file_manager/file_manager/foreground/js/preview_panel_model.js b/ui/file_manager/file_manager/foreground/js/preview_panel_model.js deleted file mode 100644 index c696ec6..0000000 --- a/ui/file_manager/file_manager/foreground/js/preview_panel_model.js +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @param {PreviewPanelModel.VisibilityType} initialVisibilityType - * @extends {cr.EventTarget} - * @constructor - * @struct - * @suppress {checkStructDictInheritance} - */ -function PreviewPanelModel(initialVisibilityType) { - cr.EventTarget.call(this); - - /** - * @type {!PreviewPanelModel.VisibilityType} - * @private - */ - this.visibilityType_ = initialVisibilityType; - - /** - * @type {!Array<!cr.ui.Command>} - * @const - * @private - */ - this.autoVisibilityCommands_ = Array.prototype.slice.call( - document.querySelectorAll('command.auto-visibility')); - cr.ui.decorate('command.auto-visibility', cr.ui.Command); - - /** - * FileSelection to be displayed. - * @type {FileSelection} - * @private - */ - this.selection_ = /** @type {FileSelection} */ - ({entries: [], computeBytes: function() {}, totalCount: 0}); - - /** - * Visibility type of the preview panel. - * @type {boolean} - * @private - */ - this.visible = false; - - for (var i = 0; i < this.autoVisibilityCommands_.length; i++) { - this.autoVisibilityCommands_[i].addEventListener( - 'hiddenChange', this.updateVisibility_.bind(this)); - } - this.updateVisibility_(); -} - -PreviewPanelModel.prototype.__proto__ = cr.EventTarget.prototype; - -/** - * Visibility type of the preview panel. - * @enum {string} - * @const - */ -PreviewPanelModel.VisibilityType = { - // Preview panel always shows. - ALWAYS_VISIBLE: 'alwaysVisible', - // Preview panel shows when the selection property are set. - AUTO: 'auto', - // Preview panel does not show. - ALWAYS_HIDDEN: 'alwaysHidden' -}; - -/** - * @enum {string} - */ -PreviewPanelModel.EventType = { - CHANGE: 'change' -}; - -PreviewPanelModel.prototype.setSelection = function(selection) { - this.selection_ = selection; - this.updateVisibility_(); -}; - -PreviewPanelModel.prototype.setVisibilityType = function(type) { - this.visibilityType_ = type; - this.updateVisibility_(); -}; - -PreviewPanelModel.prototype.updateVisibility_ = function() { - // Get the new visibility value. - var newVisible = true; - switch (this.visibilityType_) { - case PreviewPanelModel.VisibilityType.ALWAYS_VISIBLE: - newVisible = true; - break; - case PreviewPanelModel.VisibilityType.AUTO: - newVisible = - this.selection_.entries.length !== 0 || - this.autoVisibilityCommands_.some(function(command) { - return !command.hidden; - }); - break; - case PreviewPanelModel.VisibilityType.ALWAYS_HIDDEN: - newVisible = false; - break; - default: - assertNotReached(); - } - - // If the visibility has been already the new value, just return. - if (this.visible === newVisible) - return; - - // Set the new visibility value. - this.visible = newVisible; - cr.dispatchSimpleEvent(this, PreviewPanelModel.EventType.CHANGE); -};
diff --git a/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.html b/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.html deleted file mode 100644 index 8aee2eb..0000000 --- a/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.html +++ /dev/null
@@ -1,17 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. - --> -<script src="../../../../../ui/webui/resources/js/assert.js"></script> -<script src="../../../../../ui/webui/resources/js/cr.js"></script> -<script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script> -<script src="../../../../../ui/webui/resources/js/cr/ui.js"></script> -<script src="../../../../../ui/webui/resources/js/cr/ui/command.js"></script> -<script src="../../../../../ui/webui/resources/js/util.js"></script> -<script src="../../common/js/unittest_util.js"></script> -<script src="../../common/js/util.js"></script> -<script src="file_manager_commands.js"></script> -<script src="preview_panel_model.js"></script> - -<script src="preview_panel_model_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.js b/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.js deleted file mode 100644 index 6651414..0000000 --- a/ui/file_manager/file_manager/foreground/js/preview_panel_model_unittest.js +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -function testPreviewPanelModel(callback) { - document.querySelector('body').innerHTML = - '<command class="auto-visibility" hidden></command>'; - var command = document.querySelector('command.auto-visibility'); - var model = new PreviewPanelModel(PreviewPanelModel.VisibilityType.AUTO); - - var testStep = function(step, changed) { - var waitPromise = new Promise(function(fulfill) { - model.addEventListener( - PreviewPanelModel.EventType.CHANGE, fulfill.bind(null, true)); - // The handler of hiddenChange event in PreviewPanelModel dispatches - // PreviewPanelModel.EventType.CHANGE event synchronously. Thus if - // the below hiddenChange handler is called ahead of the above change - // handler, it means PreviewPanelModel.EventType.CHANGE was not - // dispatched. - command.addEventListener('hiddenChange', fulfill.bind(null, false)); - }); - - switch (step) { - case 0: - assertFalse(model.visible); - model.setSelection({entries: ["NotEmpty"]}); - break; - case 1: - assertTrue(changed); - assertTrue(model.visible); - model.setSelection({entries: []}); - break; - case 2: - assertTrue(changed); - assertFalse(model.visible); - command.setHidden(false); - break; - case 3: - assertTrue(changed); - assertTrue(model.visible); - command.setHidden(true); - break; - case 4: - assertTrue(changed); - assertFalse(model.visible); - model.setVisibilityType( - PreviewPanelModel.VisibilityType.ALWAYS_VISIBLE); - break; - case 5: - assertTrue(changed); - assertTrue(model.visible); - model.setVisibilityType( - PreviewPanelModel.VisibilityType.ALWAYS_HIDDEN); - model.setSelection({entries: ["NotEmpty"]}); - break; - case 6: - assertTrue(changed); - assertFalse(model.visible); - command.setHidden(false); - break; - case 7: - assertFalse(changed); - assertFalse(model.visible); - return; - } - - return waitPromise.then(function(newChanged) { - return testStep(step + 1, newChanged); - }); - }; - - reportPromise(testStep(0), callback); -}
diff --git a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js new file mode 100644 index 0000000..32476bd1 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
@@ -0,0 +1,75 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * This class controls wires toolbar UI and selection model. When selection + * status is changed, this class changes the view of toolbar. If cancel + * selection button is pressed, this class clears the selection. + * @param {!HTMLElement} cancelSelectionButton Button to cancel selection. + * @param {!HTMLElement} filesSelectedLabel Label to show how many files are + * selected. + * @param {!FileSelectionHandler} selectionHandler + * @param {!cr.ui.ListSelectionModel|!cr.ui.ListSingleSelectionModel} + * selectionModel + * @constructor + * @struct + */ +function ToolbarController(cancelSelectionButton, + filesSelectedLabel, + selectionHandler, + selectionModel) { + /** @private {!HTMLElement} */ + this.filesSelectedLabel_ = filesSelectedLabel; + + /** @private {!FileSelectionHandler} */ + this.selectionHandler_ = selectionHandler; + + /** @private {!cr.ui.ListSelectionModel|!cr.ui.ListSingleSelectionModel} */ + this.selectionModel_ = selectionModel; + + this.selectionHandler_.addEventListener( + FileSelectionHandler.EventType.CHANGE, + this.onSelectionChanged_.bind(this)); + + cancelSelectionButton.addEventListener( + 'click', this.onCancelSelectionButtonClicked_.bind(this)); +} + +/** + * Handles selection's change event to update the UI. + * @private + */ +ToolbarController.prototype.onSelectionChanged_ = function() { + var selection = this.selectionHandler_.selection; + + // Update the label "x files selected." on the header. + if (selection.totalCount === 0) { + this.filesSelectedLabel_.textContent = ''; + } else { + var text; + if (selection.directoryCount == 0) + text = strf('MANY_FILES_SELECTED', selection.fileCount); + else if (selection.fileCount == 0) + text = strf('MANY_DIRECTORIES_SELECTED', selection.directoryCount); + else + text = strf('MANY_ENTRIES_SELECTED', selection.totalCount); + this.filesSelectedLabel_.textContent = text; + } + + // Set .selecting class to containing element to change the view accordingly. + // TODO(fukino): This code changes the state of body, not the toolbar, to + // update the checkmark visibility on grid view. This should be moved to a + // controller which controls whole app window. Or, both toolbar and FileGrid + // should listen to the FileSelectionHandler. + this.filesSelectedLabel_.ownerDocument.body.classList.toggle( + 'selecting', selection.totalCount > 0); +} + +/** + * Handles click event for cancel button to change the selection state. + * @private + */ +ToolbarController.prototype.onCancelSelectionButtonClicked_ = function() { + this.selectionModel_.unselectAll(); +}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js index b87d69a..8a4b72a8f 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js +++ b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
@@ -58,23 +58,7 @@ }, set defaultItem(defaultItem) { this.defaultItem_ = defaultItem; - this.actionNode_.textContent = defaultItem.label || ''; - - if (defaultItem.iconType) { - this.actionNode_.classList.add('with-icon'); - this.actionNode_.style.backgroundImage = ''; - this.actionNode_.setAttribute('file-type-icon', defaultItem.iconType); - } else if (defaultItem.iconUrl) { - this.actionNode_.classList.add('with-icon'); - this.actionNode_.style.backgroundImage = - 'url(' + defaultItem.iconUrl + ')'; - this.actionNode_.removeAttribute('file-type-icon'); - } else { - this.actionNode_.classList.remove('with-icon'); - this.actionNode_.style.backgroundImage = ''; - this.actionNode_.removeAttribute('file-type-icon'); - } }, /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js b/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js index 570dc57..60f8cc08 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js +++ b/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js
@@ -88,7 +88,7 @@ * @return {string} Button label. */ CommandButton.prototype.getLabel = function() { - return this.textContent; + return this.command_ ? this.command_.label : ''; }; /** @@ -96,7 +96,16 @@ * @param {string} label New button label. */ CommandButton.prototype.setLabel = function(label) { - this.textContent = label; + // Swap the textContent with current label only when this button doesn't have + // any elements as children. + // + // TODO(fukino): If a user customize the button content, it becomes the + // user's responsibility to update the content on command label's change. + // Updating the label in customized button content should be done + // automatically by specifying an element which should be synced with the + // command label using class name or polymer's template binding. + if (!this.firstElementChild) + this.textContent = label; }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js index 34515b2..3b0dbd7 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js +++ b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
@@ -92,8 +92,7 @@ var hasFooterPanel = dialogType == DialogType.SELECT_SAVEAS_FILE; return new DialogFooter( dialogType, - queryRequiredElement( - document, hasFooterPanel ? '.dialog-footer' : '.preview-panel'), + queryRequiredElement(document, '.dialog-footer'), queryRequiredElement(document, '#filename-input-box input')); };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js index f2fafbf8..544ad80 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js +++ b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
@@ -133,7 +133,6 @@ 'mousemove', this.onMouseMoveBound_, true); this.target_.ownerDocument.addEventListener( 'mouseup', this.onMouseUpBound_, true); - cr.dispatchSimpleEvent(this.target_, 'dragselectionstart'); }; /** @@ -232,7 +231,6 @@ 'mousemove', this.onMouseMoveBound_, true); this.target_.ownerDocument.removeEventListener( 'mouseup', this.onMouseUpBound_, true); - cr.dispatchSimpleEvent(this.target_, 'dragselectionend'); this.target_.cachedBounds = null; this.target_ = null; // The target may select an item by reacting to the mouseup event.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js index fcad3f1..ad7aeabe 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -189,6 +189,10 @@ var checkmark = li.ownerDocument.createElement('div'); checkmark.className = 'checkmark'; + checkmark.addEventListener( + 'mouseup', util.repeatMouseEventWithCtrlKey.bind(null, li)); + checkmark.addEventListener( + 'mousedown', util.repeatMouseEventWithCtrlKey.bind(null, li)); frame.appendChild(checkmark); var bottom = li.ownerDocument.createElement('div');
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 4c62454..7b62e5b5 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -128,6 +128,22 @@ this.locationLine = null; /** + * The toolbar button to cancel selection. + * @type {!HTMLElement} + * @const + */ + this.cancelSelectionButton = + queryRequiredElement(this.element, '#cancel-selection-button'); + + /** + * The label showing how many files are selected. + * @type {!HTMLElement} + * @const + */ + this.filesSelectedLabel = + queryRequiredElement(this.element, '#files-selected-label'); + + /** * Search box. * @type {!SearchBox} * @const @@ -207,11 +223,6 @@ queryRequiredElement(this.fileContextMenu, '#default-action-separator'); /** - * @type {PreviewPanel} - */ - this.previewPanel = null; - - /** * The combo button to specify the task. * @type {!cr.ui.ComboButton} * @const @@ -259,28 +270,10 @@ * * @param {!FileTable} table * @param {!FileGrid} grid - * @param {!PreviewPanel} previewPanel * @param {!LocationLine} locationLine */ FileManagerUI.prototype.initAdditionalUI = function( - table, grid, previewPanel, locationLine) { - // Listen to drag events to hide preview panel while user is dragging files. - // Files.app prevents default actions in 'dragstart' in some situations, - // so we listen to 'drag' to know the list is actually being dragged. - var draggingBound = this.onDragging_.bind(this); - var dragEndBound = this.onDragEnd_.bind(this); - table.list.addEventListener('drag', draggingBound); - grid.addEventListener('drag', draggingBound); - table.list.addEventListener('dragend', dragEndBound); - grid.addEventListener('dragend', dragEndBound); - - // Listen to dragselection events to hide preview panel while the user is - // selecting files by drag operation. - table.list.addEventListener('dragselectionstart', draggingBound); - grid.addEventListener('dragselectionstart', draggingBound); - table.list.addEventListener('dragselectionend', dragEndBound); - grid.addEventListener('dragselectionend', dragEndBound); - + table, grid, locationLine) { // List container. this.listContainer = new ListContainer( queryRequiredElement(this.element, '#list-container'), table, grid); @@ -289,12 +282,6 @@ this.decorateSplitter_( queryRequiredElement(this.element, '#navigation-list-splitter')); - // Preview panel. - this.previewPanel = previewPanel; - this.previewPanel.addEventListener( - PreviewPanel.Event.VISIBILITY_CHANGE, - this.onPreviewPanelVisibilityChange_.bind(this)); - // Location line. this.locationLine = locationLine; @@ -401,44 +388,6 @@ }; /** - * Invoked while the drag is being performed on the list or the grid. - * Note: this method may be called multiple times before onDragEnd_(). - * @private - */ -FileManagerUI.prototype.onDragging_ = function() { - // On open file dialog, the preview panel is always shown. - if (DialogType.isOpenDialog(this.dialogType_)) - return; - this.previewPanel.visibilityType = - PreviewPanelModel.VisibilityType.ALWAYS_HIDDEN; -}; - -/** - * Invoked when the drag is ended on the list or the grid. - * @private - */ -FileManagerUI.prototype.onDragEnd_ = function() { - // On open file dialog, the preview panel is always shown. - if (DialogType.isOpenDialog(this.dialogType_)) - return; - this.previewPanel.visibilityType = - PreviewPanelModel.VisibilityType.AUTO; -}; - -/** - * Resize details and thumb views to fit the new window size. - * @private - */ -FileManagerUI.prototype.onPreviewPanelVisibilityChange_ = function() { - // This method may be called on initialization. Some object may not be - // initialized. - var panelHeight = this.previewPanel.visible ? - this.previewPanel.height : 0; - this.listContainer.table.setBottomMarginForPanel(panelHeight); - this.listContainer.grid.setBottomMarginForPanel(panelHeight); -}; - -/** * Re-focuses an element. * @private */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index dc2f5e00..a271a8c 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -475,8 +475,13 @@ (this.ownerDocument.createElement('div')); var icon = this.renderIconType_(entry, columnId, table); - icon.appendChild(this.renderThumbnail_(entry)); + if (FileType.isImage(entry) || FileType.isVideo(entry)) + icon.appendChild(this.renderThumbnail_(entry)); icon.appendChild(this.renderCheckmark_()); + icon.addEventListener( + 'mouseup', util.repeatMouseEventWithCtrlKey.bind(null, label)); + icon.addEventListener( + 'mousedown', util.repeatMouseEventWithCtrlKey.bind(null, label)); label.appendChild(icon); label.entry = entry;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js b/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js deleted file mode 100644 index 64afcaa..0000000 --- a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js +++ /dev/null
@@ -1,543 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * PreviewPanel UI class. - * @param {!Element} element DOM Element of preview panel. - * @param {PreviewPanelModel.VisibilityType} visibilityType Initial value of the - * visibility type. - * @param {MetadataCache} metadataCache Metadata cache. - * @param {VolumeManagerWrapper} volumeManager Volume manager. - * @param {!importer.HistoryLoader} historyLoader - * @constructor - * @extends {cr.EventTarget} - */ -var PreviewPanel = function(element, - visibilityType, - metadataCache, - volumeManager, - historyLoader) { - cr.EventTarget.call(this); - - /** - * The cached height of preview panel. - * @type {number} - * @private - */ - this.height_ = 0; - - /** - * Visibility type of the preview panel. - * @type {!PreviewPanelModel} - * @const - * @private - */ - this.model_ = new PreviewPanelModel(visibilityType); - - /** - * Dom element of the preview panel. - * @type {!Element} - * @const - * @private - */ - this.element_ = element; - - /** - * @type {!PreviewPanel.Thumbnails} - * @const - */ - this.thumbnails = new PreviewPanel.Thumbnails( - element.querySelector('.preview-thumbnails'), - metadataCache, - volumeManager, - historyLoader); - - /** - * @type {Element} - * @private - */ - this.summaryElement_ = element.querySelector('.preview-summary'); - - /** - * @type {PreviewPanel.CalculatingSizeLabel} - * @private - */ - this.calculatingSizeLabel_ = new PreviewPanel.CalculatingSizeLabel( - this.summaryElement_.querySelector('.calculating-size')); - - /** - * @type {Element} - * @private - */ - this.previewText_ = element.querySelector('.preview-text'); - - /** - * FileSelection to be displayed. - * @type {FileSelection} - * @private - */ - this.selection_ = /** @type {FileSelection} */ - ({entries: [], computeBytes: function() {}, totalCount: 0}); - - /** - * @type {!PromiseSlot} - * @const - * @private - */ - this.visibilityPromiseSlot_ = new PromiseSlot(function(visible) { - if (this.element_.getAttribute('visibility') === - PreviewPanel.Visibility_.HIDING) { - this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN); - } - cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); - }.bind(this), function(error) { console.error(error.stack || error); }); - - /** - * Sequence value that is incremented by every selection update and is used to - * check if the callback is up to date or not. - * @type {number} - * @private - */ - this.sequence_ = 0; - - /** - * @type {VolumeManagerWrapper} - * @private - */ - this.volumeManager_ = volumeManager; - - cr.EventTarget.call(this); - this.model_.addEventListener( - PreviewPanelModel.EventType.CHANGE, this.onModelChanged_.bind(this)); - this.onModelChanged_(); -}; - -/** - * Name of PreviewPanels's event. - * @enum {string} - * @const - */ -PreviewPanel.Event = { - // Event to be triggered at the end of visibility change. - VISIBILITY_CHANGE: 'visibilityChange' -}; - -/** - * @enum {string} - * @const - */ -PreviewPanel.Visibility_ = { - VISIBLE: 'visible', - HIDING: 'hiding', - HIDDEN: 'hidden' -}; - -PreviewPanel.prototype = { - __proto__: cr.EventTarget.prototype, - - /** - * Setter for the visibility type. - * @param {PreviewPanelModel.VisibilityType} visibilityType New value of - * visibility type. - */ - set visibilityType(visibilityType) { - this.model_.setVisibilityType(visibilityType); - }, - - get visible() { - return this.element_.getAttribute('visibility') == - PreviewPanel.Visibility_.VISIBLE; - }, - - /** - * Obtains the height of preview panel. - * @return {number} Height of preview panel. - */ - get height() { - this.height_ = this.height_ || this.element_.clientHeight; - return this.height_; - } -}; - -/** - * Apply the selection and update the view of the preview panel. - * @param {FileSelection} selection Selection to be applied. - */ -PreviewPanel.prototype.setSelection = function(selection) { - this.sequence_++; - this.selection_ = selection; - this.model_.setSelection(selection); - this.updatePreviewArea_(); -}; - -/** - * webkitTransitionEnd does not always fire (e.g. when animation is aborted or - * when no paint happens during the animation). This function sets up a timer - * and call the fulfill callback of the returned promise when the timer expires. - * @private - */ -PreviewPanel.prototype.waitForTransitionEnd_ = function() { - // Keep this sync with CSS. - var PREVIEW_PANEL_TRANSITION_MS = 220; - - return new Promise(function(fulfill) { - var timeoutId; - var onTransitionEnd = function(event) { - if (event && - (event.target !== this.element_ || - event.propertyName !== 'opacity')) { - return; - } - this.element_.removeEventListener('webkitTransitionEnd', onTransitionEnd); - clearTimeout(timeoutId); - fulfill(); - }.bind(this); - this.element_.addEventListener('webkitTransitionEnd', onTransitionEnd); - timeoutId = setTimeout(onTransitionEnd, PREVIEW_PANEL_TRANSITION_MS); - }.bind(this)); -}; - -/** - * Handles the model change event and update the visibility of the preview - * panel. - * @private - */ -PreviewPanel.prototype.onModelChanged_ = function() { - var promise; - if (this.model_.visible) { - this.element_.setAttribute( - 'visibility', PreviewPanel.Visibility_.VISIBLE); - this.updatePreviewArea_(); - promise = Promise.resolve(); - } else { - this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING); - promise = this.waitForTransitionEnd_(); - } - this.visibilityPromiseSlot_.setPromise(promise); -}; - -/** - * Update the text in the preview panel. - * @private - */ -PreviewPanel.prototype.updatePreviewArea_ = function() { - // If the preview panel is hiding, does not update the current view. - if (!this.visible) - return; - var selection = this.selection_; - - // If no item is selected, no information is displayed on the footer. - if (selection.totalCount === 0) { - this.thumbnails.hidden = true; - this.calculatingSizeLabel_.hidden = true; - this.previewText_.textContent = ''; - return; - } - - // If one item is selected, show thumbnail and entry name of the item. - if (selection.totalCount === 1) { - this.thumbnails.hidden = false; - this.thumbnails.selection = selection; - this.calculatingSizeLabel_.hidden = true; - this.previewText_.textContent = util.getEntryLabel( - this.volumeManager_.getLocationInfo(selection.entries[0]), - selection.entries[0]); - return; - } - - // Update thumbnails. - this.thumbnails.hidden = false; - this.thumbnails.selection = selection; - - // Obtains the preview text. - var text; - if (selection.directoryCount == 0) - text = strf('MANY_FILES_SELECTED', selection.fileCount); - else if (selection.fileCount == 0) - text = strf('MANY_DIRECTORIES_SELECTED', selection.directoryCount); - else - text = strf('MANY_ENTRIES_SELECTED', selection.totalCount); - - // Obtains the size of files. - this.calculatingSizeLabel_.hidden = selection.bytesKnown; - if (selection.bytesKnown && selection.showBytes) - text += ', ' + util.bytesToString(selection.bytes); - - // Set the preview text to the element. - this.previewText_.textContent = text; - - // Request the byte calculation if needed. - if (!selection.bytesKnown) { - this.selection_.computeBytes(function(sequence) { - // Selection has been already updated. - if (this.sequence_ != sequence) - return; - this.updatePreviewArea_(); - }.bind(this, this.sequence_)); - } -}; - -/** - * Animating label that is shown during the bytes of selection entries is being - * calculated. - * - * This label shows dots and varying the number of dots every - * CalculatingSizeLabel.PERIOD milliseconds. - * @param {Element} element DOM element of the label. - * @constructor - * @struct - */ -PreviewPanel.CalculatingSizeLabel = function(element) { - this.element_ = element; - this.count_ = 0; - this.intervalID_ = 0; -}; - -/** - * Time period in milliseconds. - * @const {number} - */ -PreviewPanel.CalculatingSizeLabel.PERIOD = 500; - -PreviewPanel.CalculatingSizeLabel.prototype = /** @struct */ { - /** - * Set visibility of the label. - * When it is displayed, the text is animated. - * @param {boolean} hidden Whether to hide the label or not. - */ - set hidden(hidden) { - this.element_.hidden = hidden; - if (!hidden) { - if (this.intervalID_ !== 0) - return; - this.count_ = 2; - this.intervalID_ = - setInterval(this.onStep_.bind(this), - PreviewPanel.CalculatingSizeLabel.PERIOD); - this.onStep_(); - } else { - if (this.intervalID_ === 0) - return; - clearInterval(this.intervalID_); - this.intervalID_ = 0; - } - } -}; - -/** - * Increments the counter and updates the number of dots. - * @private - */ -PreviewPanel.CalculatingSizeLabel.prototype.onStep_ = function() { - var text = str('CALCULATING_SIZE'); - for (var i = 0; i < ~~(this.count_ / 2) % 4; i++) { - text += '.'; - } - this.element_.textContent = text; - this.count_++; -}; - -/** - * Thumbnails on the preview panel. - * - * @param {Element} element DOM Element of thumbnail container. - * @param {MetadataCache} metadataCache MetadataCache. - * @param {VolumeManagerWrapper} volumeManager Volume manager instance. - * @param {!importer.HistoryLoader} historyLoader - * @constructor - */ -PreviewPanel.Thumbnails = function( - element, metadataCache, volumeManager, historyLoader) { - - /** @private {Element} */ - this.element_ = element; - - /** @private {MetadataCache} */ - this.metadataCache_ = metadataCache; - - /** @private {VolumeManagerWrapper} */ - this.volumeManager_ = volumeManager; - - /** @private {!importer.HistoryLoader} */ - this.historyLoader_ = historyLoader; - - /** @private {string} */ - this.lastEntriesHash_ = ''; - - Object.seal(this); -}; - -/** - * Maximum number of thumbnails. - * @const {number} - */ -PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT = 4; - -/** - * Edge length of the thumbnail square. - * @const {number} - */ -PreviewPanel.Thumbnails.THUMBNAIL_SIZE = 35; - -/** - * Longer edge length of zoomed thumbnail rectangle. - * @const {number} - */ -PreviewPanel.Thumbnails.ZOOMED_THUMBNAIL_SIZE = 200; - -PreviewPanel.Thumbnails.prototype = { - /** - * Sets entries to be displayed in the view. - * @param {FileSelection} value Entries. - */ - set selection(value) { - this.loadThumbnails_(value); - }, - - /** - * Set visibility of the thumbnails. - * @param {boolean} value Whether to hide the thumbnails or not. - */ - set hidden(value) { - this.element_.hidden = value; - } -}; - -/** - * Loads thumbnail images. - * @param {FileSelection} selection Selection containing entries that are - * sources of images. - * @private - */ -PreviewPanel.Thumbnails.prototype.loadThumbnails_ = function(selection) { - var entries = selection.entries; - var length = Math.min( - entries.length, PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT); - var clickHandler = selection.tasks && - selection.tasks.executeDefault.bind(selection.tasks); - var hash = selection.entries. - slice(0, PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT). - map(function(entry) { return entry.toURL(); }). - sort(). - join('\n'); - var entrySetChanged = hash !== this.lastEntriesHash_; - - this.lastEntriesHash_ = hash; - this.element_.classList.remove('has-zoom'); - - // Create new thumbnail image if the selection is changed. - var boxList; - if (entrySetChanged) { - this.element_.innerText = ''; - boxList = []; - for (var i = 0; i < length; i++) { - // Create a box. - var box = this.element_.ownerDocument.createElement('div'); - box.style.zIndex = PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT + 1 - i; - - // Register the click handler. - if (clickHandler) { - box.addEventListener('click', function(event) { - clickHandler(); - }); - } - - // Append - this.element_.appendChild(box); - boxList.push(box); - } - } else { - boxList = this.element_.querySelectorAll('.img-container'); - assert(length === boxList.length); - } - - // Update images in the boxes. - for (var i = 0; i < length; i++) { - // Load the image. - if (entries[i]) { - FileGrid.decorateThumbnailBox( - boxList[i], - entries[i], - this.metadataCache_, - this.volumeManager_, - this.historyLoader_, - ThumbnailLoader.FillMode.FILL, - FileGrid.ThumbnailQuality.LOW, - /* animation */ entrySetChanged, - i == 0 && length == 1 ? this.setZoomedImage_.bind(this) : undefined); - } - } -}; - -/** - * Create the zoomed version of image and set it to the DOM element to show the - * zoomed image. - * - * @param {HTMLImageElement} image Image to be source of the zoomed image. - * @param {util.Transform=} opt_transform Transformation to be applied to the - * image. - * @private - */ -PreviewPanel.Thumbnails.prototype.setZoomedImage_ = function(image, - opt_transform) { - if (!image) - return; - var width = image.width || 0; - var height = image.height || 0; - if (width == 0 || - height == 0 || - (width < PreviewPanel.Thumbnails.THUMBNAIL_SIZE * 2 && - height < PreviewPanel.Thumbnails.THUMBNAIL_SIZE * 2)) - return; - - var scale = Math.min(1, - PreviewPanel.Thumbnails.ZOOMED_THUMBNAIL_SIZE / - Math.max(width, height)); - var imageWidth = ~~(width * scale); - var imageHeight = ~~(height * scale); - var zoomedBox = - this.element_.querySelector('.popup') || - this.element_.ownerDocument.createElement('div'); - var zoomedImage = - this.element_.querySelector('.popup img') || - this.element_.ownerDocument.createElement('img'); - - if (scale < 0.3) { - // Scaling large images kills animation. Downscale it in advance. - // Canvas scales images with liner interpolation. Make a larger - // image (but small enough to not kill animation) and let IMAGE - // scale it smoothly. - var INTERMEDIATE_SCALE = 3; - var canvas = this.element_.ownerDocument.createElement('canvas'); - canvas.width = imageWidth * INTERMEDIATE_SCALE; - canvas.height = imageHeight * INTERMEDIATE_SCALE; - var ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0, canvas.width, canvas.height); - // Using bigger than default compression reduces image size by - // several times. Quality degradation compensated by greater resolution. - zoomedImage.src = canvas.toDataURL('image/jpeg', 0.6); - } else { - zoomedImage.src = image.src; - } - - var boxWidth = Math.max(PreviewPanel.Thumbnails.THUMBNAIL_SIZE, imageWidth); - var boxHeight = Math.max(PreviewPanel.Thumbnails.THUMBNAIL_SIZE, imageHeight); - if (opt_transform && opt_transform.rotate90 % 2 == 1) { - var t = boxWidth; - boxWidth = boxHeight; - boxHeight = t; - } - - if (opt_transform) - util.applyTransform(zoomedImage, opt_transform); - - zoomedBox.className = 'popup'; - zoomedBox.style.width = boxWidth + 'px'; - zoomedBox.style.height = boxHeight + 'px'; - zoomedBox.appendChild(zoomedImage); - - this.element_.appendChild(zoomedBox); - this.element_.classList.add('has-zoom'); - return; -};
diff --git a/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.html b/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.html deleted file mode 100644 index ea6a357..0000000 --- a/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright 2015 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. - --> -<script src="../../../../../../ui/webui/resources/js/assert.js"></script> -<script src="../../../../../../ui/webui/resources/js/cr.js"></script> -<script src="../../../../../../ui/webui/resources/js/cr/event_target.js"> -</script> -<script src="../../../common/js/mock_entry.js"></script> -<script src="preview_panel.js"></script> -<script src="preview_panel_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.js deleted file mode 100644 index f3e8a1c..0000000 --- a/ui/file_manager/file_manager/foreground/js/ui/preview_panel_unittest.js +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * Mock ThumbnailLoader.FillMode - */ -var ThumbnailLoader = { - FillMode: { - } -}; - -/** - * Mock FileGrid. - */ -var FileGrid = { - ThumbnailQuality: {}, - decorateThumbnailBox: function( - box, - entry, - metadataCache, - volumeManager, - historyLoader, - fillMode, - quality, - animation, - opt_callback) { - var imageContainer = document.createElement('div'); - imageContainer.classList.add('img-container'); - box.appendChild(imageContainer); - var image = new Image(); - image.width = 500; - image.height = 500; - if (opt_callback) - opt_callback(image); - } -}; - -function testPreviewThumbnail() { - var element = document.createElement('div'); - var mockFileSystem = new MockFileSystem('volumeId'); - var mockEntry = new MockFileEntry(mockFileSystem, '/test.jpg'); - var thumbnailUI = new PreviewPanel.Thumbnails(element); - thumbnailUI.selection = {entries: [mockEntry]}; - thumbnailUI.selection = {entries: [mockEntry]}; - // Multiple updates of selection do not create multiple popup images. - assertEquals(1, element.querySelectorAll('.popup').length); -}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/search_box.js b/ui/file_manager/file_manager/foreground/js/ui/search_box.js index f751b5b..eb3b6c7 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/search_box.js +++ b/ui/file_manager/file_manager/foreground/js/ui/search_box.js
@@ -181,6 +181,15 @@ }; /** + * Sets hidden attribute for components of search box. + * @param {boolean} hidden True when the search box need to be hidden. + */ +SearchBox.prototype.setHidden = function(hidden) { + this.element.hidden = hidden; + this.searchButton.hidden = hidden; +} + +/** * @private */ SearchBox.prototype.onInput_ = function() {
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index eb7a800..a00c2ec 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -28,6 +28,7 @@ <link rel="import" href="chrome://resources/polymer/core-icon/core-icon.html"> <link rel="import" href="chrome://resources/polymer/core-icons/core-icons.html"> + <link rel="import" href="chrome://resources/polymer/core-icons/social-icons.html"> <link rel="import" href="chrome://resources/polymer/core-input/core-input.html"> <link rel="import" href="chrome://resources/polymer/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/paper-input/paper-input-decorator.html"> @@ -102,6 +103,8 @@ <script src="foreground/js/ui/combobutton.js"></script> <script src="foreground/js/ui/commandbutton.js"></script> <script src="foreground/js/ui/file_manager_dialog_base.js"></script> + <script src="metadata/metadata_cache_set.js"></script> + <script src="metadata/new_metadata_provider.js"></script> <script src="foreground/js/app_installer.js"></script> <script src="foreground/js/app_state_controller.js"></script> @@ -120,17 +123,21 @@ <script src="foreground/js/gear_menu_controller.js"></script> <script src="foreground/js/import_controller.js"></script> <script src="foreground/js/launch_param.js"></script> + <script src="foreground/js/metadata/external_metadata_provider.js"></script> + <script src="foreground/js/metadata/file_system_metadata.js"></script> + <script src="foreground/js/metadata/file_system_metadata_provider.js"></script> <script src="foreground/js/metadata/metadata_cache.js"></script> + <script src="foreground/js/metadata/metadata_cache_item.js"></script> <script src="foreground/js/metadata_update_controller.js"></script> <script src="foreground/js/naming_controller.js"></script> <script src="foreground/js/navigation_list_model.js"></script> - <script src="foreground/js/preview_panel_model.js"></script> <script src="foreground/js/progress_center_item_group.js"></script> <script src="foreground/js/scan_controller.js"></script> <script src="foreground/js/search_controller.js"></script> <script src="foreground/js/share_client.js"></script> <script src="foreground/js/spinner_controller.js"></script> <script src="foreground/js/task_controller.js"></script> + <script src="foreground/js/toolbar_controller.js"></script> <script src="foreground/js/thumbnail_loader.js"></script> <script src="foreground/js/ui/banners.js"></script> <script src="foreground/js/ui/conflict_dialog.js"></script> @@ -146,7 +153,6 @@ <script src="foreground/js/ui/list_container.js"></script> <script src="foreground/js/ui/location_line.js"></script> <script src="foreground/js/ui/multi_profile_share_dialog.js"></script> - <script src="foreground/js/ui/preview_panel.js"></script> <script src="foreground/js/ui/progress_center_panel.js"></script> <script src="foreground/js/ui/scrollbar.js"></script> <script src="foreground/js/ui/search_box.js"></script> @@ -302,26 +308,54 @@ <div class="dialog-header"> <div id="location-breadcrumbs" class="breadcrumbs"></div> - <div class="spacer"></div> - <paper-button id="search-button" tabindex="7"> - <core-icon icon="search"></core-icon> + <paper-button id="cancel-selection-button"> + <core-icon icon="arrow-back" style="width:16px; height:16px"></core-icon> + <span i18n-content="CANCEL_SELECTION_BUTTON_LABEL"></span> </paper-button> + <div id="files-selected-label"></div> + <div class="spacer"></div> + <button id="tasks" class="combobutton" menu="#tasks-menu" + tabindex="7"> + <paper-ripple fit></paper-ripple> + </button> + <button id="search-button" class="icon-button" tabindex="8"> + <core-icon icon="search"></core-icon> + <paper-ripple fit></paper-ripple> + </button> <div id="search-box"> <paper-input-decorator i18n-values="label:SEARCH_TEXT_LABEL"> <input is="core-input" type="search" tabindex="-1" i18n-values="aria-label:SEARCH_TEXT_LABEL"> </paper-input-decorator> <button class="clear" tabindex="-1"></button> </div> - <button id="cloud-import-button" tabindex="10" + <button id="share-button" class="icon-button" command="#share" tabindex="9" + i18n-values="aria-label:SHARE_BUTTON_LABEL" + visibleif="full-page"> + <core-icon icon="social:person-add"></core-icon> + <paper-ripple fit></paper-ripple> + </button> + <button id="delete-button" class="icon-button" command="#delete" tabindex="10" + i18n-values="aria-label:DELETE_BUTTON_LABEL" + visibleif="full-page"> + <core-icon icon="delete"></core-icon> + <paper-ripple fit></paper-ripple> + </button> + <button id="cloud-import-button" class="icon-button" tabindex="11" i18n-values="aria-label:CLOUD_IMPORT_BUTTON_LABEL" style='display: none;'> <core-icon icon="cloud-queue"></core-icon> <paper-ripple fit></paper-ripple> </button> - <paper-button id="view-button" tabindex="8"> + <button id="cloud-import-details-button" class="icon-button" tabindex="12" + style='display: none;'> + <core-icon icon="arrow-drop-down"></core-icon> + <paper-ripple fit></paper-ripple> + </button> + <button id="view-button" class="icon-button" tabindex="13"> <core-icon icon="view-module"></core-icon> - </paper-button> - <button id="gear-button" tabindex="9" menu="#gear-menu" + <paper-ripple fit></paper-ripple> + </button> + <button id="gear-button" class="icon-button" tabindex="14" menu="#gear-menu" i18n-values="aria-label:GEAR_BUTTON_TOOLTIP" aria-activedescendant="gear-menu"> <core-icon icon="more-vert"></core-icon> @@ -329,6 +363,34 @@ </button> </div> + <div id="cloud-import-details" class="offscreen"> + <h1>Backup to Drive</h1> + + <div id='#open-destination'> + <!!-- + TODO(smckay): Setting volume-type-icon to "drive" breaks + functional tests because selection of the drive volume is + done using a query that matches this. Need to fix that. + See background/test_util.js:105 + --> + <core-icon class="icon volume-icon" volume-type-icon="na"> + </core-icon> My Photos + </div> + + <div class="detail"> + New photos: <span class="photo-count">0</span> + </div> + <div class="detail"> + Space required: <span class="space-required">0</span> + </div> + + <div class="media-strip"> + <tt>// TODO(smckay)</tt> + </div> + + <div class="import">Import!</div> + </div> + <div class="dialog-container"> <div class="dialog-navigation-list"> <div class="dialog-navigation-list-contents"> @@ -381,39 +443,6 @@ </div> </div> </div> - <div class="preview-panel progressable" visibility="hidden"> - <div class="left"> - <div> - <div class="preview-thumbnails"></div> - </div> - <div id="preview-lines"> - <div class="preview-summary"> - <span class="preview-text"></span> - <span class="calculating-size"></span> - </div> - </div> - </div> - <div class="right buttonbar" visibleif="full-page"> - <button id="share-button" command="#share" tabindex="11" - i18n-values="aria-label:SHARE_BUTTON_LABEL"></button> - <button id="tasks" class="combobutton" menu="#tasks-menu" - tabindex="12"></button> - <button id="delete-button" command="#delete" tabindex="13" - i18n-values="aria-label:DELETE_BUTTON_LABEL"></button> - </div> - <div class="preparing-label" i18n-content="PREPARING_LABEL"></div> - <div class="progress-bar"> - <div class="progress-track"></div> - </div> - <div class="right buttonbar" id="open-panel" - visibleif="open-file open-multi-file folder upload-folder"> - <select class="file-type" hidden></select> - <button i18n-content="NEW_FOLDER_BUTTON_LABEL" - visibleif="folder" command="#new-folder" tabindex="14"></button> - <button class="ok" disabled tabindex="15"></button> - <button class="cancel" i18n-content="CANCEL_LABEL" tabindex="16"></button> - </div> - </div> <div id="unmounted-panel"></div> <div id="format-panel"> <div class="error"></div> @@ -423,18 +452,18 @@ </div> </div> <div class="dialog-footer progressable" tabindex="-1" - visibleif="saveas-file"> + visibleif="saveas-file open-file open-multi-file folder upload-folder"> <div class="left"> <button id="new-folder-button" i18n-content="NEW_FOLDER_BUTTON_LABEL" visibleif="saveas-file folder" command="#new-folder" tabindex="4"> </button> - <div id="filename-input-box"> + <div id="filename-input-box" visibleif="saveas-file"> <div class="filename-label" i18n-content="FILENAME_LABEL"></div> <input class="entry-name" type="text" spellcheck="false" tabindex="1"> </div> <div class="preparing-label" i18n-content="PREPARING_LABEL"></div> - <div class="progress-bar"> + <div class="progress-bar" visibleif="saveas-file"> <div class="progress-track"></div> </div> </div>
diff --git a/ui/file_manager/gallery/css/gallery.css b/ui/file_manager/gallery/css/gallery.css index 02507a3..993dbeb 100644 --- a/ui/file_manager/gallery/css/gallery.css +++ b/ui/file_manager/gallery/css/gallery.css
@@ -190,7 +190,7 @@ /* Hide immediately when entering the slideshow. */ .gallery[tools][slideshow] > .toolbar { - transition-duration: 0; + transition-duration: 0ms; } .gallery[tools][locked] > .toolbar { @@ -294,7 +294,7 @@ background-color: transparent; overflow: hidden; position: absolute; - transition: visibility 0 linear 180ms, all 180ms linear; + transition: visibility 0ms linear 180ms, all 180ms linear; width: 260px; } @@ -440,13 +440,13 @@ .gallery .toolbar .ribbon { height: 100%; overflow: hidden; - transition: opacity 180ms linear, visibility 0 linear; + transition: opacity 180ms linear, visibility 0ms linear; z-index: 0; } .gallery[editing] .toolbar .ribbon { opacity: 0; - transition-delay: 0, 180ms; + transition-delay: 0ms, 180ms; visibility: hidden; } @@ -518,7 +518,7 @@ left: 280px; opacity: 0; right: 280px; - transition: opacity 180ms linear, visibility 0 linear 180ms; + transition: opacity 180ms linear, visibility 0ms linear 180ms; visibility: hidden; margin-bottom: -55px; }
diff --git a/ui/file_manager/integration_tests/file_manager/thumbnails.js b/ui/file_manager/integration_tests/file_manager/thumbnails.js deleted file mode 100644 index e0ba1c91..0000000 --- a/ui/file_manager/integration_tests/file_manager/thumbnails.js +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -/** - * Tests if a thumbnail for the selected item shows up in the preview panel. - * This thumbnail is fetched via the image loader. - */ -testcase.thumbnailsDownloads = function() { - var appId; - StepsRunner.run([ - function() { - setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); - }, - // Select the image. - function(inAppId) { - appId = inAppId; - remoteCall.callRemoteTestUtil('selectFile', - appId, - ['My Desktop Background.png'], - this.next); - }, - // Wait until the thumbnail shows up. - function(result) { - chrome.test.assertTrue(result); - remoteCall.waitForElement( - appId, '.preview-thumbnails .img-container img'). - then(this.next); - }, - // Verify the thumbnail. - function(element) { - chrome.test.assertTrue(element.attributes.src.indexOf( - 'data:image/jpeg') === 0); - checkIfNoErrorsOccured(this.next); - } - ]); -};
diff --git a/ui/file_manager/integration_tests/file_manager_test_manifest.json b/ui/file_manager/integration_tests/file_manager_test_manifest.json index 5457785..5523f85 100644 --- a/ui/file_manager/integration_tests/file_manager_test_manifest.json +++ b/ui/file_manager/integration_tests/file_manager_test_manifest.json
@@ -29,7 +29,6 @@ "file_manager/suggest_app_dialog.js", "file_manager/tab_index.js", "file_manager/tasks.js", - "file_manager/thumbnails.js", "file_manager/transfer.js", "file_manager/traverse.js" ]
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 0c3b42d..548fea2 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -105,6 +105,8 @@ "gfx_paths.h", "gpu_memory_buffer.cc", "gpu_memory_buffer.h", + "hud_font.cc", + "hud_font.h", "icon_util.cc", "icon_util.h", "image/canvas_image_source.cc", @@ -244,6 +246,8 @@ } else { # Mac doesn't use RenderTextHarfBuzz by default yet. sources += [ + "harfbuzz_font_skia.cc", + "harfbuzz_font_skia.h", "render_text.cc", "render_text.h", "render_text_harfbuzz.cc",
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp index 274c5dd..97e16de 100644 --- a/ui/gfx/gfx.gyp +++ b/ui/gfx/gfx.gyp
@@ -182,6 +182,10 @@ 'gfx_paths.h', 'gpu_memory_buffer.cc', 'gpu_memory_buffer.h', + 'harfbuzz_font_skia.cc', + 'harfbuzz_font_skia.h', + 'hud_font.cc', + 'hud_font.h', 'image/canvas_image_source.cc', 'image/canvas_image_source.h', 'image/image.cc', @@ -383,6 +387,8 @@ }], ['OS=="android" or OS=="ios"', { 'sources!': [ + 'harfbuzz_font_skia.cc', + 'harfbuzz_font_skia.h', 'render_text.cc', 'render_text.h', 'render_text_harfbuzz.cc',
diff --git a/ui/gfx/harfbuzz_font_skia.cc b/ui/gfx/harfbuzz_font_skia.cc new file mode 100644 index 0000000..2eaa0b0f --- /dev/null +++ b/ui/gfx/harfbuzz_font_skia.cc
@@ -0,0 +1,284 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/harfbuzz_font_skia.h" + +#include <limits> +#include <map> + +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "ui/gfx/render_text.h" + +namespace gfx { + +namespace { + +class HarfBuzzFace; + +// Maps from code points to glyph indices in a font. +typedef std::map<uint32_t, uint16_t> GlyphCache; + +typedef std::pair<HarfBuzzFace, GlyphCache> FaceCache; + +// Font data provider for HarfBuzz using Skia. Copied from Blink. +// TODO(ckocagil): Eliminate the duplication. http://crbug.com/368375 +struct FontData { + FontData(GlyphCache* glyph_cache) : glyph_cache_(glyph_cache) {} + + SkPaint paint_; + GlyphCache* glyph_cache_; +}; + +// Deletes the object at the given pointer after casting it to the given type. +template<typename Type> +void DeleteByType(void* data) { + Type* typed_data = reinterpret_cast<Type*>(data); + delete typed_data; +} + +template<typename Type> +void DeleteArrayByType(void* data) { + Type* typed_data = reinterpret_cast<Type*>(data); + delete[] typed_data; +} + +// Outputs the |width| and |extents| of the glyph with index |codepoint| in +// |paint|'s font. +void GetGlyphWidthAndExtents(SkPaint* paint, + hb_codepoint_t codepoint, + hb_position_t* width, + hb_glyph_extents_t* extents) { + DCHECK_LE(codepoint, std::numeric_limits<uint16_t>::max()); + paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); + + SkScalar sk_width; + SkRect sk_bounds; + uint16_t glyph = static_cast<uint16_t>(codepoint); + + paint->getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds); + if (width) + *width = SkScalarToFixed(sk_width); + if (extents) { + // Invert y-axis because Skia is y-grows-down but we set up HarfBuzz to be + // y-grows-up. + extents->x_bearing = SkScalarToFixed(sk_bounds.fLeft); + extents->y_bearing = SkScalarToFixed(-sk_bounds.fTop); + extents->width = SkScalarToFixed(sk_bounds.width()); + extents->height = SkScalarToFixed(-sk_bounds.height()); + } +} + +// Writes the |glyph| index for the given |unicode| code point. Returns whether +// the glyph exists, i.e. it is not a missing glyph. +hb_bool_t GetGlyph(hb_font_t* font, + void* data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t* glyph, + void* user_data) { + FontData* font_data = reinterpret_cast<FontData*>(data); + GlyphCache* cache = font_data->glyph_cache_; + + bool exists = cache->count(unicode) != 0; + if (!exists) { + SkPaint* paint = &font_data->paint_; + paint->setTextEncoding(SkPaint::kUTF32_TextEncoding); + paint->textToGlyphs(&unicode, sizeof(hb_codepoint_t), &(*cache)[unicode]); + } + *glyph = (*cache)[unicode]; + return !!*glyph; +} + +// Returns the horizontal advance value of the |glyph|. +hb_position_t GetGlyphHorizontalAdvance(hb_font_t* font, + void* data, + hb_codepoint_t glyph, + void* user_data) { + FontData* font_data = reinterpret_cast<FontData*>(data); + hb_position_t advance = 0; + + GetGlyphWidthAndExtents(&font_data->paint_, glyph, &advance, 0); + return advance; +} + +hb_bool_t GetGlyphHorizontalOrigin(hb_font_t* font, + void* data, + hb_codepoint_t glyph, + hb_position_t* x, + hb_position_t* y, + void* user_data) { + // Just return true, like the HarfBuzz-FreeType implementation. + return true; +} + +hb_position_t GetGlyphKerning(FontData* font_data, + hb_codepoint_t first_glyph, + hb_codepoint_t second_glyph) { + SkTypeface* typeface = font_data->paint_.getTypeface(); + const uint16_t glyphs[2] = { static_cast<uint16_t>(first_glyph), + static_cast<uint16_t>(second_glyph) }; + int32_t kerning_adjustments[1] = { 0 }; + + if (!typeface->getKerningPairAdjustments(glyphs, 2, kerning_adjustments)) + return 0; + + SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); + SkScalar size = font_data->paint_.getTextSize(); + return SkScalarToFixed( + SkScalarMulDiv(SkIntToScalar(kerning_adjustments[0]), size, upm)); +} + +hb_position_t GetGlyphHorizontalKerning(hb_font_t* font, + void* data, + hb_codepoint_t left_glyph, + hb_codepoint_t right_glyph, + void* user_data) { + FontData* font_data = reinterpret_cast<FontData*>(data); + if (font_data->paint_.isVerticalText()) { + // We don't support cross-stream kerning. + return 0; + } + + return GetGlyphKerning(font_data, left_glyph, right_glyph); +} + +hb_position_t GetGlyphVerticalKerning(hb_font_t* font, + void* data, + hb_codepoint_t top_glyph, + hb_codepoint_t bottom_glyph, + void* user_data) { + FontData* font_data = reinterpret_cast<FontData*>(data); + if (!font_data->paint_.isVerticalText()) { + // We don't support cross-stream kerning. + return 0; + } + + return GetGlyphKerning(font_data, top_glyph, bottom_glyph); +} + +// Writes the |extents| of |glyph|. +hb_bool_t GetGlyphExtents(hb_font_t* font, + void* data, + hb_codepoint_t glyph, + hb_glyph_extents_t* extents, + void* user_data) { + FontData* font_data = reinterpret_cast<FontData*>(data); + + GetGlyphWidthAndExtents(&font_data->paint_, glyph, 0, extents); + return true; +} + +class FontFuncs { + public: + FontFuncs() : font_funcs_(hb_font_funcs_create()) { + hb_font_funcs_set_glyph_func(font_funcs_, GetGlyph, 0, 0); + hb_font_funcs_set_glyph_h_advance_func( + font_funcs_, GetGlyphHorizontalAdvance, 0, 0); + hb_font_funcs_set_glyph_h_kerning_func( + font_funcs_, GetGlyphHorizontalKerning, 0, 0); + hb_font_funcs_set_glyph_h_origin_func( + font_funcs_, GetGlyphHorizontalOrigin, 0, 0); + hb_font_funcs_set_glyph_v_kerning_func( + font_funcs_, GetGlyphVerticalKerning, 0, 0); + hb_font_funcs_set_glyph_extents_func( + font_funcs_, GetGlyphExtents, 0, 0); + hb_font_funcs_make_immutable(font_funcs_); + } + + ~FontFuncs() { + hb_font_funcs_destroy(font_funcs_); + } + + hb_font_funcs_t* get() { return font_funcs_; } + + private: + hb_font_funcs_t* font_funcs_; + + DISALLOW_COPY_AND_ASSIGN(FontFuncs); +}; + +base::LazyInstance<FontFuncs>::Leaky g_font_funcs = LAZY_INSTANCE_INITIALIZER; + +// Returns the raw data of the font table |tag|. +hb_blob_t* GetFontTable(hb_face_t* face, hb_tag_t tag, void* user_data) { + SkTypeface* typeface = reinterpret_cast<SkTypeface*>(user_data); + + const size_t table_size = typeface->getTableSize(tag); + if (!table_size) + return 0; + + scoped_ptr<char[]> buffer(new char[table_size]); + if (!buffer) + return 0; + size_t actual_size = typeface->getTableData(tag, 0, table_size, buffer.get()); + if (table_size != actual_size) + return 0; + + char* buffer_raw = buffer.release(); + return hb_blob_create(buffer_raw, table_size, HB_MEMORY_MODE_WRITABLE, + buffer_raw, DeleteArrayByType<char>); +} + +void UnrefSkTypeface(void* data) { + SkTypeface* skia_face = reinterpret_cast<SkTypeface*>(data); + SkSafeUnref(skia_face); +} + +// Wrapper class for a HarfBuzz face created from a given Skia face. +class HarfBuzzFace { + public: + HarfBuzzFace() : face_(NULL) {} + + ~HarfBuzzFace() { + if (face_) + hb_face_destroy(face_); + } + + void Init(SkTypeface* skia_face) { + SkSafeRef(skia_face); + face_ = hb_face_create_for_tables(GetFontTable, skia_face, UnrefSkTypeface); + DCHECK(face_); + } + + hb_face_t* get() { + return face_; + } + + private: + hb_face_t* face_; +}; + +} // namespace + +// Creates a HarfBuzz font from the given Skia face and text size. +hb_font_t* CreateHarfBuzzFont(SkTypeface* skia_face, + SkScalar text_size, + const FontRenderParams& params, + bool background_is_transparent) { + // TODO(ckocagil): This shouldn't grow indefinitely. Maybe use base::MRUCache? + static std::map<SkFontID, FaceCache> face_caches; + + FaceCache* face_cache = &face_caches[skia_face->uniqueID()]; + if (face_cache->first.get() == NULL) + face_cache->first.Init(skia_face); + + hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get()); + const int scale = SkScalarToFixed(text_size); + hb_font_set_scale(harfbuzz_font, scale, scale); + FontData* hb_font_data = new FontData(&face_cache->second); + hb_font_data->paint_.setTypeface(skia_face); + hb_font_data->paint_.setTextSize(text_size); + // TODO(ckocagil): Do we need to update these params later? + internal::ApplyRenderParams(params, background_is_transparent, + &hb_font_data->paint_); + hb_font_set_funcs(harfbuzz_font, g_font_funcs.Get().get(), hb_font_data, + DeleteByType<FontData>); + hb_font_make_immutable(harfbuzz_font); + return harfbuzz_font; +} + +} // namespace gfx
diff --git a/ui/gfx/harfbuzz_font_skia.h b/ui/gfx/harfbuzz_font_skia.h new file mode 100644 index 0000000..8e2289c --- /dev/null +++ b/ui/gfx/harfbuzz_font_skia.h
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_HARFBUZZ_FONT_SKIA_H_ +#define UI_GFX_HARFBUZZ_FONT_SKIA_H_ + +#include "third_party/harfbuzz-ng/src/hb.h" +#include "third_party/skia/include/core/SkScalar.h" +#include "ui/gfx/font_render_params.h" + +class SkTypeface; + +namespace gfx { + +hb_font_t* CreateHarfBuzzFont(SkTypeface* skia_face, + SkScalar text_size, + const FontRenderParams& params, + bool background_is_transparent); + +} // namespace gfx + +#endif // UI_GFX_HARFBUZZ_FONT_SKIA_H_
diff --git a/ui/gfx/hud_font.cc b/ui/gfx/hud_font.cc new file mode 100644 index 0000000..b64845b --- /dev/null +++ b/ui/gfx/hud_font.cc
@@ -0,0 +1,30 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/hud_font.h" + +#include "base/lazy_instance.h" +#include "third_party/skia/include/core/SkTypeface.h" + +namespace ui { + +namespace { +base::LazyInstance<skia::RefPtr<SkTypeface>> g_hud_typeface; +} // namespace + +void SetHudTypeface(skia::RefPtr<SkTypeface> typeface) { + g_hud_typeface.Get() = typeface; +} + +skia::RefPtr<SkTypeface> GetHudTypeface() { + if (!g_hud_typeface.Get()) { + // This will be set pre-sandbox on Windows. On other platforms, just make + // something here. + SetHudTypeface(skia::AdoptRef( + SkTypeface::CreateFromName("monospace", SkTypeface::kBold))); + } + return g_hud_typeface.Get(); +} + +} // namespace ui
diff --git a/ui/gfx/hud_font.h b/ui/gfx/hud_font.h new file mode 100644 index 0000000..3d38d4b6 --- /dev/null +++ b/ui/gfx/hud_font.h
@@ -0,0 +1,20 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_HUD_FONT_H_ +#define UI_GFX_HUD_FONT_H_ + +#include "skia/ext/refptr.h" +#include "ui/gfx/gfx_export.h" + +class SkTypeface; + +namespace ui { + +GFX_EXPORT void SetHudTypeface(skia::RefPtr<SkTypeface> typeface); +GFX_EXPORT skia::RefPtr<SkTypeface> GetHudTypeface(); + +} // namespace ui + +#endif // UI_GFX_HUD_FONT_H_
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h index 415132f..b38c350 100644 --- a/ui/gfx/render_text.h +++ b/ui/gfx/render_text.h
@@ -580,6 +580,7 @@ FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_NormalWidth); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_SufficientWidth); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_Newline); + FRIEND_TEST_ALL_PREFIXES(RenderTextTest, NewlineWithoutMultilineFlag); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GlyphBounds); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_GlyphBounds); FRIEND_TEST_ALL_PREFIXES(RenderTextTest,
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc index 82580b3..387d3ea 100644 --- a/ui/gfx/render_text_harfbuzz.cc +++ b/ui/gfx/render_text_harfbuzz.cc
@@ -5,12 +5,10 @@ #include "ui/gfx/render_text_harfbuzz.h" #include <limits> -#include <map> #include "base/i18n/bidi_line_iterator.h" #include "base/i18n/break_iterator.h" #include "base/i18n/char_iterator.h" -#include "base/lazy_instance.h" #include "base/profiler/scoped_tracker.h" #include "third_party/harfbuzz-ng/src/hb.h" #include "third_party/icu/source/common/unicode/ubidi.h" @@ -19,6 +17,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/font_fallback.h" #include "ui/gfx/font_render_params.h" +#include "ui/gfx/harfbuzz_font_skia.h" #include "ui/gfx/utf16_indexing.h" #if defined(OS_WIN) @@ -40,270 +39,6 @@ // character to belong to more scripts. const size_t kMaxScripts = 5; -// Maps from code points to glyph indices in a font. -typedef std::map<uint32_t, uint16_t> GlyphCache; - -// Font data provider for HarfBuzz using Skia. Copied from Blink. -// TODO(ckocagil): Eliminate the duplication. http://crbug.com/368375 -struct FontData { - FontData(GlyphCache* glyph_cache) : glyph_cache_(glyph_cache) {} - - SkPaint paint_; - GlyphCache* glyph_cache_; -}; - -hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) { - return SkScalarToFixed(value); -} - -// Deletes the object at the given pointer after casting it to the given type. -template<typename Type> -void DeleteByType(void* data) { - Type* typed_data = reinterpret_cast<Type*>(data); - delete typed_data; -} - -template<typename Type> -void DeleteArrayByType(void* data) { - Type* typed_data = reinterpret_cast<Type*>(data); - delete[] typed_data; -} - -// Outputs the |width| and |extents| of the glyph with index |codepoint| in -// |paint|'s font. -void GetGlyphWidthAndExtents(SkPaint* paint, - hb_codepoint_t codepoint, - hb_position_t* width, - hb_glyph_extents_t* extents) { - DCHECK_LE(codepoint, std::numeric_limits<uint16>::max()); - paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); - - SkScalar sk_width; - SkRect sk_bounds; - uint16_t glyph = static_cast<uint16_t>(codepoint); - - paint->getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds); - if (width) - *width = SkiaScalarToHarfBuzzPosition(sk_width); - if (extents) { - // Invert y-axis because Skia is y-grows-down but we set up HarfBuzz to be - // y-grows-up. - extents->x_bearing = SkiaScalarToHarfBuzzPosition(sk_bounds.fLeft); - extents->y_bearing = SkiaScalarToHarfBuzzPosition(-sk_bounds.fTop); - extents->width = SkiaScalarToHarfBuzzPosition(sk_bounds.width()); - extents->height = SkiaScalarToHarfBuzzPosition(-sk_bounds.height()); - } -} - -// Writes the |glyph| index for the given |unicode| code point. Returns whether -// the glyph exists, i.e. it is not a missing glyph. -hb_bool_t GetGlyph(hb_font_t* font, - void* data, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t* glyph, - void* user_data) { - FontData* font_data = reinterpret_cast<FontData*>(data); - GlyphCache* cache = font_data->glyph_cache_; - - bool exists = cache->count(unicode) != 0; - if (!exists) { - SkPaint* paint = &font_data->paint_; - paint->setTextEncoding(SkPaint::kUTF32_TextEncoding); - paint->textToGlyphs(&unicode, sizeof(hb_codepoint_t), &(*cache)[unicode]); - } - *glyph = (*cache)[unicode]; - return !!*glyph; -} - -// Returns the horizontal advance value of the |glyph|. -hb_position_t GetGlyphHorizontalAdvance(hb_font_t* font, - void* data, - hb_codepoint_t glyph, - void* user_data) { - FontData* font_data = reinterpret_cast<FontData*>(data); - hb_position_t advance = 0; - - GetGlyphWidthAndExtents(&font_data->paint_, glyph, &advance, 0); - return advance; -} - -hb_bool_t GetGlyphHorizontalOrigin(hb_font_t* font, - void* data, - hb_codepoint_t glyph, - hb_position_t* x, - hb_position_t* y, - void* user_data) { - // Just return true, like the HarfBuzz-FreeType implementation. - return true; -} - -hb_position_t GetGlyphKerning(FontData* font_data, - hb_codepoint_t first_glyph, - hb_codepoint_t second_glyph) { - SkTypeface* typeface = font_data->paint_.getTypeface(); - const uint16_t glyphs[2] = { static_cast<uint16_t>(first_glyph), - static_cast<uint16_t>(second_glyph) }; - int32_t kerning_adjustments[1] = { 0 }; - - if (!typeface->getKerningPairAdjustments(glyphs, 2, kerning_adjustments)) - return 0; - - SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); - SkScalar size = font_data->paint_.getTextSize(); - return SkiaScalarToHarfBuzzPosition( - SkScalarMulDiv(SkIntToScalar(kerning_adjustments[0]), size, upm)); -} - -hb_position_t GetGlyphHorizontalKerning(hb_font_t* font, - void* data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void* user_data) { - FontData* font_data = reinterpret_cast<FontData*>(data); - if (font_data->paint_.isVerticalText()) { - // We don't support cross-stream kerning. - return 0; - } - - return GetGlyphKerning(font_data, left_glyph, right_glyph); -} - -hb_position_t GetGlyphVerticalKerning(hb_font_t* font, - void* data, - hb_codepoint_t top_glyph, - hb_codepoint_t bottom_glyph, - void* user_data) { - FontData* font_data = reinterpret_cast<FontData*>(data); - if (!font_data->paint_.isVerticalText()) { - // We don't support cross-stream kerning. - return 0; - } - - return GetGlyphKerning(font_data, top_glyph, bottom_glyph); -} - -// Writes the |extents| of |glyph|. -hb_bool_t GetGlyphExtents(hb_font_t* font, - void* data, - hb_codepoint_t glyph, - hb_glyph_extents_t* extents, - void* user_data) { - FontData* font_data = reinterpret_cast<FontData*>(data); - - GetGlyphWidthAndExtents(&font_data->paint_, glyph, 0, extents); - return true; -} - -class FontFuncs { - public: - FontFuncs() : font_funcs_(hb_font_funcs_create()) { - hb_font_funcs_set_glyph_func(font_funcs_, GetGlyph, 0, 0); - hb_font_funcs_set_glyph_h_advance_func( - font_funcs_, GetGlyphHorizontalAdvance, 0, 0); - hb_font_funcs_set_glyph_h_kerning_func( - font_funcs_, GetGlyphHorizontalKerning, 0, 0); - hb_font_funcs_set_glyph_h_origin_func( - font_funcs_, GetGlyphHorizontalOrigin, 0, 0); - hb_font_funcs_set_glyph_v_kerning_func( - font_funcs_, GetGlyphVerticalKerning, 0, 0); - hb_font_funcs_set_glyph_extents_func( - font_funcs_, GetGlyphExtents, 0, 0); - hb_font_funcs_make_immutable(font_funcs_); - } - - ~FontFuncs() { - hb_font_funcs_destroy(font_funcs_); - } - - hb_font_funcs_t* get() { return font_funcs_; } - - private: - hb_font_funcs_t* font_funcs_; - - DISALLOW_COPY_AND_ASSIGN(FontFuncs); -}; - -base::LazyInstance<FontFuncs>::Leaky g_font_funcs = LAZY_INSTANCE_INITIALIZER; - -// Returns the raw data of the font table |tag|. -hb_blob_t* GetFontTable(hb_face_t* face, hb_tag_t tag, void* user_data) { - SkTypeface* typeface = reinterpret_cast<SkTypeface*>(user_data); - - const size_t table_size = typeface->getTableSize(tag); - if (!table_size) - return 0; - - scoped_ptr<char[]> buffer(new char[table_size]); - if (!buffer) - return 0; - size_t actual_size = typeface->getTableData(tag, 0, table_size, buffer.get()); - if (table_size != actual_size) - return 0; - - char* buffer_raw = buffer.release(); - return hb_blob_create(buffer_raw, table_size, HB_MEMORY_MODE_WRITABLE, - buffer_raw, DeleteArrayByType<char>); -} - -void UnrefSkTypeface(void* data) { - SkTypeface* skia_face = reinterpret_cast<SkTypeface*>(data); - SkSafeUnref(skia_face); -} - -// Wrapper class for a HarfBuzz face created from a given Skia face. -class HarfBuzzFace { - public: - HarfBuzzFace() : face_(NULL) {} - - ~HarfBuzzFace() { - if (face_) - hb_face_destroy(face_); - } - - void Init(SkTypeface* skia_face) { - SkSafeRef(skia_face); - face_ = hb_face_create_for_tables(GetFontTable, skia_face, UnrefSkTypeface); - DCHECK(face_); - } - - hb_face_t* get() { - return face_; - } - - private: - hb_face_t* face_; -}; - -// Creates a HarfBuzz font from the given Skia face and text size. -hb_font_t* CreateHarfBuzzFont(SkTypeface* skia_face, - SkScalar text_size, - const FontRenderParams& params, - bool background_is_transparent) { - typedef std::pair<HarfBuzzFace, GlyphCache> FaceCache; - - // TODO(ckocagil): This shouldn't grow indefinitely. Maybe use base::MRUCache? - static std::map<SkFontID, FaceCache> face_caches; - - FaceCache* face_cache = &face_caches[skia_face->uniqueID()]; - if (face_cache->first.get() == NULL) - face_cache->first.Init(skia_face); - - hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get()); - const int scale = SkScalarToFixed(text_size); - hb_font_set_scale(harfbuzz_font, scale, scale); - FontData* hb_font_data = new FontData(&face_cache->second); - hb_font_data->paint_.setTypeface(skia_face); - hb_font_data->paint_.setTextSize(text_size); - // TODO(ckocagil): Do we need to update these params later? - internal::ApplyRenderParams(params, background_is_transparent, - &hb_font_data->paint_); - hb_font_set_funcs(harfbuzz_font, g_font_funcs.Get().get(), hb_font_data, - DeleteByType<FontData>); - hb_font_make_immutable(harfbuzz_font); - return harfbuzz_font; -} - // Returns true if characters of |block_code| may trigger font fallback. // Dingbats and emoticons can be rendered through the color emoji font file, // therefore it needs to be trigerred as fallbacks. See crbug.com/448909 @@ -328,6 +63,11 @@ const int32 run_length = static_cast<int32>(run_break - run_start); base::i18n::UTF16CharIterator iter(text.c_str() + run_start, run_length); const UChar32 first_char = iter.get(); + // The newline character should form a single run so that the line breaker + // can handle them easily. + if (first_char == '\n') + return run_start + 1; + const UBlockCode first_block = ublock_getCode(first_char); const bool first_block_unusual = IsUnusualBlockCode(first_block); const bool first_bracket = IsBracket(first_char); @@ -337,8 +77,10 @@ const UBlockCode current_block = ublock_getCode(current_char); const bool block_break = current_block != first_block && (first_block_unusual || IsUnusualBlockCode(current_block)); - if (block_break || first_bracket != IsBracket(current_char)) + if (block_break || current_char == '\n' || + first_bracket != IsBracket(current_char)) { return run_start + iter.array_pos(); + } } return run_break; } @@ -464,6 +206,252 @@ DCHECK(!glyphs->is_empty()); } +// Internal class to generate Line structures. If |multiline| is true, the text +// is broken into lines at |words| boundaries such that each line is no longer +// than |max_width|. If |multiline| is false, only outputs a single Line from +// the given runs. |min_baseline| and |min_height| are the minimum baseline and +// height for each line. +// TODO(ckocagil): Expose the interface of this class in the header and test +// this class directly. +class HarfBuzzLineBreaker { + public: + HarfBuzzLineBreaker(size_t max_width, + int min_baseline, + float min_height, + bool multiline, + const base::string16& text, + const BreakList<size_t>* words, + const ScopedVector<internal::TextRunHarfBuzz>& runs) + : max_width_((max_width == 0) ? std::numeric_limits<size_t>::max() + : max_width), + min_baseline_(min_baseline), + min_height_(min_height), + multiline_(multiline), + text_(text), + words_(words), + runs_(runs), + text_x_(0), + line_x_(0), + max_descent_(0), + max_ascent_(0) { + DCHECK_EQ(multiline_, (words_ != nullptr)); + AdvanceLine(); + } + + // Breaks the run at given |run_index| into Line structs. + void AddRun(int run_index) { + const internal::TextRunHarfBuzz* run = runs_[run_index]; + base::char16 first_char = text_[run->range.start()]; + if (multiline_ && first_char == '\n') + AdvanceLine(); + else if (multiline_ && (line_x_ + run->width) > max_width_) + BreakRun(run_index); + else + AddSegment(run_index, run->range, run->width); + } + + // Finishes line breaking and outputs the results. Can be called at most once. + void Finalize(std::vector<internal::Line>* lines, SizeF* size) { + DCHECK(!lines_.empty()); + // Add an empty line to finish the line size calculation and remove it. + AdvanceLine(); + lines_.pop_back(); + *size = total_size_; + lines->swap(lines_); + } + + private: + // A (line index, segment index) pair that specifies a segment in |lines_|. + typedef std::pair<size_t, size_t> SegmentHandle; + + internal::LineSegment* SegmentFromHandle(const SegmentHandle& handle) { + return &lines_[handle.first].segments[handle.second]; + } + + // Breaks a run into segments that fit in the last line in |lines_| and adds + // them. Adds a new Line to the back of |lines_| whenever a new segment can't + // be added without the Line's width exceeding |max_width_|. + void BreakRun(int run_index) { + const internal::TextRunHarfBuzz& run = *runs_[run_index]; + SkScalar width = 0; + size_t next_char = run.range.start(); + + // Break the run until it fits the current line. + while (next_char < run.range.end()) { + const size_t current_char = next_char; + const bool skip_line = + BreakRunAtWidth(run, current_char, &width, &next_char); + AddSegment(run_index, Range(current_char, next_char), + SkScalarToFloat(width)); + if (skip_line) + AdvanceLine(); + } + } + + // Starting from |start_char|, finds a suitable line break position at or + // before available width using word break. If the current position is at the + // beginning of a line, this function will not roll back to |start_char| and + // |*next_char| will be greater than |start_char| (to avoid constructing empty + // lines). + // Returns whether to skip the line before |*next_char|. + // TODO(ckocagil): Check clusters to avoid breaking ligatures and diacritics. + // TODO(ckocagil): We might have to reshape after breaking at ligatures. + // See whether resolving the TODO above resolves this too. + // TODO(ckocagil): Do not reserve width for whitespace at the end of lines. + bool BreakRunAtWidth(const internal::TextRunHarfBuzz& run, + size_t start_char, + SkScalar* width, + size_t* next_char) { + DCHECK(words_); + DCHECK(run.range.Contains(Range(start_char, start_char + 1))); + SkScalar available_width = SkIntToScalar(max_width_ - line_x_); + BreakList<size_t>::const_iterator word = words_->GetBreak(start_char); + BreakList<size_t>::const_iterator next_word = word + 1; + // Width from |std::max(word->first, start_char)| to the current character. + SkScalar word_width = 0; + *width = 0; + + for (size_t i = start_char; i < run.range.end(); ++i) { + // |word| holds the word boundary at or before |i|, and |next_word| holds + // the word boundary right after |i|. Advance both |word| and |next_word| + // when |i| reaches |next_word|. + if (next_word != words_->breaks().end() && i >= next_word->first) { + word = next_word++; + word_width = 0; + } + + Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); + SkScalar char_width = ((glyph_range.end() >= run.glyph_count) + ? SkFloatToScalar(run.width) + : run.positions[glyph_range.end()].x()) - + run.positions[glyph_range.start()].x(); + + *width += char_width; + word_width += char_width; + + if (*width > available_width) { + if (line_x_ != 0 || word_width < *width) { + // Roll back one word. + *width -= word_width; + *next_char = std::max(word->first, start_char); + } else if (char_width < *width) { + // Roll back one character. + *width -= char_width; + *next_char = i; + } else { + // Continue from the next character. + *next_char = i + 1; + } + return true; + } + } + + *next_char = run.range.end(); + return false; + } + + // RTL runs are broken in logical order but displayed in visual order. To find + // the text-space coordinate (where it would fall in a single-line text) + // |x_range| of RTL segments, segment widths are applied in reverse order. + // e.g. {[5, 10], [10, 40]} will become {[35, 40], [5, 35]}. + void UpdateRTLSegmentRanges() { + if (rtl_segments_.empty()) + return; + int x = SegmentFromHandle(rtl_segments_[0])->x_range.start(); + for (size_t i = rtl_segments_.size(); i > 0; --i) { + internal::LineSegment* segment = SegmentFromHandle(rtl_segments_[i - 1]); + const size_t segment_width = segment->x_range.length(); + segment->x_range = Range(x, x + segment_width); + x += segment_width; + } + rtl_segments_.clear(); + } + + // Finishes the size calculations of the last Line in |lines_|. Adds a new + // Line to the back of |lines_|. + void AdvanceLine() { + if (!lines_.empty()) { + internal::Line* line = &lines_.back(); + line->size.set_height(std::max(min_height_, max_descent_ + max_ascent_)); + line->baseline = + std::max(min_baseline_, SkScalarRoundToInt(max_ascent_)); + line->preceding_heights = std::ceil(total_size_.height()); + total_size_.set_height(total_size_.height() + line->size.height()); + total_size_.set_width(std::max(total_size_.width(), line->size.width())); + } + max_descent_ = 0; + max_ascent_ = 0; + line_x_ = 0; + lines_.push_back(internal::Line()); + } + + // Adds a new segment with the given properties to |lines_.back()|. + void AddSegment(int run_index, Range char_range, float width) { + if (char_range.is_empty()) { + DCHECK_EQ(0, width); + return; + } + const internal::TextRunHarfBuzz& run = *runs_[run_index]; + + internal::LineSegment segment; + segment.run = run_index; + segment.char_range = char_range; + segment.x_range = Range(text_x_, text_x_ + width); + + internal::Line* line = &lines_.back(); + line->segments.push_back(segment); + + SkPaint paint; + paint.setTypeface(run.skia_face.get()); + paint.setTextSize(SkIntToScalar(run.font_size)); + paint.setAntiAlias(run.render_params.antialiasing); + SkPaint::FontMetrics metrics; + paint.getFontMetrics(&metrics); + + line->size.set_width(line->size.width() + width); + max_descent_ = std::max(max_descent_, metrics.fDescent); + // fAscent is always negative. + max_ascent_ = std::max(max_ascent_, -metrics.fAscent); + + if (run.is_rtl) { + rtl_segments_.push_back( + SegmentHandle(lines_.size() - 1, line->segments.size() - 1)); + // If this is the last segment of an RTL run, reprocess the text-space x + // ranges of all segments from the run. + if (char_range.end() == run.range.end()) + UpdateRTLSegmentRanges(); + } + text_x_ += width; + line_x_ += width; + } + + const size_t max_width_; + const int min_baseline_; + const float min_height_; + const bool multiline_; + const base::string16& text_; + const BreakList<size_t>* const words_; + const ScopedVector<internal::TextRunHarfBuzz>& runs_; + + // Stores the resulting lines. + std::vector<internal::Line> lines_; + + // Text space and line space x coordinates of the next segment to be added. + int text_x_; + int line_x_; + + float max_descent_; + float max_ascent_; + + // Size of the multiline text, not including the currently processed line. + SizeF total_size_; + + // The current RTL run segments, to be applied by |UpdateRTLSegmentRanges()|. + std::vector<SegmentHandle> rtl_segments_; + + DISALLOW_COPY_AND_ASSIGN(HarfBuzzLineBreaker); +}; + } // namespace namespace internal { @@ -586,7 +574,8 @@ RenderTextHarfBuzz::RenderTextHarfBuzz() : RenderText(), - needs_layout_(false) { + needs_layout_(false), + glyph_width_for_test_(0u) { set_truncate_length(kMaxTextLength); } @@ -603,7 +592,7 @@ SizeF RenderTextHarfBuzz::GetStringSizeF() { EnsureLayout(); - return lines()[0].size; + return total_size_; } SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) { @@ -927,90 +916,86 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "431326 RenderTextHarfBuzz::EnsureLayout2")); - std::vector<internal::Line> lines; - lines.push_back(internal::Line()); - lines[0].baseline = font_list().GetBaseline(); - lines[0].size.set_height(font_list().GetHeight()); - - int current_x = 0; - SkPaint paint; + HarfBuzzLineBreaker line_breaker( + display_rect().width(), font_list().GetBaseline(), + font_list().GetHeight(), multiline(), GetLayoutText(), + multiline() ? &GetLineBreaks() : nullptr, runs_); // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. tracked_objects::ScopedTracker tracking_profile3( FROM_HERE_WITH_EXPLICIT_FUNCTION( "431326 RenderTextHarfBuzz::EnsureLayout3")); - for (size_t i = 0; i < runs_.size(); ++i) { - const internal::TextRunHarfBuzz& run = *runs_[visual_to_logical_[i]]; - internal::LineSegment segment; - segment.x_range = Range(current_x, current_x + run.width); - segment.char_range = run.range; - segment.run = i; - lines[0].segments.push_back(segment); - - paint.setTypeface(run.skia_face.get()); - paint.setTextSize(SkIntToScalar(run.font_size)); - paint.setAntiAlias(run.render_params.antialiasing); - SkPaint::FontMetrics metrics; - paint.getFontMetrics(&metrics); - - lines[0].size.set_width(lines[0].size.width() + run.width); - lines[0].size.set_height(std::max(lines[0].size.height(), - metrics.fDescent - metrics.fAscent)); - lines[0].baseline = std::max(lines[0].baseline, - SkScalarRoundToInt(-metrics.fAscent)); - } - + for (size_t i = 0; i < runs_.size(); ++i) + line_breaker.AddRun(visual_to_logical_[i]); + std::vector<internal::Line> lines; + line_breaker.Finalize(&lines, &total_size_); set_lines(&lines); } } void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { DCHECK(!needs_layout_); + if (lines().empty()) + return; + internal::SkiaTextRenderer renderer(canvas); ApplyFadeEffects(&renderer); ApplyTextShadows(&renderer); ApplyCompositionAndSelectionStyles(); - const Vector2d line_offset = GetLineOffset(0); - for (size_t i = 0; i < runs_.size(); ++i) { - const internal::TextRunHarfBuzz& run = *runs_[visual_to_logical_[i]]; - renderer.SetTypeface(run.skia_face.get()); - renderer.SetTextSize(SkIntToScalar(run.font_size)); - renderer.SetFontRenderParams(run.render_params, - background_is_transparent()); + for (size_t i = 0; i < lines().size(); ++i) { + const internal::Line& line = lines()[i]; + const Vector2d origin = GetLineOffset(i) + Vector2d(0, line.baseline); + SkScalar preceding_segment_widths = 0; + for (const internal::LineSegment& segment : line.segments) { + const internal::TextRunHarfBuzz& run = *runs_[segment.run]; + renderer.SetTypeface(run.skia_face.get()); + renderer.SetTextSize(SkIntToScalar(run.font_size)); + renderer.SetFontRenderParams(run.render_params, + background_is_transparent()); + Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); + scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); + SkScalar offset_x = + preceding_segment_widths - run.positions[glyphs_range.start()].x(); + for (size_t j = 0; j < glyphs_range.length(); ++j) { + positions[j] = run.positions[(glyphs_range.is_reversed()) ? + (glyphs_range.start() - j) : + (glyphs_range.start() + j)]; + positions[j].offset(SkIntToScalar(origin.x()) + offset_x, + SkIntToScalar(origin.y())); + } + for (BreakList<SkColor>::const_iterator it = + colors().GetBreak(segment.char_range.start()); + it != colors().breaks().end() && + it->first < segment.char_range.end(); + ++it) { + const Range intersection = + colors().GetRange(it).Intersect(segment.char_range); + const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); + // The range may be empty if a portion of a multi-character grapheme is + // selected, yielding two colors for a single glyph. For now, this just + // paints the glyph with a single style, but it should paint it twice, + // clipped according to selection bounds. See http://crbug.com/366786 + if (colored_glyphs.is_empty()) + continue; - Vector2d origin = line_offset + Vector2d(0, lines()[0].baseline); - scoped_ptr<SkPoint[]> positions(new SkPoint[run.glyph_count]); - for (size_t j = 0; j < run.glyph_count; ++j) { - positions[j] = run.positions[j]; - positions[j].offset(SkIntToScalar(origin.x()) + run.preceding_run_widths, - SkIntToScalar(origin.y())); - } - - for (BreakList<SkColor>::const_iterator it = - colors().GetBreak(run.range.start()); - it != colors().breaks().end() && it->first < run.range.end(); - ++it) { - const Range intersection = colors().GetRange(it).Intersect(run.range); - const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); - // The range may be empty if a portion of a multi-character grapheme is - // selected, yielding two colors for a single glyph. For now, this just - // paints the glyph with a single style, but it should paint it twice, - // clipped according to selection bounds. See http://crbug.com/366786 - if (colored_glyphs.is_empty()) - continue; - - renderer.SetForegroundColor(it->second); - renderer.DrawPosText(&positions[colored_glyphs.start()], - &run.glyphs[colored_glyphs.start()], - colored_glyphs.length()); - int start_x = SkScalarRoundToInt(positions[colored_glyphs.start()].x()); - int end_x = SkScalarRoundToInt((colored_glyphs.end() == run.glyph_count) ? - (run.width + run.preceding_run_widths + SkIntToScalar(origin.x())) : - positions[colored_glyphs.end()].x()); - renderer.DrawDecorations(start_x, origin.y(), end_x - start_x, - run.underline, run.strike, run.diagonal_strike); + renderer.SetForegroundColor(it->second); + renderer.DrawPosText( + &positions[colored_glyphs.start() - glyphs_range.start()], + &run.glyphs[colored_glyphs.start()], colored_glyphs.length()); + int start_x = SkScalarRoundToInt( + positions[colored_glyphs.start() - glyphs_range.start()].x()); + int end_x = SkScalarRoundToInt( + (colored_glyphs.end() == glyphs_range.end()) + ? (segment.x_range.length() + preceding_segment_widths + + SkIntToScalar(origin.x())) + : positions[colored_glyphs.end() - glyphs_range.start()].x()); + renderer.DrawDecorations(start_x, origin.y(), end_x - start_x, + run.underline, run.strike, + run.diagonal_strike); + } + preceding_segment_widths += SkIntToScalar(segment.x_range.length()); } } @@ -1328,7 +1313,9 @@ const SkScalar x_offset = SkFixedToScalar(hb_positions[i].x_offset); const SkScalar y_offset = SkFixedToScalar(hb_positions[i].y_offset); run->positions[i].set(run->width + x_offset, -y_offset); - run->width += SkFixedToScalar(hb_positions[i].x_advance); + run->width += (glyph_width_for_test_ > 0) + ? SkIntToScalar(glyph_width_for_test_) + : SkFixedToScalar(hb_positions[i].x_advance); // Round run widths if subpixel positioning is off to match native behavior. if (!run->render_params.subpixel_positioning) run->width = std::floor(run->width + 0.5f);
diff --git a/ui/gfx/render_text_harfbuzz.h b/ui/gfx/render_text_harfbuzz.h index 7f3a1dc..d0e167ec 100644 --- a/ui/gfx/render_text_harfbuzz.h +++ b/ui/gfx/render_text_harfbuzz.h
@@ -113,6 +113,7 @@ private: friend class RenderTextTest; + FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_NormalWidth); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_RunDirection); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_BreakRunsByEmoji); @@ -121,6 +122,13 @@ FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_NonExistentFont); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_UniscribeFallback); + // Specify the width of a glyph for test. The width of glyphs is very + // platform-dependent and environment-dependent. Otherwise multiline test + // will become really flaky. + void set_glyph_width_for_test(uint8 test_width) { + glyph_width_for_test_ = test_width; + } + // Return the run index that contains the argument; or the length of the // |runs_| vector if argument exceeds the text length or width. size_t GetRunContainingCaret(const SelectionModel& caret) const; @@ -168,6 +176,12 @@ // be NULL in case of an error. scoped_ptr<base::i18n::BreakIterator> grapheme_iterator_; + // The total size of the layouted text. + SizeF total_size_; + + // Fixed width of glyphs. This should only be set in test environments. + uint8 glyph_width_for_test_; + DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzz); };
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index f947d75..0a9f99d9 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -80,6 +80,16 @@ } #endif // !defined(OS_MACOSX) +// Test utility for Multiline_Newline test case. Empty |expected_range| means +// the blank line which has no segments. Otherwise |segments| should contain +// exactly one line segment whose range equals to |expected_range|. +void VerifyLineSegments(const Range& expected_range, + const std::vector<internal::LineSegment>& segments) { + EXPECT_EQ(expected_range.is_empty() ? 0ul : 1ul, segments.size()); + if (!expected_range.is_empty()) + EXPECT_EQ(expected_range, segments[0].char_range); +} + } // namespace class RenderTextTest : public testing::Test { @@ -1863,121 +1873,129 @@ } } -// TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline. // Ensure strings wrap onto multiple lines for a small available width. -TEST_F(RenderTextTest, DISABLED_Multiline_MinWidth) { +TEST_F(RenderTextTest, Multiline_MinWidth) { const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl }; - scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); - render_text->SetDisplayRect(Rect(1, 1000)); - render_text->SetMultiline(true); + RenderTextHarfBuzz render_text; + render_text.SetDisplayRect(Rect(1, 1000)); + render_text.SetMultiline(true); Canvas canvas; for (size_t i = 0; i < arraysize(kTestStrings); ++i) { SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); - render_text->SetText(WideToUTF16(kTestStrings[i])); - render_text->Draw(&canvas); - EXPECT_GT(render_text->lines_.size(), 1U); + render_text.SetText(WideToUTF16(kTestStrings[i])); + render_text.Draw(&canvas); + EXPECT_GT(render_text.lines_.size(), 1U); } } -// TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline. // Ensure strings wrap onto multiple lines for a normal available width. -TEST_F(RenderTextTest, DISABLED_Multiline_NormalWidth) { +TEST_F(RenderTextTest, Multiline_NormalWidth) { const struct { const wchar_t* const text; const Range first_line_char_range; const Range second_line_char_range; } kTestStrings[] = { { L"abc defg hijkl", Range(0, 9), Range(9, 14) }, - { L"qwertyzxcvbn", Range(0, 8), Range(8, 12) }, - { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9\x05DD", - Range(4, 10), Range(0, 4) } + { L"qwertyzxcvbn", Range(0, 10), Range(10, 12) }, + { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9" + L"\x05DA\x05DB\x05DD", Range(4, 12), Range(0, 4) } }; - scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); - render_text->SetDisplayRect(Rect(50, 1000)); - render_text->SetMultiline(true); + RenderTextHarfBuzz render_text; + // Specify the fixed width for characters to suppress the possible variations + // of linebreak results. + render_text.set_glyph_width_for_test(5); + render_text.SetDisplayRect(Rect(50, 1000)); + render_text.SetMultiline(true); Canvas canvas; for (size_t i = 0; i < arraysize(kTestStrings); ++i) { SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); - render_text->SetText(WideToUTF16(kTestStrings[i].text)); - render_text->Draw(&canvas); - ASSERT_EQ(2U, render_text->lines_.size()); - ASSERT_EQ(1U, render_text->lines_[0].segments.size()); + render_text.SetText(WideToUTF16(kTestStrings[i].text)); + render_text.Draw(&canvas); + ASSERT_EQ(2U, render_text.lines_.size()); + ASSERT_EQ(1U, render_text.lines_[0].segments.size()); EXPECT_EQ(kTestStrings[i].first_line_char_range, - render_text->lines_[0].segments[0].char_range); - ASSERT_EQ(1U, render_text->lines_[1].segments.size()); + render_text.lines_[0].segments[0].char_range); + ASSERT_EQ(1U, render_text.lines_[1].segments.size()); EXPECT_EQ(kTestStrings[i].second_line_char_range, - render_text->lines_[1].segments[0].char_range); + render_text.lines_[1].segments[0].char_range); } } -// TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline. // Ensure strings don't wrap onto multiple lines for a sufficient available // width. -TEST_F(RenderTextTest, DISABLED_Multiline_SufficientWidth) { +TEST_F(RenderTextTest, Multiline_SufficientWidth) { const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", L"\x62E\x628\x632", L"\x62E \x628 \x632" }; - scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); - render_text->SetDisplayRect(Rect(30, 1000)); - render_text->SetMultiline(true); + RenderTextHarfBuzz render_text; + render_text.SetDisplayRect(Rect(1000, 1000)); + render_text.SetMultiline(true); Canvas canvas; for (size_t i = 0; i < arraysize(kTestStrings); ++i) { SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); - render_text->SetText(WideToUTF16(kTestStrings[i])); - render_text->Draw(&canvas); - EXPECT_EQ(1U, render_text->lines_.size()); + render_text.SetText(WideToUTF16(kTestStrings[i])); + render_text.Draw(&canvas); + EXPECT_EQ(1U, render_text.lines_.size()); } } -// TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline. -TEST_F(RenderTextTest, DISABLED_Multiline_Newline) { +TEST_F(RenderTextTest, Multiline_Newline) { const struct { const wchar_t* const text; + const size_t lines_count; // Ranges of the characters on each line preceding the newline. - const Range first_line_char_range; - const Range second_line_char_range; + const Range line_char_ranges[3]; } kTestStrings[] = { - { L"abc\ndef", Range(0, 3), Range(4, 7) }, - { L"a \n b ", Range(0, 2), Range(3, 6) }, - { L"\n" , Range::InvalidRange(), Range::InvalidRange() } + {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } }, + {L"a \n b ", 2ul, { Range(0, 2), Range(3, 6), Range::InvalidRange() } }, + {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } }, + {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } }, + {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } }, + {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } }, }; - scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); - render_text->SetDisplayRect(Rect(200, 1000)); - render_text->SetMultiline(true); + RenderTextHarfBuzz render_text; + render_text.SetDisplayRect(Rect(200, 1000)); + render_text.SetMultiline(true); Canvas canvas; for (size_t i = 0; i < arraysize(kTestStrings); ++i) { SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); - render_text->SetText(WideToUTF16(kTestStrings[i].text)); - render_text->Draw(&canvas); + render_text.SetText(WideToUTF16(kTestStrings[i].text)); + render_text.Draw(&canvas); + EXPECT_EQ(kTestStrings[i].lines_count, render_text.lines_.size()); + if (kTestStrings[i].lines_count != render_text.lines_.size()) + continue; - ASSERT_EQ(2U, render_text->lines_.size()); + for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) { + SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j)); + VerifyLineSegments(kTestStrings[i].line_char_ranges[j], + render_text.lines_[j].segments); + } + } +} - const Range first_expected_range = kTestStrings[i].first_line_char_range; - ASSERT_EQ(first_expected_range.IsValid() ? 2U : 1U, - render_text->lines_[0].segments.size()); - if (first_expected_range.IsValid()) - EXPECT_EQ(first_expected_range, - render_text->lines_[0].segments[0].char_range); +TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) { + const wchar_t* kTestStrings[] = { + L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", + }; - const internal::LineSegment& newline_segment = - render_text->lines_[0].segments[first_expected_range.IsValid() ? 1 : 0]; - ASSERT_EQ(1U, newline_segment.char_range.length()); - EXPECT_EQ(L'\n', kTestStrings[i].text[newline_segment.char_range.start()]); + RenderTextHarfBuzz render_text; + render_text.SetDisplayRect(Rect(200, 1000)); + Canvas canvas; - const Range second_expected_range = kTestStrings[i].second_line_char_range; - ASSERT_EQ(second_expected_range.IsValid() ? 1U : 0U, - render_text->lines_[1].segments.size()); - if (second_expected_range.IsValid()) - EXPECT_EQ(second_expected_range, - render_text->lines_[1].segments[0].char_range); + for (size_t i = 0; i < arraysize(kTestStrings); ++i) { + SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); + render_text.SetText(WideToUTF16(kTestStrings[i])); + render_text.Draw(&canvas); + + EXPECT_EQ(1U, render_text.lines_.size()); } }
diff --git a/ui/gfx/screen_android.cc b/ui/gfx/screen_android.cc index 1f2f5f8..c286e603 100644 --- a/ui/gfx/screen_android.cc +++ b/ui/gfx/screen_android.cc
@@ -15,20 +15,19 @@ public: ScreenAndroid() {} - virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } + gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } - virtual gfx::NativeWindow GetWindowUnderCursor() override { + gfx::NativeWindow GetWindowUnderCursor() override { NOTIMPLEMENTED(); return NULL; } - virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) - override { + gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override { NOTIMPLEMENTED(); return NULL; } - virtual gfx::Display GetPrimaryDisplay() const override { + gfx::Display GetPrimaryDisplay() const override { gfx::DeviceDisplayInfo device_info; const float device_scale_factor = device_info.GetDIPScale(); // Note: GetPhysicalDisplayWidth/Height() does not subtract window @@ -51,32 +50,29 @@ return display; } - virtual gfx::Display GetDisplayNearestWindow( - gfx::NativeView view) const override { + gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override { return GetPrimaryDisplay(); } - virtual gfx::Display GetDisplayNearestPoint( - const gfx::Point& point) const override { + gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override { return GetPrimaryDisplay(); } - virtual int GetNumDisplays() const override { return 1; } + int GetNumDisplays() const override { return 1; } - virtual std::vector<gfx::Display> GetAllDisplays() const override { + std::vector<gfx::Display> GetAllDisplays() const override { return std::vector<gfx::Display>(1, GetPrimaryDisplay()); } - virtual gfx::Display GetDisplayMatching( - const gfx::Rect& match_rect) const override { + gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override { return GetPrimaryDisplay(); } - virtual void AddObserver(DisplayObserver* observer) override { + void AddObserver(DisplayObserver* observer) override { // no display change on Android. } - virtual void RemoveObserver(DisplayObserver* observer) override { + void RemoveObserver(DisplayObserver* observer) override { // no display change on Android. }
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index cd25b04..52daf1c 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -1360,7 +1360,7 @@ 'arguments': 'EGLint engine', }, { 'return_type': 'EGLint', 'versions': [{ 'name': 'eglWaitSyncKHR', - 'extensions': ['EGL_KHR_fence_sync', 'EGL_KHR_wait_sync'] }], + 'extensions': ['EGL_KHR_wait_sync'] }], 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' }, ]
diff --git a/ui/gl/gl_bindings_autogen_egl.cc b/ui/gl/gl_bindings_autogen_egl.cc index e0de7f2b2..003b5457 100644 --- a/ui/gl/gl_bindings_autogen_egl.cc +++ b/ui/gl/gl_bindings_autogen_egl.cc
@@ -209,7 +209,7 @@ } debug_fn.eglWaitSyncKHRFn = 0; - if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_wait_sync) { + if (ext.b_EGL_KHR_wait_sync) { fn.eglWaitSyncKHRFn = reinterpret_cast<eglWaitSyncKHRProc>( GetGLProcAddress("eglWaitSyncKHR")); DCHECK(fn.eglWaitSyncKHRFn);
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc index 4cfcf735..f89f1d2a 100644 --- a/ui/gl/gl_context.cc +++ b/ui/gl/gl_context.cc
@@ -38,20 +38,6 @@ canceled_ = true; } -GLContext::FlushEvent::FlushEvent() { -} - -GLContext::FlushEvent::~FlushEvent() { -} - -void GLContext::FlushEvent::Signal() { - flag_.Set(); -} - -bool GLContext::FlushEvent::IsSignaled() { - return flag_.IsSet(); -} - GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group), swap_interval_(1), @@ -69,13 +55,6 @@ } } -scoped_refptr<GLContext::FlushEvent> GLContext::SignalFlush() { - DCHECK(IsCurrent(NULL)); - scoped_refptr<FlushEvent> flush_event = new FlushEvent(); - flush_events_.push_back(flush_event); - return flush_event; -} - bool GLContext::GetTotalGpuMemory(size_t* bytes) { DCHECK(bytes); *bytes = 0; @@ -230,12 +209,6 @@ SetGLToRealGLApi(); } -void GLContext::OnFlush() { - for (size_t n = 0; n < flush_events_.size(); n++) - flush_events_[n]->Signal(); - flush_events_.clear(); -} - GLContextReal::GLContextReal(GLShareGroup* share_group) : GLContext(share_group) {}
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h index 62cabcd..5eac838 100644 --- a/ui/gl/gl_context.h +++ b/ui/gl/gl_context.h
@@ -34,25 +34,6 @@ virtual bool Initialize( GLSurface* compatible_surface, GpuPreference gpu_preference) = 0; - class FlushEvent : public base::RefCountedThreadSafe<FlushEvent> { - public: - bool IsSignaled(); - - private: - friend class base::RefCountedThreadSafe<FlushEvent>; - friend class GLContext; - FlushEvent(); - virtual ~FlushEvent(); - void Signal(); - - base::CancellationFlag flag_; - }; - - // Needs to be called with this context current. It will return a FlushEvent - // that is initially unsignaled, but will transition to signaled after the - // next glFlush() or glFinish() occurs in this context. - scoped_refptr<FlushEvent> SignalFlush(); - // Destroys the GL context. virtual void Destroy() = 0; @@ -143,9 +124,6 @@ // Returns the GL renderer string. The context must be current. virtual std::string GetGLRenderer(); - // Called when glFlush()/glFinish() is called with this context current. - void OnFlush(); - protected: virtual ~GLContext(); @@ -186,8 +164,6 @@ scoped_ptr<GLStateRestorer> state_restorer_; scoped_ptr<GLVersionInfo> version_info_; - std::vector<scoped_refptr<FlushEvent> > flush_events_; - int swap_interval_; bool force_swap_interval_zero_;
diff --git a/ui/gl/gl_context_android.cc b/ui/gl/gl_context_android.cc index 76b92382..9d3c86c 100644 --- a/ui/gl/gl_context_android.cc +++ b/ui/gl/gl_context_android.cc
@@ -26,18 +26,18 @@ GLNonOwnedContext(GLShareGroup* share_group); // Implement GLContext. - virtual bool Initialize(GLSurface* compatible_surface, - GpuPreference gpu_preference) override; - virtual void Destroy() override {} - virtual bool MakeCurrent(GLSurface* surface) override; - virtual void ReleaseCurrent(GLSurface* surface) override {} - virtual bool IsCurrent(GLSurface* surface) override { return true; } - virtual void* GetHandle() override { return NULL; } - virtual void OnSetSwapInterval(int interval) override {} - virtual std::string GetExtensions() override; + bool Initialize(GLSurface* compatible_surface, + GpuPreference gpu_preference) override; + void Destroy() override {} + bool MakeCurrent(GLSurface* surface) override; + void ReleaseCurrent(GLSurface* surface) override {} + bool IsCurrent(GLSurface* surface) override { return true; } + void* GetHandle() override { return NULL; } + void OnSetSwapInterval(int interval) override {} + std::string GetExtensions() override; protected: - virtual ~GLNonOwnedContext() {} + ~GLNonOwnedContext() override {} private: DISALLOW_COPY_AND_ASSIGN(GLNonOwnedContext);
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc index c254411..0fb3a74 100644 --- a/ui/gl/gl_fence.cc +++ b/ui/gl/gl_fence.cc
@@ -19,35 +19,6 @@ namespace gfx { -namespace { - -// static -GLFence* CreateFence(bool flush) { - DCHECK(GLContext::GetCurrent()) - << "Trying to create fence with no context"; - - scoped_ptr<GLFence> fence; - // Prefer ARB_sync which supports server-side wait. - if (g_driver_gl.ext.b_GL_ARB_sync || - GetGLVersionInfo()->is_es3) { - fence.reset(new GLFenceARB(flush)); -#if defined(OS_MACOSX) - } else if (g_driver_gl.ext.b_GL_APPLE_fence) { - fence.reset(new GLFenceAPPLE(flush)); -#else - } else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) { - fence.reset(new GLFenceEGL(flush)); -#endif - } else if (g_driver_gl.ext.b_GL_NV_fence) { - fence.reset(new GLFenceNV(flush)); - } - - DCHECK_EQ(!!fence.get(), GLFence::IsSupported()); - return fence.release(); -} - -} // namespace - GLFence::GLFence() { } @@ -66,11 +37,27 @@ } GLFence* GLFence::Create() { - return CreateFence(true); -} + DCHECK(GLContext::GetCurrent()) + << "Trying to create fence with no context"; -GLFence* GLFence::CreateWithoutFlush() { - return CreateFence(false); + scoped_ptr<GLFence> fence; + // Prefer ARB_sync which supports server-side wait. + if (g_driver_gl.ext.b_GL_ARB_sync || + GetGLVersionInfo()->is_es3) { + fence.reset(new GLFenceARB); +#if defined(OS_MACOSX) + } else if (g_driver_gl.ext.b_GL_APPLE_fence) { + fence.reset(new GLFenceAPPLE); +#else + } else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) { + fence.reset(new GLFenceEGL); +#endif + } else if (g_driver_gl.ext.b_GL_NV_fence) { + fence.reset(new GLFenceNV); + } + + DCHECK_EQ(!!fence.get(), GLFence::IsSupported()); + return fence.release(); } } // namespace gfx
diff --git a/ui/gl/gl_fence.h b/ui/gl/gl_fence.h index 5af253dd..76511f4 100644 --- a/ui/gl/gl_fence.h +++ b/ui/gl/gl_fence.h
@@ -18,12 +18,6 @@ static bool IsSupported(); static GLFence* Create(); - // Creates a fence that is not guaranteed to signal until the current context - // is flushed. It is illegal to call Client/ServerWait() on a fence without - // having explicitly called glFlush() or glFinish() in the originating - // context. - static GLFence* CreateWithoutFlush(); - virtual bool HasCompleted() = 0; virtual void ClientWait() = 0;
diff --git a/ui/gl/gl_fence_apple.cc b/ui/gl/gl_fence_apple.cc index 9df0cad7..3b5f697d 100644 --- a/ui/gl/gl_fence_apple.cc +++ b/ui/gl/gl_fence_apple.cc
@@ -5,19 +5,14 @@ #include "ui/gl/gl_fence_apple.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" namespace gfx { -GLFenceAPPLE::GLFenceAPPLE(bool flush) { +GLFenceAPPLE::GLFenceAPPLE() { glGenFencesAPPLE(1, &fence_); glSetFenceAPPLE(fence_); DCHECK(glIsFenceAPPLE(fence_)); - if (flush) { - glFlush(); - } else { - flush_event_ = GLContext::GetCurrent()->SignalFlush(); - } + glFlush(); } bool GLFenceAPPLE::HasCompleted() { @@ -27,11 +22,7 @@ void GLFenceAPPLE::ClientWait() { DCHECK(glIsFenceAPPLE(fence_)); - if (!flush_event_.get() || flush_event_->IsSignaled()) { - glFinishFenceAPPLE(fence_); - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; - } + glFinishFenceAPPLE(fence_); } void GLFenceAPPLE::ServerWait() {
diff --git a/ui/gl/gl_fence_apple.h b/ui/gl/gl_fence_apple.h index 6c8633d..5458e0d1 100644 --- a/ui/gl/gl_fence_apple.h +++ b/ui/gl/gl_fence_apple.h
@@ -7,14 +7,13 @@ #include "base/macros.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" namespace gfx { class GL_EXPORT GLFenceAPPLE : public GLFence { public: - GLFenceAPPLE(bool flush); + GLFenceAPPLE(); ~GLFenceAPPLE() override; // GLFence implementation: @@ -24,7 +23,6 @@ private: GLuint fence_; - scoped_refptr<GLContext::FlushEvent> flush_event_; DISALLOW_COPY_AND_ASSIGN(GLFenceAPPLE); };
diff --git a/ui/gl/gl_fence_arb.cc b/ui/gl/gl_fence_arb.cc index 05bda6b..5c6b3371 100644 --- a/ui/gl/gl_fence_arb.cc +++ b/ui/gl/gl_fence_arb.cc
@@ -6,7 +6,6 @@ #include "base/strings/stringprintf.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" namespace gfx { @@ -24,14 +23,10 @@ } // namespace -GLFenceARB::GLFenceARB(bool flush) { +GLFenceARB::GLFenceARB() { sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); DCHECK_EQ(GL_TRUE, glIsSync(sync_)); - if (flush) { - glFlush(); - } else { - flush_event_ = GLContext::GetCurrent()->SignalFlush(); - } + glFlush(); } bool GLFenceARB::HasCompleted() { @@ -52,25 +47,17 @@ void GLFenceARB::ClientWait() { DCHECK_EQ(GL_TRUE, glIsSync(sync_)); - if (!flush_event_.get() || flush_event_->IsSignaled()) { - GLenum result = - glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); - DCHECK_NE(static_cast<GLenum>(GL_TIMEOUT_EXPIRED), result); - if (result == GL_WAIT_FAILED) { - LOG(FATAL) << "Failed to wait for GLFence. error code:" << GetGLErrors(); - } - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; + GLenum result = + glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); + DCHECK_NE(static_cast<GLenum>(GL_TIMEOUT_EXPIRED), result); + if (result == GL_WAIT_FAILED) { + LOG(FATAL) << "Failed to wait for GLFence. error code:" << GetGLErrors(); } } void GLFenceARB::ServerWait() { DCHECK_EQ(GL_TRUE, glIsSync(sync_)); - if (!flush_event_.get() || flush_event_->IsSignaled()) { - glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED); - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; - } + glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED); } GLFenceARB::~GLFenceARB() {
diff --git a/ui/gl/gl_fence_arb.h b/ui/gl/gl_fence_arb.h index ef439487..3975efe 100644 --- a/ui/gl/gl_fence_arb.h +++ b/ui/gl/gl_fence_arb.h
@@ -7,14 +7,13 @@ #include "base/macros.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" namespace gfx { class GL_EXPORT GLFenceARB : public GLFence { public: - GLFenceARB(bool flush); + GLFenceARB(); ~GLFenceARB() override; // GLFence implementation: @@ -24,7 +23,6 @@ private: GLsync sync_; - scoped_refptr<GLContext::FlushEvent> flush_event_; DISALLOW_COPY_AND_ASSIGN(GLFenceARB); };
diff --git a/ui/gl/gl_fence_egl.cc b/ui/gl/gl_fence_egl.cc index c96d6d8..74f0a01 100644 --- a/ui/gl/gl_fence_egl.cc +++ b/ui/gl/gl_fence_egl.cc
@@ -6,19 +6,25 @@ #include "ui/gl/egl_util.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" namespace gfx { -GLFenceEGL::GLFenceEGL(bool flush) { +namespace { + +bool g_ignore_egl_sync_failures = false; + +} // namespace + +// static +void GLFenceEGL::SetIgnoreFailures() { + g_ignore_egl_sync_failures = true; +} + +GLFenceEGL::GLFenceEGL() { display_ = eglGetCurrentDisplay(); sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL); DCHECK(sync_ != EGL_NO_SYNC_KHR); - if (flush) { - glFlush(); - } else { - flush_event_ = GLContext::GetCurrent()->SignalFlush(); - } + glFlush(); } bool GLFenceEGL::HasCompleted() { @@ -35,17 +41,15 @@ } void GLFenceEGL::ClientWait() { - if (!flush_event_.get() || flush_event_->IsSignaled()) { - EGLint flags = 0; - EGLTimeKHR time = EGL_FOREVER_KHR; - EGLint result = eglClientWaitSyncKHR(display_, sync_, flags, time); - DCHECK_NE(EGL_TIMEOUT_EXPIRED_KHR, result); - if (result == EGL_FALSE) { - LOG(FATAL) << "Failed to wait for EGLSync. error:" - << ui::GetLastEGLErrorString(); - } - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; + EGLint flags = 0; + EGLTimeKHR time = EGL_FOREVER_KHR; + EGLint result = eglClientWaitSyncKHR(display_, sync_, flags, time); + DCHECK_IMPLIES(!g_ignore_egl_sync_failures, + EGL_TIMEOUT_EXPIRED_KHR == result); + if (result == EGL_FALSE) { + LOG(ERROR) << "Failed to wait for EGLSync. error:" + << ui::GetLastEGLErrorString(); + CHECK(g_ignore_egl_sync_failures); } } @@ -54,14 +58,11 @@ ClientWait(); return; } - if (!flush_event_.get() || flush_event_->IsSignaled()) { - EGLint flags = 0; - if (eglWaitSyncKHR(display_, sync_, flags) == EGL_FALSE) { - LOG(FATAL) << "Failed to wait for EGLSync. error:" - << ui::GetLastEGLErrorString(); - } - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; + EGLint flags = 0; + if (eglWaitSyncKHR(display_, sync_, flags) == EGL_FALSE) { + LOG(ERROR) << "Failed to wait for EGLSync. error:" + << ui::GetLastEGLErrorString(); + CHECK(g_ignore_egl_sync_failures); } }
diff --git a/ui/gl/gl_fence_egl.h b/ui/gl/gl_fence_egl.h index 75a0444..5b6006c 100644 --- a/ui/gl/gl_fence_egl.h +++ b/ui/gl/gl_fence_egl.h
@@ -7,14 +7,15 @@ #include "base/macros.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" namespace gfx { class GL_EXPORT GLFenceEGL : public GLFence { public: - GLFenceEGL(bool flush); + static void SetIgnoreFailures(); + + GLFenceEGL(); ~GLFenceEGL() override; // GLFence implementation: @@ -25,7 +26,6 @@ private: EGLSyncKHR sync_; EGLDisplay display_; - scoped_refptr<GLContext::FlushEvent> flush_event_; DISALLOW_COPY_AND_ASSIGN(GLFenceEGL); };
diff --git a/ui/gl/gl_fence_nv.cc b/ui/gl/gl_fence_nv.cc index 46dadd5..0e23b28 100644 --- a/ui/gl/gl_fence_nv.cc +++ b/ui/gl/gl_fence_nv.cc
@@ -5,11 +5,10 @@ #include "ui/gl/gl_fence_nv.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" namespace gfx { -GLFenceNV::GLFenceNV(bool flush) { +GLFenceNV::GLFenceNV() { // What if either of these GL calls fails? TestFenceNV will return true. // See spec: // http://www.opengl.org/registry/specs/NV/fence.txt @@ -23,11 +22,7 @@ glGenFencesNV(1, &fence_); glSetFenceNV(fence_, GL_ALL_COMPLETED_NV); DCHECK(glIsFenceNV(fence_)); - if (flush) { - glFlush(); - } else { - flush_event_ = GLContext::GetCurrent()->SignalFlush(); - } + glFlush(); } bool GLFenceNV::HasCompleted() { @@ -37,11 +32,7 @@ void GLFenceNV::ClientWait() { DCHECK(glIsFenceNV(fence_)); - if (!flush_event_.get() || flush_event_->IsSignaled()) { - glFinishFenceNV(fence_); - } else { - LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; - } + glFinishFenceNV(fence_); } void GLFenceNV::ServerWait() {
diff --git a/ui/gl/gl_fence_nv.h b/ui/gl/gl_fence_nv.h index 0bac11c..b1dc88f 100644 --- a/ui/gl/gl_fence_nv.h +++ b/ui/gl/gl_fence_nv.h
@@ -7,14 +7,13 @@ #include "base/macros.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" namespace gfx { class GL_EXPORT GLFenceNV : public GLFence { public: - GLFenceNV(bool flush); + GLFenceNV(); ~GLFenceNV() override; // GLFence implementation: @@ -24,7 +23,6 @@ private: GLuint fence_; - scoped_refptr<GLContext::FlushEvent> flush_event_; DISALLOW_COPY_AND_ASSIGN(GLFenceNV); };
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc index fada5e370..81a1b726 100644 --- a/ui/gl/gl_gl_api_implementation.cc +++ b/ui/gl/gl_gl_api_implementation.cc
@@ -395,11 +395,6 @@ driver_ = driver; } -void GLApiBase::SignalFlush() { - DCHECK(GLContext::GetCurrent()); - GLContext::GetCurrent()->OnFlush(); -} - RealGLApi::RealGLApi() { } @@ -412,12 +407,10 @@ void RealGLApi::glFlushFn() { GLApiBase::glFlushFn(); - GLApiBase::SignalFlush(); } void RealGLApi::glFinishFn() { GLApiBase::glFinishFn(); - GLApiBase::SignalFlush(); } TraceGLApi::~TraceGLApi() { @@ -525,12 +518,10 @@ void VirtualGLApi::glFlushFn() { GLApiBase::glFlushFn(); - GLApiBase::SignalFlush(); } void VirtualGLApi::glFinishFn() { GLApiBase::glFinishFn(); - GLApiBase::SignalFlush(); } ScopedSetGLToRealGLApi::ScopedSetGLToRealGLApi()
diff --git a/ui/gl/gl_gl_api_implementation.h b/ui/gl/gl_gl_api_implementation.h index 1b23097..d408600 100644 --- a/ui/gl/gl_gl_api_implementation.h +++ b/ui/gl/gl_gl_api_implementation.h
@@ -44,7 +44,6 @@ GLApiBase(); ~GLApiBase() override; void InitializeBase(DriverGL* driver); - void SignalFlush(); DriverGL* driver_; };
diff --git a/ui/gl/gl_image_surface_texture.h b/ui/gl/gl_image_surface_texture.h index eaf43633..d2ff5b70 100644 --- a/ui/gl/gl_image_surface_texture.h +++ b/ui/gl/gl_image_surface_texture.h
@@ -19,23 +19,23 @@ bool Initialize(SurfaceTexture* surface_texture); // Overridden from GLImage: - virtual void Destroy(bool have_context) override; - virtual gfx::Size GetSize() override; - virtual bool BindTexImage(unsigned target) override; - virtual void ReleaseTexImage(unsigned target) override {} - virtual bool CopyTexImage(unsigned target) override; - virtual void WillUseTexImage() override {} - virtual void DidUseTexImage() override {} - virtual void WillModifyTexImage() override {} - virtual void DidModifyTexImage() override {} - virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int z_order, - OverlayTransform transform, - const Rect& bounds_rect, - const RectF& crop_rect) override; + void Destroy(bool have_context) override; + gfx::Size GetSize() override; + bool BindTexImage(unsigned target) override; + void ReleaseTexImage(unsigned target) override {} + bool CopyTexImage(unsigned target) override; + void WillUseTexImage() override {} + void DidUseTexImage() override {} + void WillModifyTexImage() override {} + void DidModifyTexImage() override {} + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + OverlayTransform transform, + const Rect& bounds_rect, + const RectF& crop_rect) override; protected: - virtual ~GLImageSurfaceTexture(); + ~GLImageSurfaceTexture() override; private: scoped_refptr<SurfaceTexture> surface_texture_;
diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc index eecd064..cba706b 100644 --- a/ui/gl/gl_surface_ozone.cc +++ b/ui/gl/gl_surface_ozone.cc
@@ -105,7 +105,9 @@ AcceleratedWidget widget) : SurfacelessEGL(gfx::Size()), ozone_surface_(ozone_surface.Pass()), - widget_(widget) {} + widget_(widget), + has_implicit_external_sync_( + HasEGLExtension("EGL_ARM_implicit_external_sync")) {} bool Initialize() override { if (!SurfacelessEGL::Initialize()) @@ -122,8 +124,8 @@ return SurfacelessEGL::Resize(size); } bool SwapBuffers() override { - // TODO: this should be replaced by a fence when supported by the driver. - glFlush(); + if (!Flush()) + return false; return ozone_surface_->OnSwapBuffers(); } bool ScheduleOverlayPlane(int z_order, @@ -143,8 +145,8 @@ return true; } bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { - // TODO: this should be replaced by a fence when supported by the driver. - glFlush(); + if (!Flush()) + return false; return ozone_surface_->OnSwapBuffersAsync(callback); } bool PostSubBufferAsync(int x, @@ -160,11 +162,35 @@ Destroy(); // EGL surface must be destroyed before SurfaceOzone } + bool Flush() { + glFlush(); + // TODO: the following should be replaced by a per surface flush as it gets + // implemented in GL drivers. + if (has_implicit_external_sync_) { + const EGLint attrib_list[] = { + EGL_SYNC_CONDITION_KHR, + EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, + EGL_NONE}; + EGLSyncKHR fence = + eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); + if (fence) { + // TODO(dbehr): piman@ suggests we could improve here by moving + // following wait to right before drmModePageFlip crbug.com/456417. + eglClientWaitSyncKHR(GetDisplay(), fence, + EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); + eglDestroySyncKHR(GetDisplay(), fence); + } else { + return false; + } + } + return true; + } + // The native surface. Deleting this is allowed to free the EGLNativeWindow. scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; AcceleratedWidget widget_; scoped_ptr<VSyncProvider> vsync_provider_; - + bool has_implicit_external_sync_; DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); };
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index 30e02c87..2c06264 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn
@@ -49,6 +49,7 @@ "//third_party/mojo/src/mojo/public/cpp/system", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events:dom4_keycode_converter", @@ -131,6 +132,8 @@ "//skia", "//testing/gtest", "//ui/aura:test_support", + "//ui/base", + "//ui/base/ime", "//ui/base:test_support", "//ui/compositor:test_support", "//ui/events:test_support",
diff --git a/ui/keyboard/keyboard.gyp b/ui/keyboard/keyboard.gyp index 681d007..7a7ae452 100644 --- a/ui/keyboard/keyboard.gyp +++ b/ui/keyboard/keyboard.gyp
@@ -69,6 +69,7 @@ '../../third_party/mojo/mojo_public.gyp:mojo_js_bindings', '../../url/url.gyp:url_lib', '../aura/aura.gyp:aura', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../events/events.gyp:dom4_keycode_converter', @@ -118,6 +119,7 @@ '../../url/url.gyp:url_lib', '../aura/aura.gyp:aura', '../aura/aura.gyp:aura_test_support', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../compositor/compositor.gyp:compositor_test_support',
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc index 6f43e054..f88fc19 100644 --- a/ui/message_center/views/message_view.cc +++ b/ui/message_center/views/message_view.cc
@@ -11,6 +11,7 @@ #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" +#include "ui/gfx/shadow_value.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_style.h" #include "ui/message_center/views/padded_button.h" @@ -126,11 +127,9 @@ } void MessageView::CreateShadowBorder() { - SetBorder(scoped_ptr<views::Border>( - new views::ShadowBorder(kShadowBlur, - message_center::kShadowColor, - kShadowOffset, // Vertical offset. - 0))); // Horizontal offset. + SetBorder(scoped_ptr<views::Border>(new views::ShadowBorder( + gfx::ShadowValue(gfx::Point(0, kShadowOffset), kShadowBlur, + message_center::kShadowColor)))); } bool MessageView::IsCloseButtonFocused() {
diff --git a/ui/native_theme/native_theme_android.h b/ui/native_theme/native_theme_android.h index 378a233..657d82d 100644 --- a/ui/native_theme/native_theme_android.h +++ b/ui/native_theme/native_theme_android.h
@@ -14,11 +14,11 @@ public: static NativeThemeAndroid* instance(); - virtual SkColor GetSystemColor(ColorId color_id) const override; + SkColor GetSystemColor(ColorId color_id) const override; private: NativeThemeAndroid(); - virtual ~NativeThemeAndroid(); + ~NativeThemeAndroid() override; DISALLOW_COPY_AND_ASSIGN(NativeThemeAndroid); };
diff --git a/ui/ozone/platform/dri/dri_window.cc b/ui/ozone/platform/dri/dri_window.cc index 1973890..e1e24ab 100644 --- a/ui/ozone/platform/dri/dri_window.cc +++ b/ui/ozone/platform/dri/dri_window.cc
@@ -178,6 +178,7 @@ void DriWindow::SendBoundsChange() { cursor_->PrepareForBoundsChange(widget_); sender_->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_, bounds_)); + cursor_->ConfineCursorToBounds(widget_, GetCursorConfinedBounds()); } } // namespace ui
diff --git a/ui/ozone/platform/dri/gbm_surfaceless.cc b/ui/ozone/platform/dri/gbm_surfaceless.cc index 25ce87e8..27dfff9 100644 --- a/ui/ozone/platform/dri/gbm_surfaceless.cc +++ b/ui/ozone/platform/dri/gbm_surfaceless.cc
@@ -23,8 +23,7 @@ } bool GbmSurfaceless::ResizeNativeWindow(const gfx::Size& viewport_size) { - NOTIMPLEMENTED(); - return false; + return true; } bool GbmSurfaceless::OnSwapBuffers() {
diff --git a/ui/ozone/platform/dri/native_display_delegate_dri.cc b/ui/ozone/platform/dri/native_display_delegate_dri.cc index d1b853b..fe567b7 100644 --- a/ui/ozone/platform/dri/native_display_delegate_dri.cc +++ b/ui/ozone/platform/dri/native_display_delegate_dri.cc
@@ -200,6 +200,11 @@ return false; } } else { + if (dri_output.dpms_property()) { + dri_->SetProperty(dri_output.connector(), + dri_output.dpms_property()->prop_id, DRM_MODE_DPMS_OFF); + } + if (!screen_manager_->DisableDisplayController(dri_output.crtc())) { VLOG(1) << "Failed to disable crtc=" << dri_output.crtc(); return false;
diff --git a/ui/shell_dialogs/select_file_dialog_android.h b/ui/shell_dialogs/select_file_dialog_android.h index 90abdbb..9aee3fd3 100644 --- a/ui/shell_dialogs/select_file_dialog_android.h +++ b/ui/shell_dialogs/select_file_dialog_android.h
@@ -31,31 +31,30 @@ void OnFileNotSelected(JNIEnv* env, jobject java_object); // From SelectFileDialog - virtual bool IsRunning(gfx::NativeWindow) const override; - virtual void ListenerDestroyed() override; + bool IsRunning(gfx::NativeWindow) const override; + void ListenerDestroyed() override; // Called when it is time to display the file picker. // params is expected to be a vector<string16> with accept_types first and // the capture value as the last element of the vector. - virtual void SelectFileImpl( - SelectFileDialog::Type type, - const base::string16& title, - const base::FilePath& default_path, - const SelectFileDialog::FileTypeInfo* file_types, - int file_type_index, - const std::string& default_extension, - gfx::NativeWindow owning_window, - void* params) override; + void SelectFileImpl(SelectFileDialog::Type type, + const base::string16& title, + const base::FilePath& default_path, + const SelectFileDialog::FileTypeInfo* file_types, + int file_type_index, + const std::string& default_extension, + gfx::NativeWindow owning_window, + void* params) override; static bool RegisterSelectFileDialog(JNIEnv* env); protected: - virtual ~SelectFileDialogImpl(); + ~SelectFileDialogImpl() override; private: SelectFileDialogImpl(Listener* listener, SelectFilePolicy* policy); - virtual bool HasMultipleFileTypeChoicesImpl() override; + bool HasMultipleFileTypeChoicesImpl() override; base::android::ScopedJavaGlobalRef<jobject> java_object_;
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 7cf2f5e..fdfe02c 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -34,6 +34,7 @@ "//base", "//ui/accessibility:ax_gen", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events:events_base", @@ -129,6 +130,7 @@ "//testing/gtest", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/compositor:test_support", "//ui/events", @@ -174,6 +176,7 @@ "//ui/accessibility", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/base:test_support", "//ui/compositor:test_support", "//ui/events:test_support",
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc index 05f1868..ae2df206 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.cc +++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -76,11 +76,10 @@ delete obj; } -AXAuraObjCache::AXAuraObjCache() : current_id_(1), is_destroying_(false) { +AXAuraObjCache::AXAuraObjCache() : current_id_(1) { } AXAuraObjCache::~AXAuraObjCache() { - is_destroying_ = true; STLDeleteContainerPairSecondPointers(cache_.begin(), cache_.end()); cache_.clear(); }
diff --git a/ui/views/accessibility/ax_aura_obj_cache.h b/ui/views/accessibility/ax_aura_obj_cache.h index a8316b5..6e5d9e8 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.h +++ b/ui/views/accessibility/ax_aura_obj_cache.h
@@ -52,9 +52,6 @@ // Remove a cached entry based on an id. void Remove(int32 id); - // Indicates if this object's currently being destroyed. - bool is_destroying() { return is_destroying_; } - private: friend struct DefaultSingletonTraits<AXAuraObjCache>; @@ -78,9 +75,6 @@ std::map<int32, AXAuraObjWrapper*> cache_; int32 current_id_; - // True immediately when entering this object's destructor. - bool is_destroying_; - DISALLOW_COPY_AND_ASSIGN(AXAuraObjCache); };
diff --git a/ui/views/accessibility/ax_widget_obj_wrapper.cc b/ui/views/accessibility/ax_widget_obj_wrapper.cc index 44fcfa8..36a3143e 100644 --- a/ui/views/accessibility/ax_widget_obj_wrapper.cc +++ b/ui/views/accessibility/ax_widget_obj_wrapper.cc
@@ -17,10 +17,8 @@ } AXWidgetObjWrapper::~AXWidgetObjWrapper() { - if (!AXAuraObjCache::GetInstance()->is_destroying()) { - widget_->RemoveObserver(this); - widget_->RemoveRemovalsObserver(this); - } + widget_->RemoveObserver(this); + widget_->RemoveRemovalsObserver(this); widget_ = NULL; }
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm index 8aabac1..b5ddb05 100644 --- a/ui/views/cocoa/bridged_content_view.mm +++ b/ui/views/cocoa/bridged_content_view.mm
@@ -14,9 +14,12 @@ #include "ui/gfx/canvas_paint_mac.h" #include "ui/gfx/geometry/rect.h" #include "ui/strings/grit/ui_strings.h" +#include "ui/views/controls/menu/menu_controller.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" +using views::MenuController; + namespace { // Convert a |point| in |source_window|'s AppKit coordinate system (origin at @@ -79,13 +82,14 @@ if ((self = [super initWithFrame:initialFrame])) { hostedView_ = viewToHost; - trackingArea_.reset( - [[CrTrackingArea alloc] initWithRect:NSZeroRect - options:NSTrackingMouseMoved | - NSTrackingActiveAlways | - NSTrackingInVisibleRect - owner:self - userInfo:nil]); + // Apple's documentation says that NSTrackingActiveAlways is incompatible + // with NSTrackingCursorUpdate, so use NSTrackingActiveInActiveApp. + trackingArea_.reset([[CrTrackingArea alloc] + initWithRect:NSZeroRect + options:NSTrackingMouseMoved | NSTrackingCursorUpdate | + NSTrackingActiveInActiveApp | NSTrackingInVisibleRect + owner:self + userInfo:nil]); [self addTrackingArea:trackingArea_.get()]; } return self; @@ -134,6 +138,15 @@ if (!hostedView_) return; + // If there's an active MenuController it gets preference, and it will likely + // swallow the event. + MenuController* menuController = MenuController::GetActiveInstance(); + if (menuController && menuController->owner() == hostedView_->GetWidget()) { + if (menuController->OnWillDispatchKeyEvent(0, keyCode) == + ui::POST_DISPATCH_NONE) + return; + } + // If there's an active TextInputClient, it ignores the key and processes the // logical editing action. if (commandId && textInputClient_ && @@ -175,6 +188,20 @@ hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas); } +- (NSTextInputContext*)inputContext { + if (!hostedView_) + return [super inputContext]; + + // If a menu is active, and -[NSView interpretKeyEvents:] asks for the + // input context, return nil. This ensures the action message is sent to + // the view, rather than any NSTextInputClient a subview has installed. + MenuController* menuController = MenuController::GetActiveInstance(); + if (menuController && menuController->owner() == hostedView_->GetWidget()) + return nil; + + return [super inputContext]; +} + // NSResponder implementation. - (void)keyDown:(NSEvent*)theEvent { @@ -473,11 +500,36 @@ } - (void)insertText:(id)text replacementRange:(NSRange)replacementRange { - if (!textInputClient_) + if (!hostedView_) return; if ([text isKindOfClass:[NSAttributedString class]]) text = [text string]; + + MenuController* menuController = MenuController::GetActiveInstance(); + if (menuController && menuController->owner() == hostedView_->GetWidget()) { + // Handle menu mnemonics (e.g. "sav" jumps to "Save"). Handles both single- + // characters and input from IME. For IME, swallow the entire string unless + // the very first character gives ui::POST_DISPATCH_PERFORM_DEFAULT. + bool swallowedAny = false; + for (NSUInteger i = 0; i < [text length]; ++i) { + if (!menuController || + menuController->OnWillDispatchKeyEvent([text characterAtIndex:i], + ui::VKEY_UNKNOWN) == + ui::POST_DISPATCH_PERFORM_DEFAULT) { + if (swallowedAny) + return; // Swallow remainder. + break; + } + swallowedAny = true; + // Ensure the menu remains active. + menuController = MenuController::GetActiveInstance(); + } + } + + if (!textInputClient_) + return; + textInputClient_->DeleteRange(gfx::Range(replacementRange)); textInputClient_->InsertText(base::SysNSStringToUTF16(text)); }
diff --git a/ui/views/cocoa/bridged_native_widget.h b/ui/views/cocoa/bridged_native_widget.h index ae3afa6..bb9b406 100644 --- a/ui/views/cocoa/bridged_native_widget.h +++ b/ui/views/cocoa/bridged_native_widget.h
@@ -83,6 +83,9 @@ void SetNativeWindowProperty(const char* key, void* value); void* GetNativeWindowProperty(const char* key) const; + // Sets the cursor associated with the NSWindow. Retains |cursor|. + void SetCursor(NSCursor* cursor); + // Called internally by the NSWindowDelegate when the window is closing. void OnWindowWillClose();
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index 4062f9a..96d0170 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -204,6 +204,14 @@ return; // Capture on hidden windows is disallowed. mouse_capture_.reset(new CocoaMouseCapture(this)); + + // Initiating global event capture with addGlobalMonitorForEventsMatchingMask: + // will reset the mouse cursor to an arrow. Asking the window for an update + // here will restore what we want. However, it can sometimes cause the cursor + // to flicker, once, on the initial mouseDown. + // TOOD(tapted): Make this unnecessary by only asking for global mouse capture + // for the cases that need it (e.g. menus, but not drag and drop). + [window_ cursorUpdate:[NSApp currentEvent]]; } void BridgedNativeWidget::ReleaseCapture() { @@ -230,6 +238,10 @@ return [[GetWindowProperties() objectForKey:key] pointerValue]; } +void BridgedNativeWidget::SetCursor(NSCursor* cursor) { + [window_delegate_ setCursor:cursor]; +} + void BridgedNativeWidget::OnWindowWillClose() { if (parent_) parent_->RemoveChildWindow(this);
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.mm b/ui/views/cocoa/native_widget_mac_nswindow.mm index 7a3d3dc..00b2e1a 100644 --- a/ui/views/cocoa/native_widget_mac_nswindow.mm +++ b/ui/views/cocoa/native_widget_mac_nswindow.mm
@@ -6,11 +6,13 @@ #include "base/mac/foundation_util.h" #import "ui/views/cocoa/views_nswindow_delegate.h" +#include "ui/views/controls/menu/menu_controller.h" #include "ui/views/widget/native_widget_mac.h" @interface NativeWidgetMacNSWindow () - (ViewsNSWindowDelegate*)viewsNSWindowDelegate; - (views::Widget*)viewsWidget; +- (BOOL)hasViewsMenuActive; @end @implementation NativeWidgetMacNSWindow @@ -23,6 +25,12 @@ return [[self viewsNSWindowDelegate] nativeWidgetMac]->GetWidget(); } +- (BOOL)hasViewsMenuActive { + views::MenuController* menuController = + views::MenuController::GetActiveInstance(); + return menuController && menuController->owner() == [self viewsWidget]; +} + // Ignore [super canBecome{Key,Main}Window]. The default is NO for windows with // NSBorderlessWindowMask, which is not the desired behavior. // Note these can be called via -[NSWindow close] while the widget is being torn @@ -35,6 +43,24 @@ return [self delegate] && [self viewsWidget]->CanActivate(); } +// Override sendEvent to allow key events to be forwarded to a toolkit-views +// menu while it is active, and while still allowing any native subview to +// retain firstResponder status. +- (void)sendEvent:(NSEvent*)event { + NSEventType type = [event type]; + if ((type != NSKeyDown && type != NSKeyUp) || ![self hasViewsMenuActive]) { + [super sendEvent:event]; + return; + } + + // Send to the menu, after converting the event into an action message using + // the content view. + if (type == NSKeyDown) + [[self contentView] keyDown:event]; + else + [[self contentView] keyUp:event]; +} + // Override display, since this is the first opportunity Cocoa gives to detect // a visibility change in some cases. For example, restoring from the dock first // calls -[NSWindow display] before any NSWindowDelegate functions and before @@ -59,4 +85,26 @@ [[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; } +// NSResponder implementation. + +- (void)cursorUpdate:(NSEvent*)theEvent { + // The cursor provided by the delegate should only be applied within the + // content area. This is because we rely on the contentView to track the + // mouse cursor and forward cursorUpdate: messages up the responder chain. + // The cursorUpdate: isn't handled in BridgedContentView because views-style + // SetCapture() conflicts with the way tracking events are processed for + // the view during a drag. Since the NSWindow is still in the responder chain + // overriding cursorUpdate: here handles both cases. + if (!NSPointInRect([theEvent locationInWindow], [[self contentView] frame])) { + [super cursorUpdate:theEvent]; + return; + } + + NSCursor* cursor = [[self viewsNSWindowDelegate] cursor]; + if (cursor) + [cursor set]; + else + [super cursorUpdate:theEvent]; +} + @end
diff --git a/ui/views/cocoa/views_nswindow_delegate.h b/ui/views/cocoa/views_nswindow_delegate.h index 70fe74d..d5ef872 100644 --- a/ui/views/cocoa/views_nswindow_delegate.h +++ b/ui/views/cocoa/views_nswindow_delegate.h
@@ -7,6 +7,8 @@ #import <Cocoa/Cocoa.h> +#import "base/mac/scoped_nsobject.h" + namespace views { class NativeWidgetMac; class BridgedNativeWidget; @@ -17,12 +19,17 @@ @interface ViewsNSWindowDelegate : NSObject<NSWindowDelegate> { @private views::BridgedNativeWidget* parent_; // Weak. Owns this. + base::scoped_nsobject<NSCursor> cursor_; } // The NativeWidgetMac that created the window this is attached to. Returns // NULL if not created by NativeWidgetMac. @property(nonatomic, readonly) views::NativeWidgetMac* nativeWidgetMac; +// If set, the cursor set in -[NSResponder updateCursor:] when the window is +// reached along the responder chain. +@property(retain, nonatomic) NSCursor* cursor; + // Initialize with the given |parent|. - (id)initWithBridgedNativeWidget:(views::BridgedNativeWidget*)parent;
diff --git a/ui/views/cocoa/views_nswindow_delegate.mm b/ui/views/cocoa/views_nswindow_delegate.mm index 7acae1e..38a56c1 100644 --- a/ui/views/cocoa/views_nswindow_delegate.mm +++ b/ui/views/cocoa/views_nswindow_delegate.mm
@@ -23,6 +23,18 @@ return parent_->native_widget_mac(); } +- (NSCursor*)cursor { + return cursor_.get(); +} + +- (void)setCursor:(NSCursor*)newCursor { + if (cursor_.get() == newCursor) + return; + + cursor_.reset([newCursor retain]); + [parent_->ns_window() resetCursorRects]; +} + - (void)onWindowOrderWillChange:(NSWindowOrderingMode)orderingMode { parent_->OnVisibilityChangedTo(orderingMode != NSWindowOut); }
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index d1547c4..b74ddce 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -804,6 +804,22 @@ } } +ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent( + base::char16 character, + ui::KeyboardCode key_code) { + if (exit_type() == MenuController::EXIT_ALL || + exit_type() == MenuController::EXIT_DESTROYED) { + TerminateNestedMessageLoop(); + return ui::POST_DISPATCH_PERFORM_DEFAULT; + } + + bool should_quit = character ? SelectByChar(character) : !OnKeyDown(key_code); + if (should_quit || exit_type() != MenuController::EXIT_NONE) + TerminateNestedMessageLoop(); + + return ui::POST_DISPATCH_NONE; +} + void MenuController::UpdateSubmenuSelection(SubmenuView* submenu) { if (submenu->IsShowing()) { gfx::Point point = GetScreen()->GetCursorScreenPoint(); @@ -1028,16 +1044,22 @@ CloseSubmenu(); break; +// On Mac, treat space the same as return. +#if !defined(OS_MACOSX) case ui::VKEY_SPACE: if (SendAcceleratorToHotTrackedView() == ACCELERATOR_PROCESSED_EXIT) return false; break; +#endif case ui::VKEY_F4: if (!is_combobox_) break; // Fallthrough to accept or dismiss combobox menus on F4, like windows. case ui::VKEY_RETURN: +#if defined(OS_MACOSX) + case ui::VKEY_SPACE: +#endif if (pending_state_.item) { if (pending_state_.item->HasSubmenu()) { if (key_code == ui::VKEY_F4 &&
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index 92ea8c4..76060b0 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h
@@ -160,6 +160,13 @@ // corresponds to whether or not the menu should close. void OnDragComplete(bool should_close); + // Called while dispatching messages to intercept key events. + // If |character| is other than 0, it is handled as a mnemonic. + // Otherwise, |key_code| is handled as a menu navigation command. + // Returns ui::POST_DISPATCH_NONE if the event was swallowed by the menu. + ui::PostDispatchAction OnWillDispatchKeyEvent(base::char16 character, + ui::KeyboardCode key_code); + // Update the submenu's selection based on the current mouse location void UpdateSubmenuSelection(SubmenuView* source);
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc index e872a58b..2e4ba84 100644 --- a/ui/views/controls/webview/webview.cc +++ b/ui/views/controls/webview/webview.cc
@@ -78,7 +78,7 @@ DCHECK(!is_embedding_fullscreen_widget_); } AttachWebContents(); - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::SetEmbedFullscreenWidgetMode(bool enable) { @@ -266,7 +266,7 @@ void WebView::RenderProcessExited(content::RenderProcessHost* host, base::TerminationStatus status, int exit_code) { - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::RenderProcessHostDestroyed(content::RenderProcessHost* host) { @@ -293,11 +293,11 @@ // WebView, content::WebContentsObserver implementation: void WebView::RenderViewReady() { - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) { - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, @@ -305,7 +305,7 @@ FocusManager* const focus_manager = GetFocusManager(); if (focus_manager && focus_manager->GetFocusedView() == this) OnFocus(); - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::WebContentsDestroyed() { @@ -313,7 +313,7 @@ observing_render_process_host_->RemoveObserver(this); observing_render_process_host_ = nullptr; } - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::DidShowFullscreenWidget(int routing_id) { @@ -332,11 +332,11 @@ } void WebView::DidAttachInterstitialPage() { - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } void WebView::DidDetachInterstitialPage() { - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } //////////////////////////////////////////////////////////////////////////////// @@ -398,19 +398,14 @@ // the same. So, do not change attachment. OnBoundsChanged(bounds()); } - NotifyMaybeTextInputClientAndAccessibilityChanged(); + NotifyMaybeTextInputClientChanged(); } -void WebView::NotifyMaybeTextInputClientAndAccessibilityChanged() { +void WebView::NotifyMaybeTextInputClientChanged() { // Update the TextInputClient as needed; see GetTextInputClient(). FocusManager* const focus_manager = GetFocusManager(); if (focus_manager) focus_manager->OnTextInputClientChanged(this); - -#if defined(OS_CHROMEOS) - if (web_contents()) - NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false); -#endif // defined OS_CHROMEOS } content::WebContents* WebView::CreateWebContents(
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h index f97449b8..af64b72 100644 --- a/ui/views/controls/webview/webview.h +++ b/ui/views/controls/webview/webview.h
@@ -149,7 +149,7 @@ void AttachWebContents(); void DetachWebContents(); void ReattachForFullscreenChange(bool enter_fullscreen); - void NotifyMaybeTextInputClientAndAccessibilityChanged(); + void NotifyMaybeTextInputClientChanged(); // Create a regular or test web contents (based on whether we're running // in a unit test or not).
diff --git a/ui/views/focus/focus_traversal_unittest.cc b/ui/views/focus/focus_traversal_unittest.cc index 9ca7b452..79e22ef 100644 --- a/ui/views/focus/focus_traversal_unittest.cc +++ b/ui/views/focus/focus_traversal_unittest.cc
@@ -795,19 +795,19 @@ // the x1-x3-x2 triangles, it will traverse the left sibling of x1, (x+1)0, // twice, which means it will visit O(2^n) nodes.) // - // 0 - // / \ - // / \ - // 10 1 - // / \ / \ - // / \ / \ - // 20 11 2 3 - // / \ / \ - // / \ / \ - // ... 21 12 13 - // / \ - // / \ - // 22 23 + // | 0 | + // | / \ | + // | / \ | + // | 10 1 | + // | / \ / \ | + // | / \ / \ | + // | 20 11 2 3 | + // | / \ / \ | + // | / \ / \ | + // | ... 21 12 13 | + // | / \ | + // | / \ | + // | 22 23 | View* v = GetContentsView(); // Create 30 groups of 4 nodes. |v| is the top of each group.
diff --git a/ui/views/shadow_border.cc b/ui/views/shadow_border.cc index 3d5235c..fe744721 100644 --- a/ui/views/shadow_border.cc +++ b/ui/views/shadow_border.cc
@@ -7,50 +7,51 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gfx/shadow_value.h" #include "ui/gfx/skia_util.h" #include "ui/views/view.h" namespace views { -ShadowBorder::ShadowBorder(int blur, - SkColor color, - int vertical_offset, - int horizontal_offset) - : views::Border(), - blur_(blur), - color_(color), - vertical_offset_(vertical_offset), - horizontal_offset_(horizontal_offset) {} +namespace { -ShadowBorder::~ShadowBorder() {} +gfx::Insets GetInsetsFromShadowValue(const gfx::ShadowValue& shadow) { + std::vector<gfx::ShadowValue> shadows; + shadows.push_back(shadow); + return -gfx::ShadowValue::GetMargin(shadows); +} + +} // namespace + +ShadowBorder::ShadowBorder(const gfx::ShadowValue& shadow) + : views::Border(), + shadow_value_(shadow), + insets_(GetInsetsFromShadowValue(shadow)) { +} + +ShadowBorder::~ShadowBorder() { +} // TODO(sidharthms): Re-painting a shadow looper on every paint call may yield // poor performance. Ideally we should be caching the border to bitmaps. void ShadowBorder::Paint(const views::View& view, gfx::Canvas* canvas) { SkPaint paint; std::vector<gfx::ShadowValue> shadows; - shadows.push_back(gfx::ShadowValue(gfx::Point(), blur_, color_)); + shadows.push_back(shadow_value_); skia::RefPtr<SkDrawLooper> looper = gfx::CreateShadowDrawLooper(shadows); paint.setLooper(looper.get()); paint.setColor(SK_ColorTRANSPARENT); paint.setStrokeJoin(SkPaint::kRound_Join); gfx::Rect bounds(view.size()); - // TODO(pkasting): This isn't right if one of the offsets is larger than - // (blur_ / 2). - bounds.Inset(gfx::Insets(blur_ / 2, blur_ / 2, blur_ / 2, blur_ / 2)); + bounds.Inset(-gfx::ShadowValue::GetMargin(shadows)); canvas->DrawRect(bounds, paint); } gfx::Insets ShadowBorder::GetInsets() const { - return gfx::Insets(blur_ / 2 - vertical_offset_, - blur_ / 2 - horizontal_offset_, - blur_ / 2 + vertical_offset_, - blur_ / 2 + horizontal_offset_); + return insets_; } gfx::Size ShadowBorder::GetMinimumSize() const { - return gfx::Size(blur_, blur_); + return gfx::Size(shadow_value_.blur(), shadow_value_.blur()); } } // namespace views
diff --git a/ui/views/shadow_border.h b/ui/views/shadow_border.h index fd0565f1..afe4b64 100644 --- a/ui/views/shadow_border.h +++ b/ui/views/shadow_border.h
@@ -6,6 +6,7 @@ #define UI_VIEWS_SHADOW_BORDER_H_ #include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/shadow_value.h" #include "ui/views/border.h" #include "ui/views/views_export.h" @@ -14,10 +15,7 @@ // Creates a css box-shadow like border which fades into SK_ColorTRANSPARENT. class VIEWS_EXPORT ShadowBorder : public views::Border { public: - ShadowBorder(int blur, - SkColor color, - int vertical_offset, - int horizontal_offset); + explicit ShadowBorder(const gfx::ShadowValue& shadow); ~ShadowBorder() override; protected: @@ -27,18 +25,11 @@ gfx::Size GetMinimumSize() const override; private: - // Blur amount of the shadow in pixels. For details on how blur is defined see - // comments for blur_ in class ShadowValue. - const int blur_; + // The shadow value to use for this border. + const gfx::ShadowValue shadow_value_; - // Shadow color. - const SkColor color_; - - // Number of pixels to shift shadow to bottom. - const int vertical_offset_; - - // Number of pixels to shift shadow to right. - const int horizontal_offset_; + // The insets of this border. + const gfx::Insets insets_; DISALLOW_COPY_AND_ASSIGN(ShadowBorder); };
diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 7176d572..8a8d9eb 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp
@@ -599,6 +599,7 @@ '../../url/url.gyp:url_lib', '../accessibility/accessibility.gyp:accessibility', '../accessibility/accessibility.gyp:ax_gen', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../events/events.gyp:events', @@ -729,6 +730,7 @@ '../../ipc/ipc.gyp:test_support_ipc', '../../skia/skia.gyp:skia', '../../testing/gtest.gyp:gtest', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../compositor/compositor.gyp:compositor_test_support', @@ -776,6 +778,7 @@ '../../third_party/icu/icu.gyp:icuuc', '../../url/url.gyp:url_lib', '../accessibility/accessibility.gyp:accessibility', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../base/ui_base.gyp:ui_base_test_support', '../compositor/compositor.gyp:compositor',
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index ffc821f..564494ea 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -471,7 +471,8 @@ } void NativeWidgetMac::SetCursor(gfx::NativeCursor cursor) { - NOTIMPLEMENTED(); + if (bridge_) + bridge_->SetCursor(cursor); } bool NativeWidgetMac::IsMouseEventsEnabled() const {
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 6c3daca..7593f98 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -7,6 +7,9 @@ #import <Cocoa/Cocoa.h> #include "base/run_loop.h" +#import "ui/events/test/cocoa_test_event_utils.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/native_cursor.h" #include "ui/views/test/test_widget_observer.h" #include "ui/views/test/widget_test.h" @@ -257,5 +260,82 @@ widget->CloseNow(); } +// Simple view for the SetCursor test that overrides View::GetCursor(). +class CursorView : public View { + public: + CursorView(int x, NSCursor* cursor) : cursor_(cursor) { + SetBounds(x, 0, 100, 300); + } + + // View: + gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override { + return cursor_; + } + + private: + NSCursor* cursor_; + + DISALLOW_COPY_AND_ASSIGN(CursorView); +}; + +// Test for Widget::SetCursor(). There is no Widget::GetCursor(), so this uses +// -[NSCursor currentCursor] to validate expectations. Note that currentCursor +// is just "the top cursor on the application's cursor stack.", which is why it +// is safe to use this in a non-interactive UI test with the EventGenerator. +TEST_F(NativeWidgetMacTest, SetCursor) { + NSCursor* arrow = [NSCursor arrowCursor]; + NSCursor* hand = GetNativeHandCursor(); + NSCursor* ibeam = GetNativeIBeamCursor(); + + Widget* widget = CreateTopLevelPlatformWidget(); + widget->SetBounds(gfx::Rect(0, 0, 300, 300)); + widget->GetContentsView()->AddChildView(new CursorView(0, hand)); + widget->GetContentsView()->AddChildView(new CursorView(100, ibeam)); + widget->Show(); + + // Events used to simulate tracking rectangle updates. These are not passed to + // toolkit-views, so it only matters whether they are inside or outside the + // content area. + NSEvent* event_in_content = cocoa_test_event_utils::MouseEventAtPoint( + NSMakePoint(100, 100), NSMouseMoved, 0); + NSEvent* event_out_of_content = cocoa_test_event_utils::MouseEventAtPoint( + NSMakePoint(-50, -50), NSMouseMoved, 0); + + EXPECT_NE(arrow, hand); + EXPECT_NE(arrow, ibeam); + + // At the start of the test, the cursor stack should be empty. + EXPECT_FALSE([NSCursor currentCursor]); + + // Use an event generator to ask views code to set the cursor. However, note + // that this does not cause Cocoa to generate tracking rectangle updates. + ui::test::EventGenerator event_generator(GetContext(), + widget->GetNativeWindow()); + + // Move the mouse over the first view, then simulate a tracking rectangle + // update. + event_generator.MoveMouseTo(gfx::Point(50, 50)); + [widget->GetNativeWindow() cursorUpdate:event_in_content]; + EXPECT_EQ(hand, [NSCursor currentCursor]); + + // A tracking rectangle update not in the content area should forward to + // the native NSWindow implementation, which sets the arrow cursor. + [widget->GetNativeWindow() cursorUpdate:event_out_of_content]; + EXPECT_EQ(arrow, [NSCursor currentCursor]); + + // Now move to the second view. + event_generator.MoveMouseTo(gfx::Point(150, 50)); + [widget->GetNativeWindow() cursorUpdate:event_in_content]; + EXPECT_EQ(ibeam, [NSCursor currentCursor]); + + // Moving to the third view (but remaining in the content area) should also + // forward to the native NSWindow implementation. + event_generator.MoveMouseTo(gfx::Point(250, 50)); + [widget->GetNativeWindow() cursorUpdate:event_in_content]; + EXPECT_EQ(arrow, [NSCursor currentCursor]); + + widget->CloseNow(); +} + } // namespace test } // namespace views
diff --git a/ui/webui/resources/css/chrome_shared.css b/ui/webui/resources/css/chrome_shared.css index 6ad44bb..785e9d5 100644 --- a/ui/webui/resources/css/chrome_shared.css +++ b/ui/webui/resources/css/chrome_shared.css
@@ -21,8 +21,8 @@ } html.loading * { - -webkit-transition-delay: 0 !important; - -webkit-transition-duration: 0 !important; + -webkit-transition-delay: 0ms !important; + -webkit-transition-duration: 0ms !important; } body {
diff --git a/ui/webui/resources/css/overlay.css b/ui/webui/resources/css/overlay.css index 29fc4b6..c755c158 100644 --- a/ui/webui/resources/css/overlay.css +++ b/ui/webui/resources/css/overlay.css
@@ -46,7 +46,7 @@ /* If the options page is loading don't do the transition. */ .loading .overlay, .loading .overlay .page { - -webkit-transition-duration: 0 !important; + -webkit-transition-duration: 0ms !important; } /* keyframes used to pulse the overlay */
diff --git a/ui/webui/resources/js/cr/ui/focus_grid.js b/ui/webui/resources/js/cr/ui/focus_grid.js index 4ff1635..d8ab761 100644 --- a/ui/webui/resources/js/cr/ui/focus_grid.js +++ b/ui/webui/resources/js/cr/ui/focus_grid.js
@@ -43,6 +43,7 @@ * Row delegate to overwrite the behavior of a mouse click to deselect any row * that wasn't clicked. * @param {cr.ui.FocusGrid} focusGrid + * @constructor * @implements {cr.ui.FocusRow.Delegate} */ FocusGrid.RowDelegate = function(focusGrid) { @@ -61,11 +62,11 @@ return false; // Only the clicked row should be active. + var target = assertInstanceof(e.target, Node); this.focusGrid_.rows.forEach(function(row) { - row.makeRowActive(row.contains(e.target)); + row.makeRowActive(row.contains(target)); }); - e.preventDefault(); return true; }, }; @@ -80,7 +81,7 @@ }, /** - * @param {EventTarget} target A target item to find in this grid. + * @param {Node} target A target item to find in this grid. * @return {number} The row index. -1 if not found. */ getRowIndexForTarget: function(target) { @@ -97,7 +98,8 @@ * @private */ onKeydown_: function(e) { - var rowIndex = this.getRowIndexForTarget(e.target); + var target = assertInstanceof(e.target, Node); + var rowIndex = this.getRowIndexForTarget(target); if (rowIndex == -1) return; @@ -122,7 +124,7 @@ /** * Keep track of the last column that the user manually focused. - * @param {Event} The focusin event. + * @param {Event} e The focusin event. * @private */ onFocusin_: function(e) { @@ -131,8 +133,9 @@ return; } - if (this.getRowIndexForTarget(e.target) != -1) - this.lastFocused = e.target; + var target = assertInstanceof(e.target, Node); + if (this.getRowIndexForTarget(target) != -1) + this.lastFocused = target; }, /**
diff --git a/ui/webui/resources/js/cr/ui/focus_manager.js b/ui/webui/resources/js/cr/ui/focus_manager.js index 3d2fac9..2142efd2 100644 --- a/ui/webui/resources/js/cr/ui/focus_manager.js +++ b/ui/webui/resources/js/cr/ui/focus_manager.js
@@ -194,38 +194,6 @@ }, }; - /** - * Disable mouse-focus for button controls. - * Button form controls are mouse-focusable since Chromium 30. We want the - * old behavior in some WebUI pages. - */ - FocusManager.disableMouseFocusOnButtons = function() { - document.addEventListener('mousedown', function(event) { - if (event.defaultPrevented) - return; - var node = event.target; - var tagName = node.tagName; - if (tagName != 'BUTTON' && tagName != 'INPUT') { - do { - node = node.parentNode; - if (!node || node.nodeType != Node.ELEMENT_NODE) - return; - } while (node.tagName != 'BUTTON'); - } - var type = node.type; - if (type == 'button' || type == 'reset' || type == 'submit' || - type == 'radio' || type == 'checkbox') { - if (document.activeElement != node) - document.activeElement.blur(); - - // Focus the current window so that if the active element is in another - // window, it is deactivated. - window.focus(); - event.preventDefault(); - } - }, false); - }; - return { FocusManager: FocusManager, };
diff --git a/ui/webui/resources/js/cr/ui/focus_row.js b/ui/webui/resources/js/cr/ui/focus_row.js index 697cd699..c69d254 100644 --- a/ui/webui/resources/js/cr/ui/focus_row.js +++ b/ui/webui/resources/js/cr/ui/focus_row.js
@@ -29,6 +29,7 @@ * any focus change deactivates the row. * * @constructor + * @extends {HTMLDivElement} */ function FocusRow() {} @@ -59,7 +60,8 @@ /** * Should be called in the constructor to decorate |this|. * @param {Node} boundary Focus events are ignored outside of this node. - * @param {FocusRow.Delegate=} opt_delegate A delegate to handle key events. + * @param {cr.ui.FocusRow.Delegate=} opt_delegate A delegate to handle key + * events. */ decorate: function(boundary, opt_delegate) { /** @private {!Node} */ @@ -90,7 +92,7 @@ * which previously held focus. * @return {!Element} The element that best matches sampleElement. */ - getEquivalentElement: assertNotReached, + getEquivalentElement: function(sampleElement) { assertNotReached(); }, /** * Add an element to this FocusRow. No-op if |element| is not provided. @@ -148,8 +150,9 @@ * @private */ onFocusin_: function(e) { - if (this.boundary_.contains(assertInstanceof(e.target, Node))) - this.onFocusChange_(e.target); + var target = assertInstanceof(e.target, Element); + if (this.boundary_.contains(target)) + this.onFocusChange_(target); }, /** @@ -158,13 +161,14 @@ * @private */ onKeydown_: function(e) { - if (!this.contains(e.target)) + var element = assertInstanceof(e.target, Element); + if (!this.contains(element)) return; if (this.delegate && this.delegate.onKeydown(this, e)) return; - var elementIndex = this.focusableElements.indexOf(e.target); + var elementIndex = this.focusableElements.indexOf(element); var index = -1; if (e.keyIdentifier == 'Left') @@ -194,7 +198,7 @@ // Only accept the left mouse click. if (!e.button) { // Focus this row if the target is one of the elements in this row. - this.onFocusChange_(e.target); + this.onFocusChange_(assertInstanceof(e.target, Element)); } }, };
diff --git a/ui/webui/resources/js/cr/ui/node_utils.js b/ui/webui/resources/js/cr/ui/node_utils.js index a380670..21b0fb16 100644 --- a/ui/webui/resources/js/cr/ui/node_utils.js +++ b/ui/webui/resources/js/cr/ui/node_utils.js
@@ -31,3 +31,22 @@ buttonStrip.setAttribute('reversed', ''); } }; + +/** + * Finds a good place to set initial focus. Generally called when UI is shown. + * @param {!Element} root Where to start looking for focusable controls. + */ +cr.ui.setInitialFocus = function(root) { + // Do not change focus if any element in |root| is already focused. + if (root.contains(document.activeElement)) + return; + + var elements = root.querySelectorAll('input, list, select, textarea, button'); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.focus(); + // .focus() isn't guaranteed to work. Continue until it does. + if (document.activeElement == element) + return; + } +};
diff --git a/ui/webui/resources/js/cr/ui/page_manager/page.js b/ui/webui/resources/js/cr/ui/page_manager/page.js index 3f41981..ab9bcc1 100644 --- a/ui/webui/resources/js/cr/ui/page_manager/page.js +++ b/ui/webui/resources/js/cr/ui/page_manager/page.js
@@ -23,7 +23,7 @@ this.name = name; this.title = title; this.pageDivName = pageDivName; - this.pageDiv = $(this.pageDivName); + this.pageDiv = getRequiredElement(this.pageDivName); // |pageDiv.page| is set to the page object (this) when the page is visible // to track which page is being shown when multiple pages can share the same // underlying div. @@ -79,19 +79,7 @@ * strategy. */ focus: function() { - // Do not change focus if any control on this page is already focused. - if (this.pageDiv.contains(document.activeElement)) - return; - - var elements = this.pageDiv.querySelectorAll( - 'input, list, select, textarea, button'); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - // Try to focus. If fails, then continue. - element.focus(); - if (document.activeElement == element) - return; - } + cr.ui.setInitialFocus(this.pageDiv); }, /**
diff --git a/ui/webui/resources/js/cr/ui/page_manager/page_manager.js b/ui/webui/resources/js/cr/ui/page_manager/page_manager.js index 8220c2c..ae6283a 100644 --- a/ui/webui/resources/js/cr/ui/page_manager/page_manager.js +++ b/ui/webui/resources/js/cr/ui/page_manager/page_manager.js
@@ -3,8 +3,6 @@ // found in the LICENSE file. cr.define('cr.ui.pageManager', function() { - /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; - /** * PageManager contains a list of root Page and overlay Page objects and * handles "navigation" by showing and hiding these pages and overlays. On @@ -56,7 +54,7 @@ initialize: function(defaultPage) { this.defaultPage_ = defaultPage; - FocusOutlineManager.forDocument(document); + cr.ui.FocusOutlineManager.forDocument(document); document.addEventListener('scroll', this.handleScroll_.bind(this)); // Trigger the scroll handler manually to set the initial state. @@ -500,11 +498,10 @@ // Change focus to the overlay if any other control was focused by // keyboard before. Otherwise, no one should have focus. if (document.activeElement != document.body) { - if (FocusOutlineManager.forDocument(document).visible) { + if (cr.ui.FocusOutlineManager.forDocument(document).visible) overlay.focus(); - } else if (!overlay.pageDiv.contains(document.activeElement)) { + if (!overlay.pageDiv.contains(document.activeElement)) document.activeElement.blur(); - } } if ($('search-field') && $('search-field').value == '') {
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp index aa844d98..af219dde 100644 --- a/ui/webui/resources/polymer_resources.grdp +++ b/ui/webui/resources/polymer_resources.grdp
@@ -57,6 +57,9 @@ <structure name="IDR_POLYMER_CORE_ICONS_IMAGE_ICONS_HTML" file="../../../third_party/polymer/components-chromium/core-icons/image-icons.html" type="chrome_html" /> + <structure name="IDR_POLYMER_CORE_ICONS_SOCIAL_ICONS_HTML" + file="../../../third_party/polymer/components-chromium/core-icons/social-icons.html" + type="chrome_html" /> <structure name="IDR_POLYMER_CORE_ICONSET_CORE_ICONSET_EXTRACTED_JS" file="../../../third_party/polymer/components-chromium/core-iconset/core-iconset-extracted.js" type="chrome_html" />
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn index 17d4fa9..93ab320 100644 --- a/ui/wm/BUILD.gn +++ b/ui/wm/BUILD.gn
@@ -79,6 +79,7 @@ "//skia", "//ui/aura", "//ui/base", + "//ui/base/ime", "//ui/compositor", "//ui/events", "//ui/events/devices", @@ -108,6 +109,7 @@ "//ui/aura", "//ui/aura:test_support", "//ui/base", + "//ui/base/ime", "//ui/events", "//ui/events:events_base", ]
diff --git a/ui/wm/wm.gyp b/ui/wm/wm.gyp index 7336922..ae434406 100644 --- a/ui/wm/wm.gyp +++ b/ui/wm/wm.gyp
@@ -23,6 +23,7 @@ '../gfx/gfx.gyp:gfx_geometry', '../gfx/gfx.gyp:gfx', '../resources/ui_resources.gyp:ui_resources', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', ], 'defines': [ @@ -129,6 +130,7 @@ '../../testing/gtest.gyp:gtest', '../aura/aura.gyp:aura', '../aura/aura.gyp:aura_test_support', + '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', '../compositor/compositor.gyp:compositor', '../events/events.gyp:events',
diff --git a/url/gurl.h b/url/gurl.h index ef1e529..566fc5e 100644 --- a/url/gurl.h +++ b/url/gurl.h
@@ -18,8 +18,8 @@ class URL_EXPORT GURL { public: - typedef url::StdStringReplacements<std::string> Replacements; - typedef url::StdStringReplacements<base::string16> ReplacementsW; + typedef url::StringPieceReplacements<std::string> Replacements; + typedef url::StringPieceReplacements<base::string16> ReplacementsW; // Creates an empty, invalid URL. GURL();
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h index c3d8ba14..662cac7 100644 --- a/url/url_canon_stdstring.h +++ b/url/url_canon_stdstring.h
@@ -12,6 +12,7 @@ #include <string> #include "base/compiler_specific.h" +#include "base/strings/string_piece.h" #include "url/url_canon.h" #include "url/url_export.h" @@ -48,35 +49,35 @@ }; // An extension of the Replacements class that allows the setters to use -// standard strings. +// StringPieces (implicitly allowing strings or char*s). // -// The strings passed as arguments are not copied and must remain valid until -// this class goes out of scope. +// The contents of the StringPieces are not copied and must remain valid until +// the StringPieceReplacements object goes out of scope. template<typename STR> -class StdStringReplacements : public Replacements<typename STR::value_type> { +class StringPieceReplacements : public Replacements<typename STR::value_type> { public: - void SetSchemeStr(const STR& s) { + void SetSchemeStr(const base::BasicStringPiece<STR>& s) { this->SetScheme(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetUsernameStr(const STR& s) { + void SetUsernameStr(const base::BasicStringPiece<STR>& s) { this->SetUsername(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetPasswordStr(const STR& s) { + void SetPasswordStr(const base::BasicStringPiece<STR>& s) { this->SetPassword(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetHostStr(const STR& s) { + void SetHostStr(const base::BasicStringPiece<STR>& s) { this->SetHost(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetPortStr(const STR& s) { + void SetPortStr(const base::BasicStringPiece<STR>& s) { this->SetPort(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetPathStr(const STR& s) { + void SetPathStr(const base::BasicStringPiece<STR>& s) { this->SetPath(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetQueryStr(const STR& s) { + void SetQueryStr(const base::BasicStringPiece<STR>& s) { this->SetQuery(s.data(), Component(0, static_cast<int>(s.length()))); } - void SetRefStr(const STR& s) { + void SetRefStr(const base::BasicStringPiece<STR>& s) { this->SetRef(s.data(), Component(0, static_cast<int>(s.length()))); } };